'XML Developer/디자인 패턴'에 해당되는 글 12건

  1. 2008/01/21 [디자인 패턴#12] 스테이트 패턴
  2. 2007/10/24 [디자인 패턴#11] 컴포지트 패턴
  3. 2007/10/17 [디자인 패턴#10] 이터레이터 패턴
  4. 2007/09/05 [디자인 패턴#9] 템플릿 메소드 패턴
  5. 2007/08/10 [디자인 패턴#8] 어댑터와 퍼사드 패턴
  6. 2007/06/01 [디자인 패턴#7] 커맨드 패턴
  7. 2007/05/22 [디자인 패턴#6] 싱글턴 패턴
  8. 2007/05/09 [디자인 패턴#5] 추상 팩토리 패턴
  9. 2007/05/03 [디자인 패턴#4] 팩토리 메소드 패턴
  10. 2007/04/27 [디자인 패턴#3] 데코레이터 패턴

[디자인 패턴#12] 스테이트 패턴

|


State Pattern - 디자인 패턴

 
참고서적 :  Head First Design Pattern
소스코드 다운로드 : http://www.wickedlysmart.com/headfirstdesignpatterns/code.html
 
패턴 정의 #12 - 스테이트(state) Pattern
객체의 내부 상태가 바뀜에 따라서 객체의 행동을 바꿀 수 있습니다.
마치 객체의 클래스가 바뀌는 것과 같은 결과를 얻을 수 있습니다.
 
음료수 자판기와 같은 vending machine을 설계할 때, 스테이트 다이어그램을 그려봤을 겁니다.
이러한 경우에 사용하는 디자인 패턴입니다.
 
중첩된 if문으로 각각의 상태를 체크하는 대신,
각각의 상태를 구상 클래스로 정의해서 사용하는 방식입니다.
 
클래스의 개수가 많아질 수 있다는 단점은 있지만.. 상태의 추가에 대한 확장성이 매우 뛰어난 패턴입니다.
스트레티지 패턴과도 형식은 유사하지만, 사용하는 의미가 다르다고 이해하시면 됩니다.
 


클래스 다이어그램은 다음과 같습니다.
 


 
- Context라는 클래스에는 여러 가지 내부 상태가 들어갈 수 있습니다.
- Context의 request() 메소드가 호출되면, 그 작업은 상태 객체에게 맡겨집니다.
- State 인터페이스에서는 모든 구상 상태 클래스에 대한 공통 인터페이스를 정의합니다.
모든 상태 클래스에서 같은 인터페이스를 구현하기 때문에 바꿔가면서 쓸 수 있습니다.
- Concrete State에서는 Context로부터 전달된 요청을 처리합니다.
각 Concrete State에서 그 요청을 처리하는 방법을 자기 나름의 방식으로 구현합니다.
이렇게 하고 Context에서 상태를 바꾸기만 하면 행동도 바뀌게 됩니다.

 
크리에이티브 커먼즈 라이선스
Creative Commons License




Trackback 0 And Comment 0

[디자인 패턴#11] 컴포지트 패턴

|


Composite Pattern - 디자인 패턴
 
참고서적 : Head First Design Pattern
소스코드 다운로드 : http://www.wickedlysmart.com/headfirstdesignpatterns/code.html

패턴 정의 #11 - 컴포지트(composite) Pattern

객체들을 트리 구조로 구성하여 부분과 전체를 나타내는 계층구조를 만들 수 있습니다.
이 패턴을 이용하면 클라이언트에서 개별 객체와 다른 객체들로 구성된 복합 객체(composite)를 똑같은 방법으로 다룰 수 있습니다.

트리 구조를 살펴보면 노드(node)와 잎(leaf)으로 구성되어 있는 것을 알 수 있습니다.
이러한 노드와 잎을 한가지 형태로 표현할 수 있도록 구성되어 있는 것이 컴포지트 패턴입니다.
그래서 부분-전체 계층구조를 생성할 수 있다고 이야기 합니다.

이렇게 하기 위해서 기본적으로 컴포지트 컴포넌트에는 노드에서 하는 역할과 잎에서 하는 역할이 모두 포함되어야 합니다.

클래스 다이어그램을 살펴보면 Leaf와 Composite가 Component를 구현하고 있는데, 서로 필요한 메소드만 구현한 것을 알 수 있습니다.



- 클라이언트에서는 Component 인터페이스를 이용하여 복합 객체 내의 객체들을 조작할 수 있습니다.
- Component에서는 복합객체 내에 들어있는 모든 객체들에 대한 인터페이스를 정의합니다.

즉, 노드 뿐만 아니라 잎에 대한 메소드까지 정의하는 겁니다.
- Component에서 add(), remove(), getChild() 및 몇가지 작업에 대한 기본 행동을 정의할 수도 있습니다.


크리에이티브 커먼즈 라이선스
Creative Commons License




Trackback 0 And Comment 0

[디자인 패턴#10] 이터레이터 패턴

|


Iterator Pattern - 디자인 패턴

참고서적 : Head First Design Pattern
소스코드 다운로드 : http://www.wickedlysmart.com/headfirstdesignpatterns/code.html
 
패턴 정의 #10 - 이터레이터(iterator) Pattern
컬렉션 구현 방법을 노출시키지 않으면서도 그 집합체 안에 들어있는 모든 항목에 접근할 수 있게 해주는 방법을 제공합니다.
 
반복적으로 처리해야 하는 것을 통합해 주는 패턴입니다.
배열, ArrayList, Hashtable등의 리스트 처리 방식이 모두 다릅니다.
이런 것을 iterator 패턴을 이용하면 동일한 방식으로 처리할 수 있습니다.
 
배열의 경우에는 직접 구현해 주어야 하지만, ArrayList나 Hashtable의 경우 java.util.Iterator를 이용하면 됩니다.
 
디자인 원칙
1. 클래스를 바꾸는 이유는 한 가지 뿐이어야 한다.
-> 클래스는 한가지 목적을 가지고 사용해야 한다는 의미입니다.
(두 가지 이상의 목적을 가지고 구현이 될 경우, 두 가지 이유 때문에 변경해야 하는 문제점도 발생할 수 있기 때문입니다.)
 
이터레이터 패턴은 일반적으로 많이 사용하기 때문에 클래스 다이어그램을 이해하는데 큰 어려움이 없을 것입니다.
iterator 인터페이스가 제공하는 hasNext(), next(), remove() 메소드를 유의해서 살펴보시기 바랍니다.



- Iterator 인터페이스에서는 모든 반복자에서 구현해야 하는 인터페이스를 제공하며
컬렉션에 들어있는 원소들에 돌아가면서 접근할 수 있게 해 주는 메소드들을 제공해야 합니다.
여기에서는 java.util.Iterator를 사용합니다.
자바에서는 기본으로 제공하는 Iterator 인터페이스를 사용하고 싶지 않다면 직접 인터페이스를 만들어서 써도 됩니다.
 

크리에이티브 커먼즈 라이선스
Creative Commons License




Trackback 0 And Comment 0

[디자인 패턴#9] 템플릿 메소드 패턴

|


Template Method Pattern - 디자인 패턴

참고서적 : Head First Design Pattern
소스코드 다운로드 : http://www.wickedlysmart.com/headfirstdesignpatterns/code.html
 
패턴 정의 #9 - 템플릿 메소드 (Template Method) Pattern
템플릿 메소드 패턴에서는 메소드에서 알고리즘의 골격을 정의합니다.
알고리즘의 여러 단계 중 일부는 서브클래스에서 구현할 수 있습니다.
템플릿 메소드를 이용하면 알고리즘의 구조는 그대로 유지하면서 서브클래스에서 특정 단계를 재정의 할 수 있습니다.
 
알고리즘의 템플릿 즉, 틀을 만들기 위한 패턴입니다.
추상클래스를 만들어 두고, 여기에 templateMethod를 둡니다.
templateMethod에서는 알고리즘에 따라 여러 메소드를 호출하고..
각각의 메소드는 추상클래스에 구현되어 있기도 하고 서브클래스에서 직접 구현해야 하는 것도 있습니다.
 
클래스 다이어그램을 통해서 살펴보도록 하지요~




- AbstractClass에 템플릿 메소드가 들어있습니다.
abstract 메소드로 선언된 단계(메소드)들이 템플릿 메소드에서 활용됩니다.
- ConcreteClass는 여러개가 있을 수 있습니다.
각 클래스에서는 템플릿 메소드에서 요구하는 모든 단계들을 제공해야 합니다.
- 템플릿 메소드에서는 알고리즘을 구현할 때, primitiveOperation1과 primitiveOperation2를 활용합니다.
알고리즘 자체는 이 단계들의 구체적인 구현으로부터 분리되어 있습니다.
- abstract로 선언되었던 단계들은 ConcreteClass에서 구현합니다.
templateMethod()에서는 이런 메소드를 호출해서 작업을 처리합니다.
 
추가적으로 concreteOperation은 추상 클래스내에 구현되어 있는 것입니다. 이것은 서브클래스에서 상속받을 필요가 없습니다.
옵션을 설정하는 등의 경우에 따라 concreteOperation도 상속받아 구현할 필요가 있을 수 있습니다.
그러한 것을 후크(hook)라고 이야기 합니다.
후크를 이용하면 알고리즘의 단계를 옵션에 따라 변경할 수도 있습니다.


디자인 원칙
1. 헐리우드 원칙 - 먼저 연락하지 마세요. 저희가 연락 드리겠습니다.
 
각각의 구성요소들이 언제 어떤식으로 사용되는지를 결정하는 것은 고수준의 구성요소(즉 수퍼 클래스)에서 한다는 의미입니다.
템플릿 메소드 패턴, 팩토리 메소드 패턴, 옵저버 패턴, 커맨드 패턴등이 여기에 따르는 것이 아닐까 합니다.
 
실제로 JAVA API 중 템플릿 메소드 패턴을 사용하는 것은 다음과 같다고 합니다.
 
1. 배열에서의 sort 메소드 (compareTo라는 primitiveOperation 호출)
2. JFrame에서의 paint 메소드 (대표적인 후크 메소드)
3. Applet에서의 init, start, stop, destory, paint 메소드 (역시 후크 메소드..)

 
다음 사항은 유사한 각 패턴의 비교입니다.
 
템플릿 메소드 패턴 - 알고리즘의 일부 단계를 구현하는 것을 서브클래스에서 처리합니다.
스트래티지 패턴 - 바꿔 쓸 수 있는 행동을 캡슐화 하고, 어떤 행동을 사용할 지는 서브클래스에 맡깁니다.
팩토리 메소드 패턴 - 어떤 구상 클래스를 생성할지를 서브 클래스에 결정합니다.
 
크리에이티브 커먼즈 라이선스
Creative Commons License




Trackback 0 And Comment 0

[디자인 패턴#8] 어댑터와 퍼사드 패턴

|


Adapter & Facade Pattern - 디자인 패턴

참고서적 : Head First Design Pattern
소스코드 다운로드 : http://www.wickedlysmart.com/headfirstdesignpatterns/code.html
 
패턴 정의 #8 - 어댑터(Adapter) Pattern
한 클래스의 인터페이스를 클라이언트에서 사용하고자 하는 다른 인터페이스로 변환합니다.
어댑터를 이용하면 인터페이스 호환성 문제 때문에 같이 쓸 수 없는 클래스들을 연결해서 쓸 수 있습니다.  
 
흔히 11자형 플러그와 돼지코 플러그의 상호 어댑터를 연상하면 쉬울 겁니다.
간단히 클래스 다이어그램을 살펴보시기 바랍니다.
 


 
- 클라이언트에서는 타겟 인터페이스만 볼 수 있습니다.
- 어댑터에서 타겟 인터페이스를 구현합니다.
- 어댑터는 어댑티로 구성되어 있습니다.
- 모든 요청은 어댑티에 위임됩니다.
 
개념은 간단하죠.. Target 인터페이스를 구현한 Adapter에서 Adaptee를 호출하는 형식입니다.
클라이언트가 사용하는 Target 인터페이스에 맞추어서 Adaptee 클래스를 Adapter로 변경해 호출하는 겁니다.
 
말이 꼬이는 듯 하지만 자세히 보면 이해가 될 겁니다.
 
다중 상속이 가능하다면 다음 그림과 같이 Target과 Adaptee를 모두 상속받도록 구현할 수도있습니다.
위의 그림은 객체 구성(composition)을 이용한 객체 어댑터이구..
아래 그림은 다중 상속을 이용한 클래스 어댑터라고 합니다.
 


 

패턴 정의 #9 - 퍼사드(Facade) Pattern
어떤 서브시스템의 일련의 인터페이스에 대한 통합된 인터페이스를 제공합니다.
퍼사드에서 고수준 인터페이스를 정의하기 때문에 서브시스템을 더 쉽게 사용할 수 있습니다.
 
퍼사드 패턴은 단순화된 인터페이스를 통해서 서브시스템을 더 쉽게 사용할 수 있도록 하기 위한 용도로 쓰인다는 점입니다.
패턴의 클래스 다이어그램을 보면 더욱 쉽게 이해할 수 있을 것입니다.
 
디자인 원칙
1. 최소 지식 원칙 - 정말 친한 친구하고만 애기하라.
 
예제 클래스다이어그램으로 HomeTheater를 퍼사드 패턴으로 구현한 것입니다.
 
복잡한 HomeTheater 기능을 직접 이용하지 않고 HomeTheaterFacade 클래스를 통해 이용하는 것입니다.
 

 
- 클라이언트에게는 친구가 HomeTheaterFacade 하나 뿐입니다.
객체지향 프로그래밍에서는 친구가 하나만 있는 것이 좋습니다.
- HomeTheaterFacade에서 클라이언트 대신 모든 서브시스템 구성요소를 관리해 줍니다.
덕분에 클라이언트는 단순하면서도 유연해질 수 있습니다.
- HomeTheater 구성요소를 업그레이드 해도 클라이언트에는 아무 영향이 없습니다.
- 서비시스템에서도 최소 지식 원칙을 최대한 지키는 것이 좋습니다.
서로 얽혀 있는 친구들이 너무 많아져서 시스템이 너무 복잡한 것 같으면 퍼사드를 추가하는 것도 생각해 보는 것이 좋습니다.

 
다음 사항은 설계할 때 참고하시기 바랍니다.
 
데코레이터 패턴 - 인터페이스는 바꾸지 않고 책임(기능)만 추가
어댑터 패턴 - 한 인터페이스를 다른 인터페이스로 변환
퍼사드 패턴 - 인터페이스를 간단하게 바꿈
 
이상입니다~~ 좋은 하루되세요!! from 미니
 
크리에이티브 커먼즈 라이선스
Creative Commons License




Trackback 0 And Comment 0

[디자인 패턴#7] 커맨드 패턴

|


Command Pattern - 디자인 패턴

참고서적 : Head First Design Pattern
소스코드 다운로드 : http://www.wickedlysmart.com/headfirstdesignpatterns/code.html
 
패턴 정의 #7 - Command Pattern

커맨드 패턴을 이용하면 요구 사항을 객체로 캡슐화 할 수 있으며,
매개변수를 써서 여러 가지 다른 요구 사항을 집어넣을 수도 있습니다.
또한 요청 내용을 큐에 저장하거나 로그로 기록할 수도 있으며,
작업취소 기능도 지원 가능합니다.
 
커맨드 패턴은 그 원리를 이해하면 그리 어렵지 않게 접근할 수 있습니다.
Command 객체에서는 execute() 메소드만 공개해 두고..
execute() 메소드에서는 각 Receiver 객체의 action()을 수행하도록 구성되어 있는 것입니다.
 
다음 클래스 다이어그램을 살펴보시기 바랍니다.
 

 

- 클라이언트는 ConcreteCommand를 생성하고 Receiver를 설정합니다.
- 인보커에는 명령이 들어 있으며, execute() 메소드를 호출함으로써 커맨드 객체에게 특정 작업을 수행해 달라는 요구를 하게 됩니다.
- Command는 모든 커맨드 객체에서 구현해야 하는 인터페이스입니다.
모든 명령은 execute() 메소드 호출을 통해 수행되며, 이 메소드에서는 리시버에 특정 작업을 처리하라는 지시를 전달합니다.
이 인터페이스를 보면 execute()한 내용르 모두 취소하는 undo() 메소드도 들어있습니다.
- ConcreteCommand는 특정 행동과 리시버 사이를 연결해 줍니다.
인보커에서 execute() 호출을 통해 요청을 하면 ConcreteCommand 객체에서 리시버에 있는 메소드를 호출함으로써 그 작업을 처리합니다.
- 리시버는 요구사항을 수행하기 위해 어떤 일을 처리해야 할는지 알고 있는 객체입니다.
 
클라이언트에서는 Invoker를 통해서 각 Command의 execute()를 실행할 수 있습니다.
Invoker의 setCommand를 통해서 여러 Command 객체를 설정하구요..
Command 객체를 생성할 때.. Receiver 객체를 전달하는 겁니다.
 
즉, 클라이언트에서의 프로그래밍 순서를 보면 다음과 같다고 할 수 있습니다.
 
1. Invoker 객체 생성
2. Receiver 객체 생성
3. ConcreteCommand 객체 생성 (Receiver 객체 전달)
4. Invoker 객체의 setCommand 실행 (ConcreteCommand 객체 전달)
5. Invoker 객체 메소드 실행 (Command 객체의 execute() 실행)


 
크리에이티브 커먼즈 라이선스
Creative Commons License




Trackback 0 And Comment 0

[디자인 패턴#6] 싱글턴 패턴

|


Singleton Pattern - 디자인 패턴

참고서적 :  Head First Design Pattern
소스코드 다운로드 : http://www.wickedlysmart.com/headfirstdesignpatterns/code.html
 
패턴 정의 #6 - Singleton Pattern
싱글턴 패턴 (Singleton Pattern)은 해당 클래스의 인스턴스가 하나만 만들어지고,
어디서든지 인스턴스에 접근할 수 있도록 하기 위한 패턴입니다.  
 
가장 널리 사용하는 디자인 패턴이 아닌가 합니다.
굳이 디자인 패턴을 모르더라도 자바 프로그래밍에서 자주 사용하기도 하죠~~  
 
싱글턴 패턴은 클래스에서 자신의 단 하나뿐인 인스턴스를 관리하도록 만들면 됩니다.
그리고 다른 어떤 클래스에서도 자신의 인스턴스를 추가로 만들지 못하도록 해야 합니다.
인스턴스가 필요하면 반드시 클래스 자신을 거치도록 해야 되겠죠..
 

 
- uniqueInstance 클래스 변수에 싱글턴의 유일무이한 인스턴스가 저장됩니다.
- getInstance() 메소드는 정적 메소드, 즉 클래스 메소드입니다.
그냥 Singleton.getInstance() 라는 코드만 사용하면 언제 어디서든 이 메소드를 호출할 수 있습니다.
전역 변수에 접근하는 것만큼이나 쉬우면서도 게으른 인스턴스 생성을 활용할 수 있다는 장점을 제공합니다.
- 싱글턴 패턴을 구현한다고 해서 여기 있는 Singleton 클래스처럼 간단해야 하는 것은 아닙니다.
그냥 일반적인 클래스를 만들 때와 마찬가지로 다양한 데이터와 메소드를 사용할 수 있습니다.
 

싱글턴 패턴을 사용할 경우, 한가지 고려해야 할 사항이 바로 멀티스레딩 관련 문제입니다.
두 개의 쓰레드가 동시에 생성할 경우, 인스턴스가 두 개 생길 수도 있다는 것이죠..
 
그래서 이에 대한 해결책으로 다음과 같은 세가지 방법을 사용합니다.
참고하시기 바랍니다.
 
1. synchronized 키워드를 사용한다.
 
synchronized로 동기화 하게 되면 비용 측면에서의 문제가 발생할 수 있으므로
getInstance()의 속도가 그리 중요하지 않을 경우, 사용해야 한다고 합니다.



2. 인스턴스를 필요할 때 생성하지 말고, 처음부터 만들어 버린다.
 
실행중에 만들지 않고 처음부터 Singleton 인스턴스를 만드는 방법입니다.
 
클래스가 로딩 될 때, JVM에서 Singleton의 유일한 인스턴스를 생성한다고 합니다.
그러므로 JVM에서 유일한 인스턴스를 생성하기 전에는 어떤 쓰레드도 uniqueInstance 변수에 접근할 수 없습니다.
 



3. DCL(Double Checking Locking)을 써서 getInstance()에서 동기화 되는 부분에 대한 체크를 줄입니다.
 
DCL은 Java 5 이전 버전에는 사용할 수 없습니다. 즉, 1.4 버전에서는 지원이 안된다는 것이죠~
어쨌든 동기화를 체크하는 부분이 처음에만 이루어지므로 성능에 큰 영향을 주지 않게 됩니다.



volatile 키워드를 사용하면 멀티쓰레딩을 쓰더라도 uniqueInstance 변수가 Singleton 인스턴스로 초기화 되는 과정이 올바르게 진행되도록 할 수 있습니다.
 
크리에이티브 커먼즈 라이선스
Creative Commons License




Trackback 0 And Comment 0

[디자인 패턴#5] 추상 팩토리 패턴

|



Abstract Factory Pattern - 디자인 패턴

참고서적 :  Head First Design Pattern
소스코드 다운로드 : http://www.wickedlysmart.com/headfirstdesignpatterns/code.html
 
패턴 정의 #5 - Abstract Factory Pattern

추상 팩토리 패턴에서는 인터페이스를 이용하여 서로 연관된, 또는 의존하는 객체를 구상 클래스를 지정하지 않고도 생성할 수 있습니다.
 
디자인 원칙

1. 추상화된 것에 의존하도록 만들어라. 구상 클래스에 의존하도록 만들지 않도록 한다.
 
추상 팩토리 패턴을 사용하면 클라이언트에서 추상 인터페이스를 통해서 일련의 제품들을 공급받을 수 있습니다.
이때, 실제로 어떤 제품이 생산되는지는 전혀 알 필요도 없습니다.
따라서 클라이언트와 팩토리에서 생산되는 제품을 분리시킬 수 있습니다.
 



- 클라이언트를 만들 때는 추상 팩토리를 바탕으로 만듭니다. 실제 팩토리는 실행시에 결정됩니다.
- AbstractFactory는 모든 구상 팩토리에서 구현해야 하는 인터페이스입니다. 제품을 생산하기 위한 일련의 메소드들이 정의되어 있습니다.
- 구상 팩토리에서는 서로 다른 제품군을 구현합니다.
클라이언트에서 제품이 필요하면 이 팩토리 가운데 적당한 걸 골라서 쓰면 되기 때문에 제품 객체의 인스턴스를 직접 만들 필요가 없죠.
- 각 구상 팩토리에서 필요한 제품들을 모두 만들 수 있습니다.
 
실제 PizzaStore에서 사용된 그림은 다음과 같습니다.
 
여기에서 클라이언트는 NYPizzaStore와 같은 것이 되겠죠...
그리고 NYPizzaStore의 팩토리 메소드로 사용된 createPizza() 함수 내에 재료를 나타내는 PizzaIngredientFactory에 대한 인스턴스를 포함하고 있게 됩니다.

 

크리에이티브 커먼즈 라이선스
Creative Commons License




Trackback 0 And Comment 0

[디자인 패턴#4] 팩토리 메소드 패턴

|



Factory Method Pattern - 디자인 패턴

 
참고서적 : Head First Design Pattern
소스코드 다운로드 : http://www.wickedlysmart.com/headfirstdesignpatterns/code.html
 
패턴 정의 #4 - Factory Method Pattern

팩토리 메소드 패턴에서는 객체를 생성하기 위한 인터페이스를 정의하는데,
어떤 클래스의 인스턴스를 만들지는 서브클래스에서 결정하게 만듭니다.
팩토리 메소드 패턴을 이용하면 클래스의 인스턴스를 만드는 일을 서브 클래스에 맡기는 것이죠.
 
Creator 추상 클래스에서 객체를 만들기 위한 메소드, 즉 팩토리 메소드를 위한 인터페이스를 제공하고 있습니다.
Creator 추상 클래스에 구현되어 있는 다른 메소드에서는 팩토리 메소드에 의해 생산된 제품을 가지고 필요한 작업을 처리합니다.
하지만 실제 팩토리 메소드를 구현하고 제품(객체 인스턴스)를 만들어 내는 일은 서브클래스에서만 할 수 있습니다.
 



 
- Creator에는 제품을 가지고 원하는 일을 하기 위한 모든 메소드들이 구현되어 있습니다.
하지만 제품을 만들어 주는 팩토리 메소드는 추상 메소드로 정의되어 있을 뿐 구현되어 있진 않습니다.
- Creator의 모든 서브클래스에 factoryMethod() 추상 메소드를 구현해야 합니다.
- ConcreteCreator에서는 실제로 제품을 생산하는 factoryMethod()를 구현해야 합니다.
- 제품 클래스에서는 모두 똑같은 인터페이스를 구현해야 합니다.
그래야 그 제품을 사용할 클래스에서 구상 클래스가 아닌 인터페이스에 대한 레퍼런스를 써서 객체를 참조할 수 있으니까요.
 
팩토리 메소드 패턴은 실제로 많이 사용하는 형태입니다.
여기에서 중요한 개념은 "서브클래스에서 객체 인스턴스를 생성한다"인 것 같습니다.
 
다음 Pizza 예제에서도 NYPizzaStore나 ChicagoPizzaStore에서 createPizza()라는 팩토리 메소드를 통해 인스턴스를 생성하구요..
실제 주문은 상위 클래스인 PizzaStore의 orderPizza()에서 이루어 지는 것이죠..
 
마지막으로 createPizza()는 어떤 스타일의 Pizza를 만들어야 할 지를 결정하는 구문이 포함되어 있는 겁니다.
즉, 제품 클래스인 Pizza를 실질적으로 생성하는 것입니다.

 

크리에이티브 커먼즈 라이선스
Creative Commons License




Trackback 0 And Comment 0

[디자인 패턴#3] 데코레이터 패턴

|



Decorator Pattern - 디자인 패턴
 
참고서적 : Head First Design Pattern
소스코드 다운로드 : http://www.wickedlysmart.com/headfirstdesignpatterns/code.html
 
패턴 정의 #3 - Decorator Pattern
데코레이터 패턴(Decorator Pattern)에서는 객체에 추가적인 요건을 동적으로 첨가한다. 
데코레이터는 서브클래스를 만드는 것을 통해서 기능을 유연하게 확장할 수 있는 방법을 제공한다. 
 
디자인 원칙
1. 클래스는 확장에 대해서는 열려 있어야 하지만 코드 변경에 대해서는 닫혀 있어야 한다.
 
데코레이터 패턴은 포함관계를 나타냅니다. 
기본 Component를 각 Decorator 클래스가 포함함으로써.. 원하는 결과를 가져올 수 있도록 만들어 놓은 것입니다.
 
소스 파일을 보면 이해할 수 있겠지만, 
예를 들어 커피를 주문하는데.. 모카하고 휘핑 크림을 추가한 다크 로스트 커피를 주문한다면 다음과 같은 식으로 처리됩니다.
 
1. DarkRoast 객체를 가져온다.
2. Mocha 객체로 장식한다.
3. Whip 객체로 장식한다.
4. cost() 메소드를 호출한다. 이때 첨가물의 가격을 계산하는 일은 해당 객체들에게 위임된다. 

 
음.. 일단, 다음 클래스다이어그램을 보시고, 소스를 살펴보시기 바랍니다.~
 

 

- Beverage는 가장 기본이 되는 Component 추상 클래스로 볼 수 있습니다.
- 커피 종류마다 Beverage에 대한 구상 클래스를 하나씩 만듭니다. (HouseBlend, DarkRoast, Expresso, Decaf)
- 각각의 첨가물을 나타내는 데코레이터를 추가합니다. cost() 뿐만 아니라 getDescription() 도 구현해야 합니다. 
- 각 데코레이터 안에는 Beverage 클래스가 들어있습니다. 
즉, 데코레이터에는 구성요소에 대한 레퍼런스가 들어있는 인스턴스 변수가 있지요.
 
그리 어려운 개념은 아닌데, 말이 좀 어렵게 되어 있습니다. 
실제 소스와 위 그림을 잘 보시면 이해가 될 것입니다. 
 
자바에서도 java.io 클래스에 데코레이터 패턴이 적용되어 있습니다.
InputStream의 사용을 잘 생각해 보면 위에서 설명한 포함 관계가 맞죠?


 
크리에이티브 커먼즈 라이선스
Creative Commons License




Trackback 0 And Comment 0
prev | 1 | 2 | next