본문 바로가기

자바

[자바] 장식자 패턴

package decorator;

/**
 * 복수 행으로 구성되는 문자열을 표시하기 위한 추상 클래스.
 * @author dev-jones
 *
 */
public abstract class Display {

	/**
	 * 각각 가로의 문자수와 세로의 문자수를 얻기 위한 메소드
	 */
	public abstract int getColumns();
	public abstract int getRows();
	
	/**
	 * 입력받은 row의 문자열을 리턴
	 * @param row
	 * @return
	 */
	public abstract String getRowText(int row); 
	
	public final void show() {
		for(int i = 0; i < getRows(); i++) {
			System.out.println(getRowText(i));
		}
	}
}

 

package decorator;

/**
 * 1행의 문자열을 표시하는 클래스
 * @author dev-jones
 *
 */
public class StringDisplay extends Display {
	private String printStr;
	
	public StringDisplay(String printStr) {
		this.printStr = printStr;
	}
	
	@Override
	public int getColumns() {
		return printStr.getBytes().length;
	}
	
	@Override
	public int getRows() {
		return 1;
	}
	
	public String getRowText(int row) {
		if(row == 0) return printStr;
		else return "";
	}
}
package decorator;

/**
 * 장식(Border)이 내용물(Display)과 같은 메소드를 가진다는 것은
 * 인터페이스(API)적으로 장식과 내용물을 동일시 할수 있다는 의미.
 * 메모리 상의 1바이트 문자가 화면 상의 1칼럼에 해당한다고 가정.
 * @author dev-jones
 *
 */
public abstract class Border extends Display {
	
	protected Display display;	// 이 장식이 둘러싸고 있는 '내용물'
	
	protected Border(Display display) {	// 인스턴스 생성시 '내용물'을 인수로 지정
		this.display = display;
	}
}
package decorator;

public class SideBorder extends Border {

	private char borderChar;	// 장식이 되는 문자.
	
	public SideBorder(Display display, char ch) {
		super(display);
		this.borderChar = ch;
	}
	
	@Override
	public int getColumns() {
		return 1 + display.getColumns() + 1;
	}
	
	@Override
	public int getRows() {
		return display.getRows();
	}
	
	@Override
	public String getRowText(int row) {
		return borderChar + display.getRowText(row) + borderChar;
	}
}
package decorator;

public class FullBorder extends Border {

	public FullBorder(Display display) {
		super(display);
	}
	
	@Override
	public int getColumns() {
		return 1 + display.getColumns() + 1;
	}
	
	@Override
	public int getRows() {
		return 1 + display.getRows() + 1;
	}
	
	@Override
	public String getRowText(int row) {
		if(row == 0) return "+" + makeLine('-', display.getColumns()) + "+";
		else if(row == display.getRows() + 1) return "+" + makeLine('-', display.getColumns()) + "+";
		else return "|" + display.getRowText(row -1) + "|";
	}
	
	private String makeLine(char ch, int count) {
		StringBuffer buf = new StringBuffer();
		
		for(int i = 0; i < count; i++) {
			buf.append(ch);
		}
		return buf.toString();
	}
}
package decorator;

public class Main {

	public static void main(String[] args) {
		Display b1 = new StringDisplay("Hello, world.");
		Display b2 = new SideBorder(b1, '#');
		Display b3 = new FullBorder(b2);
		
		b1.show();
		System.out.println();
		b2.show();
		System.out.println();
		b3.show();
		System.out.println();
		
		Display b4 = new SideBorder(
						new FullBorder(
								new FullBorder(
										new SideBorder(
												new FullBorder(
														new StringDisplay("안녕하세요")
												), '*'
										)
								)
						), '/');
		
		b4.show();
	}
}

 

 

결과:

Hello, world.

#Hello, world.#

+---------------+
|#Hello, world.#|
+---------------+

/+---------------------+/
/|+-------------------+|/
/||*+---------------+*||/
/||*|안녕하세요|*||/
/||*+---------------+*||/
/|+-------------------+|/
/+---------------------+/

'자바' 카테고리의 다른 글

[자바] 싱글톤이 보장받지 않는 상황  (0) 2021.06.03
[자바] builder 패턴  (0) 2021.06.03
List의 중복제거, HashSet  (1) 2021.05.24
[자바] 재귀함수와 증감연산자  (0) 2021.05.15
람다  (0) 2021.04.05