* Decorator Pattern
Decorator : 장식하는 사람이라는 뜻. 기능을 마치 장식처럼 계속 추가할 수 있는 패턴. 또 기능을 실행 중에 동적으로 변경, 확장할 수 있는 패턴. SW의 확장성이 매우 높아짐.
Strings: 문자열을 여러 개 가지고 있음. 장식할 대상. 장식이 없는 내용물.
Decorator: Strings의 장식들을 나타내는 클래스.
3개의 Decorator를 상속하는 클래스 : 구체적인 장식을 구현한 클래스
Item : Strings 와 Decorator가 상속하는 클래스. 두 개의 서로 다른 개념을 하나의 개념으로 다룰 수 있는 장치. 내용물과 장식에 대한 구분 없이 둘을 동일한 개념으로 다룰 수 있음.

장식 필요한 기본 Strings 와 장식 하는 객체 Decorator 를 하나의 개념으로 다루기 위한 추상 클래스 Item
아래 예제는 기본 Strings 에 장식을 다는 예로, Item 클래스에선 기본적으로 출력하는 메서드가 있다.
public abstract class Item {
public abstract int getLinesCount(); // 문자열의 개수 (라인 수) 반환
public abstract int getMaxLength(); // 문자열 중 가장 긴 문자열 길이 반환
public abstract int getLength(int index); // 지정된 index의 문자열 길이 반환
public abstract String getString(int index); // 지정된 index의 문자열 반환
public void print() {
int cntLines = getLinesCount();
for(int i=0; i<cntLines; i++) {
String string = getString(i);
System.out.println(string);
}
}
}
장식이 없는 상태 Strings
public class Strings extends Item {
private ArrayList<String> strings = new ArrayList<>();
public void add(String item) {
strings.add(item);
}
@Override
public int getLinesCount() {
return strings.size();
}
@Override
public int getMaxLength() {
Iterator<String> iter = strings.iterator();
int maxWidth = 0;
while(iter.hasNext()) {
String string = iter.next();
int width = string.length();
if(width > maxWidth) maxWidth = width;
}
return maxWidth;
}
@Override
public int getLength(int index) {
String string = strings.get(index);
return string.length();
}
@Override
public String getString(int index) {
return strings.get(index);
}
}
장식을 위해 Item 객체를 필드에 갖는 Decorator 추상 클래스.
public abstract class Decorator extends Item {
protected Item item;
public Decorator(Item item) {
this.item = item;
}
}
Item의 좌, 우에 ch를 추가하는 SideDecorator
public class SideDecorator extends Decorator {
private Chractor ch;
public SideDecorator(Item item, Charactor ch) {
super(item);
this.ch = ch;
}
@Override
public int getLinesCount() {
return item.getLinesCount();
}
@Override
public int getMaxLength() {
return item.getMaxLength() + 2;
}
@Override
public int getLength(int index) {
return item.getLength(index) + 2;
}
@Override
public String getString(int index) {
return ch + item.getString(index) + ch;
}
}
Strings를 박스로 감싸는 BoxDecorator
public class BoxDecorator extends Decorator {
public BoxDecorator(Item item) {
super(item);
}
@Override
public int getLinesCount() {
return item.getLinesCount() + 2;
}
@Override
public int getMaxLength() {
return item.getMaxLength() + 2;
}
@Override
public int getLength(int index) {
return item.getLength(index) + 2;
}
@Override
public String getString(int index) {
int maxWidth = this.getMaxLength();
if(index == 0 || index == getLineCount()-1) {
StringBuilder sb = new StringBuilder();
sb.append('+');
for(int i=0; i<maxWidth-2; i++) {
sb;append('-');
}
sb.append('+');
return sb.toString();
} else {
return '|' + item.getString(index-1)
+ makeTailString(maxWidth - getLength(index -1));
}
}
private String makeTailString(int count) {
StringBuilder sb = new StringBuilder();
for(int i=0; i<count; i++) {
sb.append(' ');
}
sb.append('|')l
return sb.toString();
}
}
구현한 클래스를 main 에서 사용해본다.
public static void main(String[] args) {
Strings strings = new Strings();
strings.add("Hello");
strings.add("My name is Choi");
strings.add("I am a JAVA Developer.");
strings.add("Design-Pattern is powerful tool.");
Item decorator = new SideDecorator(strings, '\"');
decorator = new BoxDecorator(decorator);
decorator.print();'코딩 > Software Architecture' 카테고리의 다른 글
| [GoF Design Pattern] Chain of Responsibility (0) | 2022.12.06 |
|---|---|
| [GoF Design Pattern] Mediator (0) | 2022.12.06 |
| [GoF Design Pattern] Memento (0) | 2022.12.05 |
| [GoF Design Pattern] Builder (0) | 2022.12.04 |
| [GoF Design Pattern] Facade (0) | 2022.12.04 |