280 likes | 472 Views
Java 로 배우는 디자인패턴 입문 Chapter 12. Decorator 장식과 내용물의 동일시. 2004-1. 01. Decorator 패턴. 예 : 케이크 스펀지 케이크 딸기를 얹으면 => 스트로베리 케이크 화이트 초콜릿 + 초 => 생일 케이크 중심이 되는 객체에 , 장식과 같은 부가적인 기능을 하나씩 입혀서 좀 더 목적에 어울리는 객체를 만들자 . 02. 예제 프로그램. 문자열 주위에 장식 (-, +, | 문자 ) 을 입혀 표시하는 프로그램. 02. 예제 프로그램.
E N D
Java로 배우는 디자인패턴 입문Chapter 12. Decorator장식과 내용물의 동일시 2004-1
01. Decorator 패턴 • 예: 케이크 • 스펀지 케이크 • 딸기를 얹으면 => 스트로베리 케이크 • 화이트 초콜릿 + 초 => 생일 케이크 • 중심이 되는 객체에, 장식과 같은 부가적인 기능을 하나씩 입혀서 좀 더 목적에 어울리는 객체를 만들자. 12. Decorator
02. 예제 프로그램 • 문자열 주위에 장식(-, +, | 문자)을 입혀 표시하는 프로그램 12. Decorator
02. 예제 프로그램 12. Decorator
02. 예제 프로그램 12. Decorator
02. 예제 프로그램 • Display 클래스 • 여러 줄로 이루어진 문자열을 표시하기 위한 추상 클ㄹ스 • getColumns( ): 가로의 문자 수를 얻기 위한 메소드 • getRows( ): 세로의 줄의 수를 얻기 위한 메소드 • getRowText( ): 지정한 줄의 문자열을 얻기 위한 메소드 • show( ) • 모든 줄을 화면에 표시하는 메소드 • Template Method 패턴이 적용됨 12. Decorator
02. 예제 프로그램 • StringDisplay 클래스 • 한 줄의 문자열을 표시하는 클래스 • string 필드: 표시할 문자열을 저장함 • getColumns( ): string.getBytes().length 를 이용하여 문자열이 차지하는 바이트 수를 반환함 • getRows( ): 1을 반환함 • getRowText(int row): 입력 매개 변수 row가 0일 때만 string 필드를 반환한다. • 이 클래스는, 여러 케이크의 중심에 있는 스펀지 케이크에 해당함 12. Decorator
02. 예제 프로그램 • Border 클래스 • ‘장식’을 나타내는 추상 클래스 • Display의 하위 클래스로 정의됨 • 장식(Border)이 내용물(Display)과 동일한 메소드를 가진다. • 장식과 내용물을 동일시 할 수 있다. • 장식 클래스를 내용물로 해서 또 다른 장식을 붙일 수 있다는 의미 • display 필드: Display 형으로 선언됨 • 장식이 감싸고 있는 “내용물”을 가리킨다. • 이 필드는, StringDisplay 뿐 만 아니라 Border 도 참조할 수 있다. • 이유: Border도 Display의 하위 클래스이므로 12. Decorator
02. 예제 프로그램 • SideBorder 클래스 • Border의 하위 클래스 • 구체적인 장식의 일종 • 문자열 좌우에 정해진 문자(BorderChar)로 장식한다. • 생성자에서, 내용물(display)과 장식 문자(ch)가 지정됨 • getColumns( ): 내용물의 문자 수에 2를 더한다. • getRows( ): 내용물의 getRows( )를 호출한다. • getRowText( ): 내용물의 Text 양쪽에 장식 문자를 연결하여 반환한다. 12. Decorator
02. 예제 프로그램 • FullBorder 클래스 • Border의 하위 클래스 • 상하좌우에 장식을 한다. • SideBorder와 달리, 장식할 문자가미리 고정되어 있다. • makeLine(char ch, int count): ch를 count 갯수 만큼 연속해서 문자열로 만드는 메소드 • getRowText(int row) • 입력인자 row가, 0 이거나 (내용물의 전체 줄 수 +1)과 같으면 문자열 상단 또는 하단에 장식할 문자열을 만든다. 12. Decorator
02. 예제 프로그램 • Main 클래스 • 동작 테스트용 클래스 • b1 객체: ‘Hello, world.’를 장식하지 않고 표시한 것 • b2 객체: b1에 대해 ‘#’ 문자로 좌우에 장식한 것 • b3 객체: b2에 대해 전체 장식을 한 것 • b4 객체: ‘안녕하세요’에 여려 겹 장식을 한 것 12. Decorator
02. 예제 프로그램 12. Decorator
03. 등장 역할 • Component의 역할 • 기능을 추가할 때 핵심이 되는 역할 • 스펀지 케이크에 해당함 • 예제에서는, Display 클래스가 해당됨 • ConcreteComponent의 역할 • Component 역할을 구현한 구체적인 클래스 • 구체적인 스펀지 케이크에 해당함 • 예제에서는, StringDisplay 클래스가 해당됨 12. Decorator
03. 등장 역할 • Decorator(장식자)의 역할 • Component 역할과 동일한 인터페이스를 가짐 • 장식자이면서, 장식할 대상이 되기도 한다. • 예제에서는, Border 클래스가 해당됨 • Concrete Decorator의 역할 • 구체적인 장식자 • 예제에서는, SideBorder와 FullBorder 클래스가 해당됨 12. Decorator
03. 등장 역할 12. Decorator
04. 독자의 사고를 넓혀주는 힌트 • 투과적인 인터페이스(API) • Border 클래스가 Display 클래스의 하위 클래스 • 장식을 나타내는 Border 클래스가, 내용물을 나타내는 Display와 동일한 인터페이스(API)를 가진다. • => 장식하는 클래스가, 다시 장식의 대상이 될 수 있다. • getColumns, getRows, getRowText, show 메소드는 은폐되지 않고, 다른 클래스에서 볼 수 있다. => 투과적 • Composite과 마찬가지로 재귀적인 구조임 • 목적이 서로 다르다. • Composite 패턴은, container가 다시 내용물이 될 수 있다. • Decorator 패턴은, 장식하는 클래스가, 다시 장식 대상이 될 수 있다. • 예: FullBorder의 getRowText( )는 자신이 가지고 있는 Display 객체의 getRowText( ) 메소드를 호출한다. 12. Decorator
04. 독자의 사고를 넓혀주는 힌트 • 내용물을 변경하지 않고, 기능을 추가할 수 있다 • 내용물을 변경하지 않고, 새로운 장식을 계속해서 부착할 수 있다. • 포장되는 대상을 변경하지 않고, 기능을 추가할 수 잇다. • Decorator 패턴에서는 위임이 사용된다. • 예: SideBorder의 getColumns 메소드 내에서는, display.getColumns( ) 를 호출한다. 12. Decorator
04. 독자의 사고를 넓혀주는 힌트 • 단순한 장식으로도 다양한 기능을 추가할 수 있다. • 간단한 구체적인 장식(ConcreteDecorator 역할)을 많이 준비해 두고, 그것들을 자유롭게 조합하여 새로운 장식을 만들 수 있다. 12. Decorator
04. 독자의 사고를 넓혀주는 힌트 • java.io 패키지와 Decorator 패턴 • 입출력 관련 패키지 java.io 에, Decorator 패턴이 사용됨 • 예: • 파일로부터 데이터 읽어 들일 때 • 버퍼링 기능 추가 Reader reader = new FileReader(“datafile.txt”); Reader reader = new BufferedReader( new FileReader(“datafile.txt”); ); 12. Decorator
04. 독자의 사고를 넓혀주는 힌트 • java.io 패키지와 Decorator 패턴 • 예(계속): • 줄 번호 관리 기능 추가 • 또 다른 조합 (버퍼링은 실행 안 함) • javax.swing.border 패키지에도, 화면에 표시되는 컴포넌트에 추가할 수 잇는 장식용 클래스들이 모여있다. Reader reader = new LineNumberReader( new BufferedReader( new FileReader(“datafile.txt”); ) ); Reader reader = new LineNumberReader( new FileReader(“datafile.txt”); ); 12. Decorator
04. 독자의 사고를 넓혀주는 힌트 • 작은 클래스가 증가함 • Decorator 패턴을 사용하면, 유사한 작은 클래스들이 많아지는 단점이 있다. 12. Decorator
05. 관련 패턴 • Adapter 패턴 • Strategy 패턴 12. Decorator
06. 보강: 상속과 위임에 있어서의 동일시 • 상속 – 하위 클래스와 상위 클래스의 동일 시 • Child의 인스턴스를 Parent 형 변수에 그대로 대입하고, Parent로 부터 상속받은 메소드를 그대로 불러낼 수 있다. • 하위 클래스의 메소드를 불러내기 위해서는 type cast 가 필요함 class Parent { ... void parentMethod( ) { ... } } class Child extends Parent { ... void ChildMethod( ) { ... } } Parent obj = new Child( ); obj.parentMethod( ); Parent obj = new Child( ); ((Child)obj).childMethod( ); 12. Decorator
06. 보강: 상속과 위임에 있어서의 동일시 • 위임 – 자신과 위임할 곳을 동일 시 • Rose 와 Violet이 똑같은 메소드 method를 가지고 있고, Rose는 Violet에게 위임한다. class Rose{ Violet obj = ... void method( ) { obj.method(); } } class Violet { void method( ) { ... } } 12. Decorator
06. 보강: 상속과 위임에 있어서의 동일시 • 위임 – 자신과 위임할 곳을 동일 시 • Flower 라는 공통 상위 클래스를 정의하면, ‘공통 정보 공유’가 명확해 진다. abstract class Flower { abstract void method( ); } class Rose extends Flower{ Violet obj = ... void method( ) { obj.method(); } } class Violet extends Flower{ void method( ) { ... } } 12. Decorator
06. 보강: 상속과 위임에 있어서의 동일시 • 위임 – 자신과 위임할 곳을 동일 시 • Flower 는 인터페이스일 수 도 있다. interface Flower { abstract void method( ); } class Rose implements Flower{ Violet obj = ... void method( ) { obj.method(); } } class Violet implements Flower{ void method( ) { ... } } Flower 형으로 선언하는 것이 더 좋을 수 있다. 12. Decorator
07. 요약 • 객체를 차례차례 장식해서, 기능을 추가해 나가는 Decorator 패턴 12. Decorator
연습 문제 • Q12-1 • 문자열 아래 위로 장식문자를 추가하는 UpDownBorder 클래스 만들기 • Q12-2 • 여러 줄의 문자열을 표시하는 MultiStringDisplay 클래스 만들기 • ConcreteComponent 역할 수행 12. Decorator