본문 바로가기
Programming/디자인 패턴

데코레이터 패턴 (Decorator)

by Teshub 2021. 2. 2.

- 정의 -

객체에 추가 요소를 동적으로 더할 수 있다. 데코레이터 패턴을 사용 시 서브클래스를 만드는 경우에 비해 훨씬 유연하게 기능을 확장할 수 있다.

 

예시 코드

예시 구현 코드입니다

public abstract class Beverage {

    String description = "제목없음";

    public String getDescription() {
        return description;
    }
    public abstract double cost();
}


public abstract class CondimentDecorator extends Beverage{
    public abstract String getDescription();
}


public class Espresso extends Beverage{

    public Espresso() {
        description = "에스프레소";
    }

    @Override
    public double cost() {
        return 1.99;
    }
}


public class HouseBlend extends Beverage{

    public HouseBlend() {
        description = "하우스 블렌드 커피";
    }

    @Override
    public double cost() {
        return 0.89;
    }
}


public class Mocha extends CondimentDecorator {

    Beverage beverage;

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

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

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", 모카";
    }
}


public class Soy extends CondimentDecorator {

    Beverage beverage;

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

    @Override
    public double cost() {
        return .15 + beverage.cost();
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", 두유";
    }
}


public class Whip extends CondimentDecorator {

    Beverage beverage;

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

    @Override
    public double cost() {
        return .10 + beverage.cost();
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", 휘핑";
    }
}


 

테스트 코드입니다

public class testCode {

    public static void main(String[] args) {
        //에소프레소
        Beverage beverage = new Espresso();
        System.out.println(beverage.getDescription() + " $" + beverage.cost());

        //에소프레소에 휘핑하고 모카 추가
        Beverage beverage2 = new Espresso();
        beverage2 = new Mocha(beverage2);
        beverage2 = new Whip(beverage2);
        System.out.println(beverage2.getDescription() + " $" + beverage2.cost());

        //하우스블랜드커피에 모카와 두유추가
        Beverage beverage3 = new HouseBlend();
        beverage3 = new Mocha(beverage3);
        beverage3 = new Soy(beverage3);
        System.out.println(beverage3.getDescription() + " $" + beverage3.cost());

    }
}

실행결과입니다

에스프레소 객체에 모카를 더하고 휘핑을 더하는 등객체에 추가요소를 동적으로 더할 수 있습니다

SOLID원칙 중 OCP 확장에는 열려있지만 코드 변경에는 닫혀있어야 한다는 원칙에 부합합니다

 

디자인 패턴 책을 공부하면서 코드만 봐서는 제일 감 안 오는 패턴 중 하나입니다

솔직히 지금도 예시 좀만 바꿔서 무슨 패턴인지 보면 구별 못할 거 같고요;

데코레이터 클래스로 객체를 감싸고 추가 요소가 필요하면 감싼 객체와 함께 데코레이터로 한번 더 감싼다는 개념은 알겠는데 코드로 만들어 보려니 힘드네요 ㅎ,,,

 

다음 포스팅은 팩토리 패턴과 추상 팩토리 패턴입니다 

 

참고서적 : Head First Design Patterns

 

책을 참고하였지만 직접내용을 치고 구현한 것이라 오류나 오탈자가 있을 수 있습니다.

틀린 내용 있을 시 덧글에 적어주시면 참고하여 수정하겠습니다 감사합니다.

 

 

728x90

댓글