노트북을 살때 파우치를 사고 케이스를 사고 필름사면서 노트북을 꾸며 주듯이 객체를 만들 때 객체에 기능을 더해가는 패턴을 Decorater Pattern입니다.
객체를 생성할 때 기능을 추가하는데 특화된 패턴입니다.
일단 예제 코드를 작성해보겠습니다.
Display.java
public abstract class Display{ public abstract int getRows(); public abstract int getColumns(); public abstract String getRowText(int line); public void show(){ for(int i=0; i < getRows(); i++) System.out.println(getRowText(i)); } }
StringDisplay.java(꾸며지는 객체)
public class StringDisplay extends Display{ String string; public StringDisplay(String string){ this.string = string; }
public int getRows(){ return 1; } public int getColumns(){ return string.getBytes().length; } public String getRowText(int line){ if (line ==0) return string; else return null; } }
Border.java
public abstract class Border extends Display{ Display display; public Border(Display display){ this.display = display; } }
추상클래스 Display를 Border에 상속해주고 있다. 둘은 결국엔 동일한 메소드들을 갖게되고
SideBorder.java(꾸며주는 클래스)
public class SideBorder extends Border{ char side; public SideBorder(Display display, char side){ super(display); this.side = side; }
public int getRows(){ return display.getRows(); } public int getColumns(){ return 1+display.getColumns()+1; } public String getRowText(int line){ return side+display.getRowText(line)+side; } }
FullBorder.java(꾸며주는 클래스)
public class FullBorder extends Border{
public FullBorder(Display display){ super(display); }
public int getRows(){ return 1+display.getRows()+1; } public int getColumns(){ return 1+display.getColumns()+1; } public String getRowText(int line){ if(line == 0) return "+"+makeLine(display.getColumns())+"+"; else if(line == display.getRows()+1) return "+"+makeLine(display.getColumns())+"+"; else return "|"+ display.getRowText(line-1)+"|"; } private String makeLine(int limit){ StringBuilder stringBuilder = new StringBuilder(); for(int i =0; i < limit; i++) stringBuilder.append("-"); return stringBuilder.toString(); } }
result
public class Main { public static void main(String[] args){ StringDisplay d1 = new StringDisplay("Decorator"); SideBorder d2 = new SideBorder(d1, '#'); FullBorder d3 = new FullBorder(d2); d1.show(); d2.show(); d3.show(); } }