2008-11-07 8 views
13

가정이 클래스는 A이며, 데코레이터 디자인 패턴을 사용하고 싶습니다. 내가 틀렸다면 수정해라.하지만 작동하려면, A 인스턴스에 대한 참조를 담는 데코레이터 클래스, 예를 들어 ADecorator을 만들어야하고, 다른 모든 데코레이터는 이것을 확장하여 기능을 추가 할 것이다.데코레이터 디자인 패턴에 데코레이터가 필요한 이유는 무엇입니까?

A 인스턴스를 사용하는 대신 데코레이터 클래스를 만들어야하는 이유가 무엇인지 모르겠습니까?

답변

25

데코레이터 패턴은 객체에 동적으로 (즉, 런타임에) 기능을 추가하는 데 사용됩니다. 일반적으로 클래스를 작성할 때 객체의 기능이 고정됩니다. 그러나 중요한 점은 객체의 기능이 장식 된 객체에 대한 원래 객체 위임 책임과 동일한 인터페이스를 구현하기 때문에 객체의 클라이언트가 객체의 클라이언트에 투명하게 확장된다는 것입니다.

데코레이터 패턴은 오브젝트에있을 수있는 많은 선택적 기능이있는 시나리오에서 작동합니다. 데코레이터 패턴이 없으면 각 객체 옵션 구성에 대해 다른 클래스를 만들어야합니다. 꽤 유용한 한 가지 예가 헤드 우선 디자인 패턴 book from O'Reilly에 있습니다. StarBucks처럼 들리는 커피 숍 예제를 사용합니다.

따라서 비용과 같은 방법으로 기본적인 커피를 마실 수 있습니다.

public double cost(){ 
    return 3.45; 
} 

그런 다음 고객은 그래서 당신은 이제 비용 방법과 CoffeeCream 클래스 생성 0.35 비용 크림을 추가 할 수 있습니다

public double cost(){ 
    return 3.80; 
} 

그런 다음 고객이 0.5 비용 모카을 할 수 있습니다, 그리고 그들은 모카을 할 수 있습니다 크림 또는 모카 크림없이. 그래서 여러분은 CoffeeMochaCream과 CoffeeMocha 클래스를 만듭니다. 그런 다음 고객이 이중 크림을 원한다면 CoffeeCreamCream 클래스를 만들면됩니다. 결국에는 클래스 폭발이 발생합니다. 사용 된 빈약 한 예를 핑계로 말씀해주십시오. 그것은 조금 늦었고 그것이 사소한 것임을 알고 있지만 그 점을 표현합니다.

대신 당신이 추상적 인 비용 방법으로 아이템 추상 클래스를 만들 수 있습니다

public abstract class Item{ 
    public abstract double cost(); 
} 

그리고 당신은 확장 구체적인 커피 클래스를 만들 수 있습니다 항목 :

public class Coffee extends Item{ 
    public double cost(){ 
     return 3.45; 
    } 
} 

그런 다음 당신은 CoffeeDecorator을 만드는 것이 동일한 인터페이스를 확장하고 Item을 포함합니다.

public abstract class CoffeeDecorator extends Item{ 
    private Item item; 
    ... 
} 

그런 다음 각 옵션에 대한 구체적인 장식을 만들 수 있습니다 데코레이터는 그냥 한이 항목의로 포장되는 개체의 유형을 상관하지 않는 방법

public class Mocha extends CoffeeDecorator{ 

    public double cost(){ 
    return item.cost() + 0.5; 
    } 

} 

공지를? 아이템 오브젝트의 cost()를 사용하고 단순히 자체 비용을 추가합니다.

public class Cream extends CoffeeDecorator{ 

    public double cost(){ 
    return item.cost() + 0.35; 
    } 

} 

는 이제 이러한 몇 가지 클래스와 구성으로 많은 수의 수 : 예를

Item drink = new Cream(new Mocha(new Coffee))); //Mocha with cream 

또는

Item drink = new Cream(new Mocha(new Cream(new Coffee))));//Mocha with double cream 

등등

.

+0

아하, 당신이 Head First Design Patterns를 읽은 것 같군요? – dhiller

+0

위키피디아의 기사보다이 답변을 더 쉽게 이해할 수있었습니다. –

+0

@dhiller 그래. 디자인 패턴은 내가 시도한 첫 번째 것이고 모든 학생들에게 추천하기 시작했습니다. –

5

나는 더 잘 설명 할 수 없다. wikipedia 기사.

+0

거의 snarky 답처럼 들리지만, 나는 가서 Wikipedia 기사를 보았습니다. 그렇습니다. 훌륭합니다. Charade, 당신이 알고 싶었던 모든 것이 바로 누가, 무엇을, 언제, 어디서, 어떻게! –

+0

죄송합니다. snarky가 들리지만 영어는 제 모국어가 아니므로 "사고"와 같은 일이 생길 수 있습니다 :-) – Kasper

2

일부 언어 (예 : Ruby 또는 JavaScript)에서는 A 인스턴스에 새로운 기능을 추가 할 수 있습니다. 귀하의 질문에 자바 태그가 붙어 있으므로 Java에서이 작업을 수행 할 수없는 이유를 묻고 있습니다. 그 이유는 Java가 정적으로 입력되기 때문입니다. A 인스턴스는 클래스 A가 정의하거나 상속하는 메소드 만 가질 수 있습니다. 따라서 런타임에 A 인스턴스에 A가 정의하지 않은 메소드를 제공하려면이 새 메소드를 다른 클래스에 정의해야합니다.

3

처음에 패턴을 처음 시작하는 경우 Head First Design Patterns 책은 으로 경이적인입니다. 개념을 소화하기 쉽도록 만들고, 이해하기 쉽도록 비슷한 패턴을 대조하고 비교합니다.

+0

나는 이것을 두 번째로해야한다. 책은 믿을 수 없다. 사실 위의 커피 예제는 그 책에서 가져온 것이지만이 책은 그 예제를 훨씬 더 많이 사용합니다. –

관련 문제