본문 바로가기

프로그래밍/패턴,설계,자료구조

데코레이터 패턴( Decorator Pattern ) [ Head First Design Pattern 내용중에서 ]


Decorator Pattern : 객체에서 추가적인 요건을 동적으로 첨가한다. 데코레이터는 서브 클래스를 만드는 것을 통해서 기능을 유연하게 확장할 수 있는 방법을 제공한다.

<예제 : 커피전문점 음료( Action Script 3.0 ) > ============================================ 구성요소
//음료 베이스 클래스 선언 ( 추상 구성 요소 )
	public class Beverage
	{
		private var _description : String = "제목없음";
		
		public static var TALL : Number 		= 1;
		public static var GRANDE : Number 	= 2;
		public static var VENTI : Number 		= 3;
		
		public function Beverage()
		{
		}
		
		public function set description(strArg : String ) : void
		{			
			this._description = strArg;
		}
		
		public function getDescription( ) : String
		{			
			return this._description;
		}
		
		public function cost(): Number
		{
			//throw new Error( "must be overriden");
			return 0;
		}
		
		public function setSize(nArgs : Number ) :void
		{
		
		}
		
		public function getSize() :Number
		{
			return 0;				
		}
		
	}
//다크 로스트라는 구상구성요소 작성
	public class DarkRoast extends Beverage
	{
		public function DarkRoast()
		{
			super();
			this.description = "다크 로스트";
		}
		
		override public function cost() : Number
		{		
			return 0.99; 
		}
		
		override public function getSize():Number
		{
			return Beverage.VENTI	
		}
		
	}
	public class Decaf extends Beverage
	{
		public function Decaf()
		{
			super();			
			this.description = "디카페인";			
		}
		
		override public function cost(): Number
		{			
			return 1.05;	
		}
				
		override public function getSize():Number
		{
			return Beverage.TALL;	
		}		
	}
	public class Espresso extends Beverage
	{
		public function Espresso()
		{
			super();
			this.description = "에스프레소";
		}
		
		override public function cost() : Number
		{		
			return 1.99; 
		}		
		
		
		override public function getSize():Number
		{
			return Beverage.GRANDE;	
		}			
		
	public class HouseBlend extends Beverage
	{
		public function HouseBlend()
		{
			super();
			this.description = "하우스 블렌드 커피";
		}
		
		override public function cost() : Number
		{		
			return 0.89; 
		}		
		
		
		override public function getSize():Number
		{
			return Beverage.TALL;	
		}				
		
	}
============================================ 데코레이터 : 첨가 요소 ( 모카 , 휘핑 ...)
	public class CondimentDecorator extends Beverage
	{
		public function CondimentDecorator()
		{
			super();
		}
		
		override public function getDescription( ) : String
		{			
			//throw new Error( "must be overriden");
			return "";
		}
		
	}
	
public class Mocha extends CondimentDecorator
	{
		
		private var _beverage : Beverage;
		
		public function Mocha(  beverage : Beverage )
		{
			_beverage = beverage;
		}
		
		override  public function getDescription( ) : String
		{
			return this._beverage.getDescription()+", 모카"; 	
		}
		
		
		override public function cost() :  Number
		{		
			return 0.20+_beverage.cost();	
		}
		
	}
	public class Soy extends CondimentDecorator
	{
		private var _beverage : Beverage;
		
		public function Soy(  beverage : Beverage )
		{
			_beverage = beverage;
		}
		
		override public function getDescription( ) : String
		{
			return this._beverage.getDescription()+", 두유"; 	
		}
		
		
		override public function cost() :  Number
		{			
			return 0.15 +_beverage.cost();	
		}
		
		
		
	}
	public class SteamMilk extends CondimentDecorator
	{
		var _beverage : Beverage;
		
		public function SteamMilk(  beverage : Beverage )
		{
			_beverage = beverage;
		}
		
		override public function getDescription( ) : String
		{
			return this._beverage.getDescription(); 	
		}
		
		
		override public function cost() :  Number
		{			
			return 0.10 +_beverage.cost();	
		}
	}
	public class Whip extends CondimentDecorator
	{
		private var _beverage : Beverage;
		
		public function Whip(  beverage : Beverage )
		{
			_beverage = beverage;
		}
		
		override public function getDescription( ) : String
		{
			return this._beverage.getDescription()+ ", 휘핑 "; 	
		}
		
		
		override  public function cost() :  Number
		{			
			return 0.10 +_beverage.cost();	
		}
	}
==================================== 실행
	public class DecoratePatternTest extends Sprite
	{
		public function DecoratePatternTest()
		{		
			
			var beverage0 : Beverage = new Espresso();			
			trace( beverage0.getDescription()+" : " + String( Number( beverage0.cost() )  ));
			
			
			var beverage1 : Beverage = new  DarkRoast();
			
			beverage1 = new Mocha( beverage1 );
			beverage1 = new Mocha( beverage1 );
			beverage1 = new Whip( beverage1 );			
			trace( beverage1.getDescription()+" : " + String( Number( beverage1.cost() )  ));
			
			var beverage2 : Beverage = new HouseBlend();
			beverage2 = new Soy( beverage2 );
			beverage2 = new Mocha( beverage2 );
			beverage2 = new Whip( beverage2 );
			trace( beverage2.getDescription()+" : " + String( Number( beverage2.cost() )  ));
			
						
		}		
		
	}