프로그램 아키텍쳐/디자인패턴

데코레이터 패턴 ( Decorator Pattern )

본클라쓰 2009. 1. 4. 17:18

 

 데코레이터 패턴(Decorator Pattern)은 객체에 추가적인 요건을 동적으로 첨가시킬 수 있다데코레이터 패턴은 서브클래스를 만드는 것(상속)을 통해서 기능을 유연하게 확장할 수잇는 방법을 제공한다. 즉, 여러가지 기능을 추가시켜야 할 때 중심이 되는 기능과 부가적인 기능을 나누어 클래스화 시켜 사용하는 방법이다.

 

데코레이터 패턴의 특징

  • 데코레이터의 슈퍼클래스(부가적 기능의 슈퍼클래스)는 자신이 장식하고 있는 객체(중심되는 기능의 클래스)의 슈퍼클래스와 같다.
  • 한 객체를 여러 개의 데코레이터로 감쌀 수 있다.
  • 데코레이터는 자신이 감싸고 있는 객체와 같은 슈퍼클래스를 가지고 있기 대문에 원래 객체가 들어갈 자리에 데코레이테 객체를 집어넣어도 상관 없다.
  • 데코레이터는 자신이 장식하고 있는 객체에게 어떤 행동을 위임하는 것 외에 원하는 추가적인 작업을 수행할 수 있다.
  • 객체는 언제든지 감쌀 수 있기 때문에 실행중에 필요한 데코레이터를 마음대로 적용 할 수 있다.

 데코레이터 패턴은 기본적인 데이터에 첨가할 데이터가 다양하고 일정하지 않을 때 효율적이다. 기본적인 클래스를 따로 분류하고 첨가하는 메소드나 데이터를 따로 분류하여 클래스화 시키는 것이다. 그리고 그 둘을 하나로 묶어주는 슈퍼 클래스로 부터 같이 상속을 받는 것이다. 하지만 데코레이터 패턴을 사용하면 자잘한 객체들이 매우 많이 추가될 수 있고, 데코레이터를 너무 많이 사용하면 코드가 필요 이상으로 복잡해질 수도 있다.




 

코드 예제

[ 슈퍼 클래스 ]

/** 슈퍼클래스(중심적인 객체와 부가적인 객체의 슈퍼 클래스) */
public abstract class Bookstore {


    String Description=" ";  /* 기본 변수 */
 
    public String getDescription(){  /* 이름을 얻는 메소드 */
        return Description;
    }
 
    public abstract double cost();  /* 값을 구성하는 것은 상속받아 정리 */
}

  

[ 중심 클래스(코너를 기준) ] 

/** 기본 클래스 */
public class A_Corner extends Bookstore{
 
    public A_Corner(){
        Description = "A코너";
    }
 

    public double cost(){
        return 0;
    }
}

 

[ 부가적인 객체의 슈퍼 클래스(책을 기준) ] 

/** 첨가 클래스 */
public abstract class Books extends Bookstore{
    public abstract String getDescription(); /* 첨가하는 클래스의 표현값을 따로 얻기 */
}

 

[ 부가적인 객체 클래스 ] 

/** 첨가클래스 */
public class A extends Books{


    Bookstore bookstore;
 
    public A(Bookstore bookstore){
        this.bookstore = bookstore;
    }
 
    public String getDescription(){

        return bookstore.getDescription()+" A책";
    }
  
    public double cost(){
        return bookstore.cost()+1000;
    }
}

 

[ 부가적인 객체 클래스 ] 

/** 첨가클래스 */
public class B extends Books{


    Bookstore bookstore; /* 슈퍼클래스 객체 */

 

    public B(Bookstore bookstore)/* 생성시 기본 클래스를 전달받기 */
        this.bookstore = bookstore;
    } 

 

    public String getDescription() { /* 설명값에 추가*/
        return bookstore.getDescription()+" B책";
    } 

 

    public double cost(){ /* 값을 계속 더해줌 */
        return bookstore.cost()+1500;
    }


}

  

[ 테스트 클래스 ] 

/** 테스트 클래스 */
public class Simulator {

 

    public static void main(String[] args) {


        Bookstore bookstore = new A_Corner(); /* 기본 클래스 생성*/
  
        bookstore = new A(bookstore); /* A객체를 첨가 */

        System.out.println(bookstore.getDescription()+bookstore.cost());


        bookstore = new B(bookstore); /* B객체를 첨가 */
        System.out.println(bookstore.getDescription()+bookstore.cost());
    }
}