[디자인패턴] 데코레이터 패턴 (Decorator Pattern)

데코레이터 패턴이란

스티커 사진을 만들어주는 프로그램을 설계해야한다고 하자. 스티커 사진의 뼈대는 기본 사진으로 시작한다. 사진은 다양한 프레임, 스티커등을 이용해서 꾸밀 수 있다. 이러한 프로그램은 어떻게 설계해야할까?

위와 같은 경우 데코레이터 패턴을 이용하기에 적절하다. 데코레이터 패턴은 기본 틀에 새롭게 추가될 수 잇는 정보들을 따로 분리하면서, 확장하기 용이하도록 융통성을 제공한다.

데코레이터 패턴은 기본 기능에 추가 기능을 구현하는 경우, 각 기능을 클래스로 정의해 조합하여 이용할 수 있도록 한다.

데코레이터 패턴 UML과 특징

component는 부모 class로 구성 요소들을 의미하는 클래스이다. 추상 클래스로 operation을 하위 클래스가 재정의하도록한다.
ConcreteComponent가 기본이 되는 클래스이다. 주된 기능, 기본이 되는 기능을 주로 작성하게 된다.
Decorator은 부수적인 기능, 장식이 되는 기능을 추가하한다. ConcreteDecoratorComponent클래스는 이 Decorator을 상속 받아 구현한다. Decorator은 component라는 재귀적 연관을 이용하여 주기능과 여러 부수적인 기능들을 재조합 할 수 있게 한다. 상속을 이용한 것이 아닌 aggregation을 이용한다는 점에서 더욱 융통적이다.

  • 위와 같은 설계는 요구의 융통성을 다루는데 용이하다.
  • 객체 체인의 생성 : 데코레이터 패턴은 동적으로 객체의 체인을 생성할 수 있다.
Display photo = new photoStickerDecorator(new PhotoFrameDecorator(new PhotoDisplay())); 

위와 같은 경우, photoStickerDecorator - photoFrameDecorator - PhotoDisplay가 체인과 같이 연결되어 호출되는 것을 볼 수 있다.

  • 객체 체인의 인스턴스화
  • 팩토리 객체 : 데코레이터를 펙토리로 생성하게끔 작성하는 방법도 있다.
  • Testing을 하는 경우에 데코레이터 패턴을 이용하기도 한다. 데코레이터 패턴은 기본 양식에 데코레이터로 wrapping 되어있는 형태이다. 이는 기본 양식을 control하기에 쉬운 형태라고 여겨지기 때문에 그런 것 같다.

데코레이터 패턴 예시

이제 차를 꾸미는 프로그램을 작성하려고 하는 경우를 생각해보자.
기본적으로 Car 클래스를 abstract로 가지고, Car을 꾸밀 수 있는 형태로는 Luxury,Sports로 2가지 종류가 있다고 하자.

먼저 Component에 해당하는 Car 인터페이스를 작성했다.

public interface Car{
	void draw();
} 

다음으로, 가장 기본이 되는 concreteComponent인 BasicCar을 작성했다.

public class BasicCar implements Car{
	void draw(){
		System.out.println("Basic Car"); 
    }
}

이제 꾸며주는 LuxuryCar과 SportsCar의 부모인 CarDecorator을 작성하자. 이는 Car의 자식 클래스이다.

public class CarDecorator implements Car{
	protected Car c; 
	public CarDecorator(Car c){
    	this.c = c; 
    }
	void draw(){
    	this.c.draw(); 
    }
}

다음은 decorator의 자식들인 LuxuryCar과 SportsCar을 설계해주었다.

public class LuxuryCar extends CarDecorator{
	public LuxuryCar(Car c){ 
    	super(c); 
    } 
    public draw(){ 
    	super.draw();
        System.out.println("Luxury Car"); 
     }
}

public class SportsCar extends CarDecorator {
	public SportsCar(Car c) {
		super(c);
	}
	public void assemble() {
		super.assemble();
		System.out.print("Sports Car.");
	}

}

좋은 웹페이지 즐겨찾기