装饰者模式

1.动态地将责任附加到对象上,扩展功能,比继承更有弹性。

2.代码

C++

 1 //decorate c++
 2 #include <iostream>
 3 #include <string>
 4 using namespace std;
 5 
 6 //基类 饮料
 7 class Beverage{
 8 public:
 9     Beverage(string s): description(s){}
10     virtual string getDescription(){                 //配料需覆盖,饮料不用
11         return description;
12     }
13     virtual double cost() = 0;
14 private:
15     string description;
16 };
17 
18 //子类 饮料:浓咖啡
19 class Espresso : public Beverage{
20 public:
21     Espresso() : Beverage("Espresso"){}               //不能在子类初始化列表初始化父类成员
22     double cost(){
23         return 1.99;
24     }
25 };
26 
27 //子类 饮料:混合
28 class HouseBlend : public Beverage{
29 public:
30     HouseBlend() : Beverage("House Blend coffee"){}
31     double cost(){
32         return 0.89;
33     }
34 };
35 
36 //配料
37 class CondimentDecorator : public Beverage{
38 public:
39     CondimentDecorator(string s): Beverage(s){}
40 };
41 
42 //配料:摩卡
43 class Mocha : public CondimentDecorator{
44 public:
45     Mocha(Beverage* beverage) : m_pbeverage(beverage),CondimentDecorator("Mocha"){}
46     string getDescription(){
47         return m_pbeverage->getDescription() + ",Mocha";
48     }
49     double cost(){
50         return .20 + m_pbeverage->cost();
51     }
52 private:
53     Beverage* m_pbeverage;
54 };
55 
56 //配料:鲜奶油
57 class Whip : public CondimentDecorator{
58 public:
59     Whip(Beverage* beverage) : m_pbeverage(beverage),CondimentDecorator("Whip"){}
60     string getDescription(){
61         return m_pbeverage->getDescription() + ",Whip";
62     }
63     double cost(){
64         return .30 + m_pbeverage->cost();
65     }
66 private:
67     Beverage* m_pbeverage;
68 };
69 
70 //
71 int main(){
72     //beverage*1
73     Beverage* beverage_1 = new Espresso();
74     cout<<beverage_1->getDescription()<<" $"<<beverage_1->cost()<<endl;
75     
76     //Mocha*2 Whip*1
77     Beverage* beverage_2 = new Espresso();
78     beverage_2 = new Mocha(beverage_2);    
79     beverage_2 = new Mocha(beverage_2);
80     beverage_2 = new Whip(beverage_2);
81     cout<<beverage_2->getDescription()<<" $"<<beverage_2->cost()<<endl;
82 
83     return 0;
84 }

  Java

 1 //decorate java
 2 //base class
 3 abstract class Beverage{
 4     String description = "Unknown Beverage";
 5     public String getDescription(){
 6         return description;
 7     }
 8     public abstract double cost();
 9 }
10 abstract class CondimentDecorator extends Beverage{
11     public abstract String getDescription();
12 }
13 
14 //Espresso
15 class Espresso extends Beverage{
16     public Espresso(){
17         description = "Espresso";
18     }
19     public double cost(){
20         return 1.99;
21     }
22 }
23 
24 //HouseBlend
25 class HouseBlend extends Beverage{
26     public HouseBlend(){
27         description = "House Blend coffee";
28     }
29     public double cost(){
30         return 0.89;
31     }
32 }
33 //Mocha
34 class Mocha extends CondimentDecorator{
35     Beverage beverage;
36     public Mocha(Beverage beverage){
37         this.beverage = beverage;
38     }
39     public String getDescription(){
40         return beverage.getDescription() + ",Mocha";
41     }
42     public double cost(){
43         return .20 + beverage.cost();
44     }
45 }
46 
47 //Whip
48 class Whip extends CondimentDecorator{
49     Beverage beverage;
50     public Whip(Beverage beverage){
51         this.beverage = beverage;
52     }
53     public String getDescription(){
54         return beverage.getDescription() + ",Whip";
55     }
56     public double cost(){
57         return .30 + beverage.cost();
58     }
59 }
60 //main
61 public class StarbuzzCoffee{
62     public static void main(String[] args){
63         //a beverage
64         Beverage beverage = new Espresso();
65         System.out.println(beverage.getDescription() + " $" + beverage.cost());
66         
67         //Mocha*2 Whip*1
68         Beverage beverage2 = new Espresso();
69         beverage2 = new Mocha(beverage2);
70         beverage2 = new Mocha(beverage2);
71         beverage2 = new Whip(beverage2);
72         System.out.println(beverage2.getDescription() + " $" + beverage2.cost());
73     }
74 }

  3. 杂记:

(1)利用继承设计子类的行为是在编译时静态决定的

         利用组合扩展对象的行为,动态的

         组合维护,添加新功能,无须更改已存在代码,bug引入风险低

(2)类应该对扩展开放,对修改关闭

        每个部分都遵守:没必要,增加复杂度;通常集中在最有可能改变的地方

(3)应对继承滥用设计

(4)装饰和被装饰者 有相同基类,利用继承达到类型匹配,而不是利用继承获得 行为

posted @ 2020-04-07 17:08  三岁玩童  阅读(164)  评论(0编辑  收藏  举报