Design Patterns

[Design Pattern] 데코레이터 패턴

FreeEnd 2008. 7. 16. 22:45
반응형
* 본 게시물은 HeadFirst Design Patterns을 기준으로 간략한 내용만 정리하였음을 밝힙니다.

1. 데코레이터 패턴

 데코레이터 패턴은 코드 자체를 데코레이션(장식) 하듯이 꾸미며 하위 클래스를 만들어나간다는 뜻에서 데코레이터 패턴이라고 한다.



2. 데코레이터 패턴의 정의

 데코레이터 패턴에서는 객체에 추가적인 요건을 동적으로 추가한다. 데코레이터는 서브클래스를 만드는 것을 통해 기능을 확장하는 방법을 제공한다.

 [예]

{  [ < (물 가격)  + 커피 가격 > +  프림 가격 ] + 설탕 가격 } = 다방 커피 가격



3. 데코레이터 패턴의 예


// Coffee Type------------------------

public abstract class Beverage {
    String description = "untitle";

    public String getDescription(){
        return desciption;
    }

    public avstract double cost();
}


public class Espresso extends Beverage{
    public Espresso(){
      desctiption = "Espresso";
    }

    public double cost(){
         return 1.99;
    }
}

public class HouseBlend extends Beverage{
   public HouseBlend(){
     desctiption = "HouseBlend";
   }

   public double cost(){
        return 1.99;
   }
}

// Option Type ---------------------------------

// public class CondimentDecorator extend Beverage{};

public class OptionName extend CondimentDecorator{
    Beverage beverage;

    public Mocha(Beverage beverage){
        this.beverage = beverage;
    }

    public String getDesctiption(){
        return beverage.getDescription() + ", OptionName";
    }

    public double cost(){
        return .20 + beverage.cost();
    }
}


상단 코드에서 보면 기본적으로 Beverage을 CondimentDecorator이 상속하고 자식 클래스가 자신이 상속받은 부모클래스형을 포함하면서 중복적으로 재귀 포함하는 관계이다. 결국은 포장지를 겹쳐 씌우면서 새로운 cost와 이름을 포장해나가는 형태이다.

cost()함수를 보면서 예를 들면 먼저 생성한 Beverage형의 인스턴스의 이름을 Moca라고 했을때 Moca.cost()가 가격이 된다. 다음 Decorator형의 인스턴스를 생성하고 Beverage형을 Decorator에 멤버 변수로 포함한뒤 다시 cost를 출력해보면 결국은
.20 + Moca.cost()가 된다. 여기서 Decorator를 더 포함하고자 한다면 결국 Decorator도 Beverage를 상속받은 것이기 때문에 Decorator를 생성한뒤 다시 멤버변수로 선언해 집어넣으면 된다. 결국 새로운 Option값이 .30일때 새로 생긴 cost는 .30 + .20 + Moca.cost()의 형태가 되는 것이다.



4. 적용

 이미 존재하는 클래스에 기능을 부가적으로 추가할수 있는 데코레이터를 만들어 보자.

 입력스트림에 기능을 추가한 클래스이다.

 public class LowerCaseInputStream extends FilterInputStream{
     public LowerCaseInputStrem(InputStream in){
          super(in)
     }

     public int read() throw IOException {
          int c = super.read();
           //write here. create Optional act!!!
           //ex)
           //return (c==-1 ? c: character.toLowerCase((char) c)));
      }

     public int read(byte[] b, int offset, int len) throws IOException{
          int result = super.read(b.offset, len);
           //write here. create Optional act!!!
          //ex)
           // for(int i = offset; i<offset+result ; i++){
           //         b[i] = (byte) Character.toLowerCase((char b[i]);
           //  }
                return result;
     }
}


2008. 7. 16. HeadFirst Design Patterns.

반응형