Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
design_pattern:decorator_pattern [2017/10/29 13:07] – 만듦 ledyxdesign_pattern:decorator_pattern [2022/06/14 17:59] (current) – [Decorator Pattern] ledyx
Line 1: Line 1:
 = Decorator Pattern = = Decorator Pattern =
-장식과 내용물을 동일시해서 장식을 여러 겹 중복되게 하기+장식과 내용물을 동일시해서 장식을 여러 겹 중복되게 하기. 투과적인 인터페이스(API)를 갖는다. (예를 들어 케이크에 초콜릿으로 코팅하면 초콜릿 케이크, 생크림으로 코팅하면 생크림 케이크) 
 +  * 장식이 되는 기능을 하나씩 추가하면서 좀 더 목적에 맞는 객체 만들기 
 +    * 기능 확장이 필요할 때 서브클래싱 대신 쓸 수 있는 유연한 대안 [(https://ko.wikipedia.org/wiki/%EB%8D%B0%EC%BD%94%EB%A0%88%EC%9D%B4%ED%84%B0_%ED%8C%A8%ED%84%B4)] 
 +  * [[Composite Pattern]]과 무엇이 다른가? 
 +    * "Decorator Pattern은 테두리 장식을 중복해서 **__<fc red>기능을 추가</fc>__**"하는 것에 집중. 이 때, 내용물을 변경하지 않고 기능을 추가할 수 있다. 
 +  * 예시 
 +<sxh java ; gutter:false> 
 +BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("text.txt"))) 
 +</sxh>
  
 +{{tag>Architecture Modeling Design_Pattern Structural}}
  
 += Component =
 +<sxh java>
 +package component;
 +import java.util.stream.IntStream;
  
-{{tag>Architecture Modeling DesignPattern Structional}}+public abstract class Display { 
 + public abstract int getColumns(); 
 + public abstract int getRows(); 
 + public abstract String getRowText(int row); 
 + public final void show() { 
 + IntStream.range(0, getRows()).forEach(row -System.out.println(getRowText(row))); 
 + } 
 +} 
 +</sxh>
  
 +== ConcreteComponent ==
 +<sxh java>
 +package component;
 +
 +public class StringDisplay extends Display {
 + private String str;
 +
 + public StringDisplay(String str) {
 + this.str = str;
 + }
 +
 + @Override
 + public int getColumns() {
 + return str.getBytes().length;
 + }
 +
 + @Override
 + public int getRows() {
 + return 1;
 + }
 +
 + @Override
 + public String getRowText(int row) {
 + return row == 0? str : null;
 + }
 +}
 +</sxh>
 +
 +
 +== Decorator ==
 +<sxh java ; highlight:[6,8-10]>
 +package decorator;
 +import component.Display;
 +
 +public abstract class Border extends Display {
 +
 + protected Display display; // 내용물
 +
 + public Border(Display display) {
 + this.display = display;
 + }
 +}
 +</sxh>
 +
 +
 +=== ConcreteDecorator ===
 +
 +<sxh java>
 +package decorator;
 +
 +public class SideBorder extends Border {
 + private char borderDecorator;
 +
 + public SideBorder(Display display, char borderDecorator) {
 + super(display);
 + this.borderDecorator = borderDecorator;
 + }
 +
 + @Override
 +    public int getColumns() {
 +        return display.getColumns() + 2; // 양쪽 장식물 길이 더한 값
 +    }
 + 
 +    @Override
 +    public int getRows() {
 +        return display.getRows();
 +    }
 + 
 +    @Override
 +    public String getRowText(int row) {
 +        StringBuilder sb = new StringBuilder();
 +        sb.append(borderDecorator);
 +        sb.append(display.getRowText(row));
 +        sb.append(borderDecorator);         
 +        return sb.toString();
 +    }
 +}
 +</sxh>
 +
 +<sxh java>
 +package decorator;
 +
 +import java.util.stream.IntStream;
 +
 +import component.Display;
 +
 +public class FullBorder extends Border {
 +
 + public FullBorder(Display display) {
 + super(display);
 + }
 +
 + @Override
 + public int getColumns() {
 + return display.getColumns() + 2; // 양쪽 장식물 길이 더한 값
 + }
 +
 + @Override
 + public int getRows() {
 + return display.getRows() + 2; // 상하 장식물 길이 더한 값
 + }
 +
 + @Override
 + public String getRowText(int row) {
 + StringBuilder sb = new StringBuilder();
 +
 + // 상하 사이인 경우
 + if(0 < row && row < display.getRows() + 1) {
 + sb.append('|');
 + sb.append(display.getRowText(row - 1));
 + sb.append('|');
 + }
 + else {
 + sb.append('+');
 + IntStream.range(0, display.getColumns()).forEach(i -> sb.append('-'));
 + sb.append('+');
 + }
 +
 + return sb.toString();
 + }
 +}
 +</sxh>
 +
 +
 += Client =
 +<sxh java>
 +import component.Display;
 +import component.StringDisplay;
 +import decorator.FullBorder;
 +import decorator.SideBorder;
 +
 +public class Main {
 +    public static void main(String[] args) {
 +    Display component = new StringDisplay("Hello world");
 +    Display decorator1 = new SideBorder(component, '#');
 +    Display decorator2 = new FullBorder(decorator1);
 +   
 +    component.show();
 +    decorator1.show();
 +    decorator2.show();
 +   
 +    System.out.println();
 +   
 +    Display composite = new SideBorder(
 +     new FullBorder(
 +     new FullBorder(
 +    new SideBorder(
 + new FullBorder(
 + new StringDisplay("Hello world")
 + ) , '*')))
 +     , '/');
 +    composite.show();
 +    }
 +}
 +
 +
 +/*
 +Hello world
 +#Hello world#
 ++-------------+
 +|#Hello world#|
 ++-------------+
 +
 +/+-----------------+/
 +/|+---------------+|/
 +/||*+-----------+*||/
 +/||*|Hello world|*||/
 +/||*+-----------+*||/
 +/|+---------------+|/
 +/+-----------------+/
 +*/
 +</sxh>
design_pattern/decorator_pattern.1509282438.txt.gz · Last modified: 2021/02/07 03:15 (external edit)