【大话设计模式系列】之装饰者模式

来源:互联网 发布:apache配置怎么快 编辑:程序博客网 时间:2024/05/17 06:19

装饰者模式:动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

      利用组合(composition)和委托(delegation)可以在运行时具有继承行为的效果。通过动态的组合对象,可以在新的代码添加新功能,而无须改动现有代码。既然没有改动现有代码,那么引进bug或产生意外的副作用的机会将大幅度减少。

      利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为。然而,如果能都利用组合的做法扩展对象的行为,既可以在运行时动态的进行扩展。



开闭原则:类应该对扩展开放,对修改关闭。代码应该如晚霞中的莲花一样的关闭(免于改变),如晨曦中的莲花一样的开放(能够扩展)。在遵循选择需要扩展的代码部分时要小心。每个地方都要采用开闭原则是一种浪费,也没有必要,通常会引入新的抽象层次,增加代码的复杂度,应该把注意力集中在设计中最有可能改变的地方。










   


//Beverage是一个抽象类,有两个方法getDescription()和cost()public abstract class Beverage{String description="Unknown Beverage";//getDescription()已经在此实现了,但是cost必须在子类中实现。public String getDescription() {return description;}public abstract double cost();}/*首先,必须让CondimentDecorator能够取代Beverage,所以将CondimentDecorator扩展为Beverage类。所有的调料装饰者都必须重新实现getDescription()方法 */public abstract class CondimentDecorator extends Beverage{public abstract String getDescription();}//写饮料的代码://首先,让Espresso(浓缩咖啡)扩展自Beverage类,因为是一种Espresso饮料。public class Espresso extends Beverage{public Espresso(){//为了要设置饮料的描述,我们写了一个构造器。description="Espresso";}public double cost(){return 1.99;}}//写调料代码//Mocha是一个装饰者,扩展自CondimentDecorator,CondimentDecorator扩展自Beveragepublic class Mocha extends CondimentDecorator{Beverage beverage;/*要让Mocha能够引用一个Beverage,做法如下:  1、用一个实例变量记录饮料,也就是被装饰者。  2、想办法让被装饰着(饮料)被记录到实例变量中。如把饮料当做构造器的参数,再由构造器将此饮料记录在实例变量中。*/public Mocha(Beverage beverage){this.beverage=beverage;}//我们希望不只是描述饮料,而是完成的连调料也描述出来。所以,首先利用委托的办法,得到一个叙述,然后在其后面加上附加的叙述。public String getDescription(){return beverage.getDecription()+",Mocha";}//要计算带Mocha的饮料的价钱,首先把调用委托类给被装饰对象,以计算价钱,然后再加上Mocha的价钱,得到最后结果。public double cost(){return .20+beveragr.cost();}}//供应咖啡public class StarbuzzCoffee{public static void main(String args[]){//定一杯Espresso,不需要调料,打印出它的描述与价钱。Beverage beverage=new Espresso();System.out.printIn(beverage.getDescription()+" $"+beverage.cost());//制造出一个DarkRoast对象,用Mocha装饰它,用第二个Mocha装饰它,用Whip装饰它。Beverage beverage2=new DarkRoast();beverage2=new Mocha(beverage2);beverage2=new Mocha(beverage2);beverage2=new Whip(beverage2);System.out.printIn(beverage2.getDescription()+" $"+beverage2.cost());//最后再来一杯调料味豆浆,摩卡,奶泡的HouseBlend咖啡。Beverage beverage3=new HouseBlend();beverage3=new Mocha(beverage3);beverage3=new Mocha(beverage3);beverage3=new Whip(beverage3);System.out.printIn(beverage3.getDescription()+" $"+beverage3.cost());}}


 


原创粉丝点击