728x90
출처 : 책 - java 언어로 배우는 디자인 패턴 입문
12. Decorator - 장식과 내용물을 동일시하기
1. 목적
- 케이크에 크림을 바르고, 초콜릿을 입혀나가는 것처럼 이전 클래스를 받아 기능을 점차 추가(장식)해 나간다.
- 장점 : 내용물을 변경하지 않고 기능을 추가할 수 있다.
장식의 종류가 다른 오브젝트를 유연하게 생성할 수 있다.
- 단점 : 작은 클래스가 많아진다.
잘 설명되어 잇는 유튜브를 소개한다.
2. 예제
(1) Display - 추상 클래스
public abstract class Display {
public abstract int getColumns();
public abstract int getRows();
public abstract String getRowText(int row);
public void show() {
for (int i = 0; i < getRows(); i++) {
System.out.println(getRowText(i));
}
}
}
(2) StringDisplay - 1행만 표현하는 클래스. Display의 하위 클래스이다.
public class StringDisplay extends Display {
private String string;
public StringDisplay(String string) {
this.string = string;
}
public int getColumns() {
return string.getBytes().length;
}
public int getRows() {
return 1;
}
public String getRowText(int row) {
if (row == 0) {
return string;
} else {
return null;
}
}
}
(3) Border - Display 클래스를 감싸고, 상속의 기준이 되는 Border 클래스를 만들어준다.
메소드의 구현보다 Display 클래스를 감싸고 있는 '장식' 클래스라는 의미가 더 중요하다.
장식클래스들의 기준이 되는 부모 추상 클래스이다.
( StringDisplay는 Display 의 하위 클래스이므로 Display로 받을 수 있기에 Border가 또한 감쌀 수 있다 )
public abstract class Border extends Display {
protected Display display;
protected Border(Display display) {
this.display = display;
}
}
(4) SideBorder - 좌우 경계 기능(장식) 추가
public class SideBorder extends Border {
private char borderChar;
public SideBorder(Display display, char ch) {
super(display);
this.borderChar = ch;
}
public int getColumns() {
return 1 + display.getColumns() + 1;
}
public int getRows() {
return display.getRows();
}
public String getRowText(int row) {
return borderChar + display.getRowText(row) + borderChar;
}
}
(5) FullBorder - 상하좌우 경계 기능(장식) 추가.
public class FullBorder extends Border {
public FullBorder(Display display) {
super(display);
}
public int getColumns() {
return 1 + display.getColumns() + 1;
}
public int getRows() {
return 1 + display.getRows() + 1;
}
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();
}
}
(6) Main
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();
b2.show();
b3.show();
Display b4 =
new SideBorder(
new FullBorder(
new FullBorder(
new SideBorder(
new FullBorder(
new StringDisplay("안녕하세요.")
),
'*'
)
)
),
'/'
);
b4.show();
}
}
728x90
'개발 > 디자인 패턴' 카테고리의 다른 글
[Java 언어로 배우는 디자인 패턴 입문] 구조를 돌아다니기 14. Chain of Responsibility (0) | 2021.01.12 |
---|---|
[Java 언어로 배우는 디자인 패턴 입문] 구조를 돌아다니기 13. Visitor (0) | 2021.01.11 |
[Java 언어로 배우는 디자인 패턴 입문] 동일시하기 11. Composite (0) | 2021.01.10 |
[Java 언어로 배우는 디자인 패턴 입문] 분리해서 생각하기 10. Strategy (0) | 2021.01.10 |
[Java 언어로 배우는 디자인 패턴 입문] 분리해서 생각하기 9. Bridge (0) | 2021.01.10 |
댓글