设计模式——装饰者模式

咖啡店里咖啡中可以加不同的配料–摩卡、牛奶、糖、奶泡;不同的饮品加上不同的配料有不同的价钱,怎样实现呢?

可能你的第一印象会想到使用继承, 
1. 首先定义一个咖啡基类 
2. 对于加糖的,加牛奶的,加摩卡的 ,加奶泡的,分别写一个子类继承 
3. 对于加糖,又加奶的写一个类,对于对于加糖,又摩卡的写一个类,对于对于加糖、又奶泡的写一个类,对于加糖,又加奶、摩卡的写一个类—- 
说到这里,你会发现这里四种配料就要写十几种实现类了,那如果我们的配料是二十几种或者三十几种呢,那么使用继承这种 方式肯定会使我们的子类爆炸,那要怎样解决你,答案就是使用装饰者模式

装饰者模式是在已有功能的基础之上,动态地添加更多 功能的一种方式,这些新加的代码装饰了原有类的 核心职责或主要行为。

Component:一般是一个抽象类(也有可能不是),是一组有着某种用途类的基类,包含着这些类最基本的特性。

ConcreteComponent:继承自Component,一般是一个有实际用途的类,这个类就是我们以后要装饰的对象。

Decorator:继承自Component,装饰者需要共同实现的接口(也可以是抽象类),用来保证装饰者和被装饰者有共同的超类,并保证每一个装饰者都有一些必须具有的性质,如每一个装饰者都有一个实例变量(instance  variable)用来保存某个Component类型的类的引用。

ConcreteDecorator:继承自Decorator,用来装饰Component类型的类(不能装饰抽象类),为其添加新的特性,可以在委托被装饰者的行为完成之前或之后的任意时候

咖啡抽象类

 1  abstract class Coffee
 2     {
 3         /**
 4         *
 5         * @return 返回价格
 6         */
 7         public abstract int getPrice();
 8 
 9         /**
10          * 返回名字
11          * @return
12          */
13         public abstract String getName();
14     }

调料抽象类

1 abstract class Decorator:Coffee
2     {
3         public abstract String getDescription();  
4     }

生产一杯原味咖啡

 1  class CoffeeA:Coffee
 2     {
 3         public override int getPrice()
 4         {
 5             return 1;
 6         }
 7 
 8         public override string getName()
 9         {
10             return "CoffeeA";
11         }
12     }

生产牛奶配料

 1  class MilkDecorator:Decorator
 2     {
 3         Coffee mCoffee;
 4         /**
 5      * 通过组合的方式把Coffee对象传递进来
 6      *
 7      * @param coffee
 8      */
 9     public MilkDecorator(Coffee coffee) {
10         this.mCoffee = coffee;
11     }
12 
13     public override int getPrice() {
14         return mCoffee.getPrice()+10;
15     }
16 
17     public override String getName()
18     {
19         return mCoffee.getName() + "addMilk";
20     }
21     }

生产抹茶配料

 1  class MochaDecorator:Decorator
 2     {
 3      Coffee mCoffee;
 4         /**
 5      * 通过组合的方式把Coffee对象传递进来
 6      *
 7      * @param coffee
 8      */
 9      public MochaDecorator(Coffee coffee)
10     {
11         this.mCoffee = coffee;
12     }
13 
14      public override int getPrice()
15      {
16         return mCoffee.getPrice()+30;
17     }
18 
19      public override String getName()
20      {
21         return  mCoffee.getName() +"addMocha";
22     }
23     }

由于具体的配料类继承与配料抽象类,而配料抽象类又继承与咖啡类,因此配料类实现时需要实现这两个类中中的所有方法。

接下来我们开始对咖啡装饰

 1 Coffee A = new CoffeeA();
 2 Console.WriteLine("品牌:" + A.getName() + " 价格:" + A.getPrice());
 3 
 4 A = new SoyDecorator(A );
 5 Console.WriteLine("品牌:" + A .getName());
 6 
 7 B = new MochaDecorator(B);
 8 Console.WriteLine("品牌:" + A .getName());
 9 
10  
11 
12 Console.ReadLine();

装饰者模式中用到了继承,但是这里装饰者模式用继承是为了保证装饰者和被装饰者有共同的超类,而不是为了给被装饰的类扩展新的特性,而装饰者模式中新的特性是通过类与类的组合(has-a的关系)而得到的,所以把装饰者模式和继承看做同一类设计思想是不恰当的。

 自我感觉和组合模式太相似。

学习于    https://www.cnblogs.com/coffeeSS/p/5405787.html

猜你喜欢

转载自www.cnblogs.com/cwmizlp/p/9059871.html