02. 예제 프로그램

Download Report

Transcript 02. 예제 프로그램

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