欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

设计模式之装饰者模式

程序员文章站 2023-11-25 23:01:46
首先让我们看一下装饰者模式(我爱叫他套娃模式)的概念:动态的将责任附加到对象上, 若要扩展功能,装饰者提供了比继承者更有弹性的集成方案。 什么?没看懂?没关系,最后再来看这个概念,想让让我们来看一个咖啡屋项目(就是点各式 各样的咖啡)。 原本的设计如下: 看似很好的设计,但是别忘了,买咖啡时候我们会 ......

首先让我们看一下装饰者模式(我爱叫他套娃模式)的概念:动态的将责任附加到对象上,

                                            若要扩展功能,装饰者提供了比继承者更有弹性的集成方案。

什么?没看懂?没关系,最后再来看这个概念,想让让我们来看一个咖啡屋项目(就是点各式

各样的咖啡)。

原本的设计如下:

设计模式之装饰者模式

 

看似很好的设计,但是别忘了,买咖啡时候我们会让他们给我们加一系列的调料,例如蒸奶、

摩卡......。所以,在这时咖啡店的设计就变成了,如下:

设计模式之装饰者模式

 

不错,你看到了类爆炸

好啦,现在有对这个系统做出了改进,如下:

设计模式之装饰者模式

 

好啦,现在这个设计相比之前的的确好了许多,但是如果我们要修改配料呢?那么就必须修改

超类,这时候就违反了一条设计原则:类应该对扩展开放,对修改关闭

所以这个时候,装饰者模式单诞生了!!!!!

来看个例子:

   如果顾客现在要一杯摩卡和奶泡深培咖啡。那么,要做的是:

       ①拿一个深培咖啡(darkroast)对象

       ②以摩卡(mocha)对象装饰它

       ③以奶泡(whip)装饰它

       ④调用cost()方法,并依赖委托(delegate)将调料的几千加上去

   如何工作?

       ①以darkroast对象开始

           设计模式之装饰者模式

 

        ②顾客想要摩卡(mocha),所以建立一个mocha对象,并用它将darkroast对象包起来

           设计模式之装饰者模式

       ③顾客也想要奶泡(whip),所以建立一个whip装饰者,并用它将mocha对象包起来。别

          忘了,darkroast继承自beverage,且有一个cost()方法,用来计算饮料价钱

          设计模式之装饰者模式

       ④现在,该是为顾客算钱的时候了。通过调用最外圈的装饰者的cost就可以办到,如下图:

          设计模式之装饰者模式

好了,请记住装饰者和被装饰对象有相同的超类型现在让我们写一些代码,了解他的工作吧:

首先看一下我们现在的设计图:

设计模式之装饰者模式

先从beverage类下手,这不需要改变原始设计。如下图:

 

1 public abstract class beverage {
2     string description = "unknown beverage";
3 
4     public string getdescription(){
5         return description;
6     }
7 
8     public abstract double cost();
9 }

 

beverage很简单。让我们来实现condiment(调料)抽象类,也就是装饰这类吧:

1 public abstract class condimentdecorator extends  beverage{
2     beverage beverage;
3 
4     public abstract string getdescription();
5 }

现在,该是实现一些饮料的时候了!先从浓缩咖啡(espresso)开始:

espresso.java:

1 public class espresso extends beverage {
2     public espresso() {
3     description = "espresso";
4     }
5 
6     public double cost() {
7         return 1.99;
8     }
9 }

darkroast.java:

1 public class darkroast extends beverage {
2     public darkroast() {
3         description = "dark roast coffee";
4     }
5 
6     public double cost() {
7         return .99;
8     }
9 }

houseblend.java:

1 public class houseblend extends beverage {
2     public houseblend() {
3         description = "house blend coffee";
4     }
5 
6     public double cost() {
7         return .89;
8     }
9 }

 

开始协调料代码:

mocha.java:

 1 public class mocha extends condimentdecorator {
 2     public mocha(beverage beverage) {
 3         this.beverage = beverage;
 4     }
 5 
 6     public string getdescription() {
 7         return beverage.getdescription() + ", mocha";
 8     }
 9 
10     public double cost() {
11         return .20 + beverage.cost();
12     }
13 }

milk.java:

 1 public class milk extends condimentdecorator {
 2     public milk(beverage beverage) {
 3         this.beverage = beverage;
 4     }
 5 
 6     public string getdescription() {
 7         return beverage.getdescription() + ", milk";
 8     }
 9 
10     public double cost() {
11         return .10 + beverage.cost();
12     }
13 }

soy.java:

 1 public class soy extends condimentdecorator {
 2     public soy(beverage beverage) {
 3         this.beverage = beverage;
 4     }
 5 
 6     public string getdescription() {
 7         return beverage.getdescription() + ", soy";
 8     }
 9 
10     public double cost() {
11         return .15 + beverage.cost();
12     }
13 }

whip.java:

 1 public class whip extends condimentdecorator {
 2     public whip(beverage beverage) {
 3         this.beverage = beverage;
 4     }
 5 
 6     public string getdescription() {
 7         return beverage.getdescription() + ", whip";
 8     }
 9 
10     public double cost() {
11         return .10 + beverage.cost();
12     }
13 }

测试代码:

main.java:

 1 public class main {
 2 
 3     public static void main(string[] args) {
 4         beverage beverage = new espresso();
 5         system.out.println(beverage.getdescription()
 6                 + " $" + beverage.cost());
 7 
 8         beverage beverage2 = new darkroast();
 9         beverage2 = new mocha(beverage2);
10         beverage2 = new mocha(beverage2);
11         beverage2 = new whip(beverage2);
12         system.out.println(beverage2.getdescription()
13                 + " $" + beverage2.cost());
14 
15         beverage beverage3 = new houseblend();
16         beverage3 = new soy(beverage3);
17         beverage3 = new mocha(beverage3);
18         beverage3 = new whip(beverage3);
19         system.out.println(beverage3.getdescription()
20                 + " $" + beverage3.cost());
21     }
22 }

结果:

设计模式之装饰者模式