设计模式之装饰者模式

来源:互联网 发布:深圳cnc数控编程培训 编辑:程序博客网 时间:2024/06/05 16:13

      在说装饰者模式之前我们需要先了解一个重要的原则,那就是开放--关闭原则,可以这么理解为,开放是在原有的代码上能够拥有很好的扩展性,封闭则原有的代码可以选择不去改变,其实一个目标就是在不修改现有代码的情况下,允许类容易被扩展,搭配新的行为,使得设计的代码更具有弹性,接受更多的多样化的需求。

    通常我们会在设计中最有可能改变的地方使用这个原则,不必要每个地方都要按照这个原则去设计,即便是设计出来也是一种浪费。

      接下来我们结合一个例子来理解装饰者模式:


     假如,我们拥有了一家星巴克咖啡店,哈哈,当然是假如哈,让我们思考一下,一个简单的消费者消费咖啡的过程,这个过程中我们需要标定价格,所以我们可以默认用cost()方法来模拟这个过程;之后我们可以设计一个关于咖啡原料计算价格的基类cost()方法被设计到里面,当然是个抽象类,这样的话可以更好的通过继承来实现对每种饮料价格的计算和对应没种咖啡特色的价格的计算(如继承的子类中有包含了其它的原料,继承父类的cost()同时也可以覆盖改写)。当然这个是我们能够最直接想到的。但反过来想一下,当咖啡的种类增加时,则增加继承的子类,同时增加的种类的计算方式会有不同,则使得原有的基类也需要做出很大的更改,这样的话维护起来非常困难。这里我们采用装饰者模式,这个模式是解决这个问题的一个比较好的方案。

    好比顾客说我需要摩卡和奶泡深烘焙的咖啡,那么我们要做的是:1.拿一个深烘焙咖啡对象。2.以摩卡对象装饰它。3.用奶泡对象装饰它。4.调用cost()方法,并依赖委托(delegete)将调料的价钱加上去。

分析一下:烘焙对象起自己带有一个计算价格的cost()方法,当被摩卡对象装饰的时候,摩卡对象会根据自己的里面带有的cost()方法进行计算,后面的奶泡对象的装饰过程和摩卡一样,最终仅调用最外层的奶泡装饰者对象就可以了。

剖析一下可以发现:

1.装饰者和被装饰的对象有相同的超类,达到类型匹配的目的,而不是利用继承来获得行为。

2.可以用一个或者多个装饰者包装一个对象。

3.因为超类相同,所以在任何需要原始对象的场合,都可以用装饰过的对象代替它。

4.也是重点:装饰者可以在所委托被装饰者的行为之前/之后,加上自己的行为,来达到特性的目的。

5.对象可以在任何时候被装饰,所以可以再运行时动态的,不限量的用自己喜欢的方式来装饰对象。

说了这么多,来个直接的类图来说明下:



用代码实现:

首先定义Beverage类:

public abstract class Beverage{String description = "Unkonwn Beverage";public String getDescription(){return description;}public abstract double const();}
实现其继承类:

public abstract class CondimentDecorator extends Beverage{public abstract String getDescription();}
实现几个组件类,如Espresso类,HouseBlend类:

public class Espresso extends Beverage{public Espresso(){description = "Espresso";}public double cost(){return 1.99;}}
HouseBlend类:

public class HouseBlend extends Beverage{public HostBlend(){description = "House Blend Coffee";}public double cost(){return .89;}}
其次再实现继承自CondimentDecorator类的装饰者,其它的装饰者可参考这个装饰者的构建方法:

public class Mocha extends ConidmentDecorator{Beverage beverage;public Mocha(Beverage beverage){this.beverage = beverage;}public String getDescription(){return beverage.getDescription() + ", Mocha";}public double cost(){return 0.20 + beverage.cost();}}
写一个测试程序,测试程序如下:

public class StarbuzzCoffee{public static void main(String[] args){Beverage beverage = new Espresso();System.out.println(beverage.getDescription()+ "$" + beverage.cost());Beverage beverage2 = new DarkRoast();beverage2 = new Mocha(beverage2);beverage2 = new Mocha(beverage2);beverage2 = new Whip(beverage2);System.out.println(beverage2.getDescription()+ "$" + beverage2.cost());Beverage beverage3 = new HouseBlend();beverage3 = new Soy(beverage3);beverage3 = new Mocha(beverage3);beverage3 = new Whip(beverage3);System.out.println(beverage3.getDescription()+ "$" + beverage3.cost());}}
测试结果如下:



Java.io中对装饰者模式的使用:Java.io中大量的使用了装饰者模式,把API范围所辖之后可以考到类似于下面的组织形式,当然缺点也很明显,常常会造成设计中有大量的小类,数量很多 可能会造成此API 使用起来困难,但是当了解了装饰者模式之后就能够很容易的判别出这个类是如何组织的,以方便包装方式取得想要的行为。




原创粉丝点击