2009. 9. 18. 14:51
Programming/Design Pattern
Beverage
-----------------
description
-----------------
getDescription()
cost()
-----------------
|
|----------------------------
| |
HouseBlend Decaf
----------------- ----------------
cost() cost()
----------------- ----------------
Beverage는 음료를 나타내는 추상클래스이며, 모든 음료는 이 클래스의 서브클래스가 된다.
커피를 주문할때 스팀 우유나 두유, 모카 등을 추가하고, 그 위에 휘핑 크림을 얹기도 한다. 각각을 추가 할 때마다 커피 가격은 증가된다. 이를 위해 추가되는 사항들 마다 각 음료별 추가되는 사항들이 경우에 수에 따라 모두 클래스로 구성해 두었다면 정말 황당한 상황이다. 왜 이렇게 클래스가 많아 질 수 밖에 없는가? 해결 방법은 없는 것일까?
그러면 그냥 인스턴스 변수하고 슈퍼클래스 상속을 써서 추가 사항을 관리하면 안될까?
Beverage
-----------------
description
milk
soy
mocha
whip
-----------------
getDescription()
cost()
hasMilk()
setMilk()
hasSoy()
setSoy()
hasMocha()
setMocha()
hasWhip()
setWhip()
-----------------
|
|----------------------------
| |
HouseBlend Decaf
----------------- ----------------
cost() cost()
----------------- ----------------
이 경우의 문제점은 무엇일까?
- 첨가물 가격 변경시 기존 코드 수정
- 첨가물의 종류가 많아지면 새로운 메소드를 추가해야하고, 슈퍼클래스의 cost()메소드도 고쳐야한다.
- 새로운 음료가 출시될 수도 있다. 그 중에는 특정 첨가물이 들어가면 안되는 경우도 있을 것이다.
- 더블 모카를 주문한다면?
OCP(open-closed principle) : 클래스는 확장에 대해서는 열려 있어야 하지만 코드 변경에 대해서는 닫혀 있어야
한다.
데코레이터 패턴
객체에 추가적인 요건을 동적으로 참가한다.
데코레이터는 서브클래스를 만드는 것을 통해서 기능을 유연하게 확장할 수 있는 방법을 제공한다.
데코레이터에서는 자기가 감싸고 있는 구성요소의 메소드릉 호출한 결과에 새로운 기능을 더함으로써 행동을 확장합니다.
Beverage -----------------
description
-----------------
getDescription()
cost()
-----------------
|
|----------------------------
| |
HouseBlend Decaf CondimentDecorator
----------------- ---------------- ------------------------
cost() cost() getDescription()
----------------- ---------------- ------------------------
| |
---------------------- |
| |
Mlik Mocha
-------------------- --------------------
Beverage beverage Beverage beverage
-------------------- --------------------
cost() cost()
getDescription() getDescription()
-------------------- --------------------
[생각할 점]
1. 자잘한 클래스들이 엄청나가 추가되는 경우가 있을 수 있다.
2. 특정 형식에 의존하는 코드에 데코레이터를 그냥 적용한다면 엉망이 되어 버릴 수 있다.
3. 구성요소를 초기화하는데 필요한 코드가 훨씬 복잡해 진다.
- 이 종 화 (ingenuity.egloos.com) -