设计模式学习(五) -- 装饰者模式 Decorator Pattern
来源:互联网 发布:中国统计局数据库 编辑:程序博客网 时间:2024/06/05 20:25
装饰者模式:动态地将责任附加到对象上。若要扩展功能,装饰者模式提供了比继承更有弹性的替代方案。
继承的缺点:类的数量爆炸、设计死板,以及基类加入的新功能不适用所有子类。
利用继承来设计子类的行为,是在编译时静态地决定的,而且所有子类都会继承到相同的行为。用组合扩展对象的行为,就能在运行时动态地扩展行为。而且使用组合,可以动态地组合对象,写新的代码添加新的功能,而不需要修改原来的代码,减少引进bug的风险。
设计原则:类应该对扩展开放,对修改关闭。
允许类容易扩展,在不修改原来代码的情况下,就可以搭配新的行为。
遵循开放-关闭原则,会引入新的抽象层次,增加代码的复杂度,所以需要把精力集中在设计中最有可能改变的地方来使用这一原则。
- 装饰者和被装饰者有相同的超类型 (利用继承达到类型匹配,而不是为了获取基类行为);
- 可以用一个或者多个装饰者包装一个对象;
- 由于有相同的超类,所以任何需要使用被装饰的对象时,都可以用装饰者的对象代替它;
- 装饰者可以在所委托的被装饰者的行为之前或者之后,加上自己的行为;
- 被装饰的对象,可以在运行时动态不限量的使用任何装饰者来装饰对象。
装饰者模式实例类图:
- 装饰者CondimentDecorator和被装饰者Expresso、HouseBlend、DarkRoast等具有相同的超类型Beverage。
- 可以用一个或者多个CondimentDecorator装饰者(如Milk、Mocha、Soy等)来包装一个被装饰对象(如Expresso、HouseBlend、DarkRoast等的对象)。
例如:
Beverage beverage = new HouseBlend();
beverage = new Mocha(beverage); //用Mocha对象来包装HouseBlend对象 - 装饰者Mocha对象可以在被装饰者HouseBlend对象的cost调用之后加上自己的cost定义的行为(参见代码)
装饰者对象持有超类型Beverage的引用,这样就可以使用超类型的引用来添加自己的行为。 - 被装饰者HouseBlend对象可以在运行时动态不限量使用任何装饰者Milk、Mocha、Soy等对象来装饰自己。
Beverage beverage2 = new HouseBlend(); //HouseBlend对象是被装饰者对象
beverage2 = new Mocha(beverage2); //被Mocha装饰
beverage2 = new Soy(beverage2); //被Soy装饰
beverage2 = new Whip(beverage2); //被Whip装饰
对象被装饰者对象装饰,体现在代码中就是:被装饰者对象 = 装饰者对象;
代码实现:
/** * * @author Yves */public abstract class Beverage { public String description = "Unknown Beverage"; public String getDescription(){ return this.description; } public abstract double cost();}
超类型Beverage
public class DarkRoast extends Beverage { public DarkRoast() { super.description = "DarkRoast"; } @Override public double cost() { return 0.99; }}
被装饰者DarkRoast
public class HouseBlend extends Beverage{ public HouseBlend(){ super.description = "House blend coffee"; } @Override public double cost() { return 0.89; }}
被装饰者HouseBlend
public abstract class CondimentDecorator extends Beverage{ public abstract String getDescription();}
装饰者抽象类CondimentDecorator与被装饰者DarkRoast和被装饰者HouseBlend具有相同的超类型Beverage
public class Mocha extends CondimentDecorator{ Beverage beverage; public Mocha(Beverage beverage){ this.beverage = beverage; } @Override public String getDescription() { return beverage.getDescription() + ", Mocha"; } @Override public double cost() { return beverage.cost() + 0.20; } }
装饰者子类Mocha持有超类型Beverage引用,并利用该引用在cost方法中添加自己的行为beverage.cost() + 0.20;
public class Soy extends CondimentDecorator{ Beverage beverage; public Soy(Beverage beverage){ this.beverage = beverage; } @Override public String getDescription() { return beverage.getDescription() + ", Soy"; } @Override public double cost() { return beverage.cost() + 0.15; } }
装饰者子类Soy持有超类型Beverage引用,并利用该引用在cost方法中添加自己的行为beverage.cost() + 0.15;
public class Whip extends CondimentDecorator{ Beverage beverage; public Whip(Beverage beverage){ this.beverage = beverage; } @Override public String getDescription() { return beverage.getDescription() + ", Whip"; } @Override public double cost() { return beverage.cost() + 0.10; } }
装饰者子类Whip持有超类型Beverage引用,并利用该引用在cost方法中添加自己的行为beverage.cost() + 0.10;
public class StarbuzzCoffee { public static void main(String args[]){ Beverage beverage = new HouseBlend(); System.out.println(beverage.getDescription() + " $" + beverage.cost()); Beverage beverage2 = new DarkRoast(); //DarkRoast is the concrete class which can be decorated. beverage2 = new Mocha(beverage2); //Decorate by Mocha beverage2 = new Whip(beverage2); //Decorate by Whip System.out.println(beverage2.getDescription() + " $" + beverage2.cost()); }}
被装饰者DarkRoast,beverage2.cost() –> 0.99
内圈装饰者Mocha,beverage2.cost() –> 0.20
外圈装饰Whip,beverage2.cost() –> 0.10
最后beverage2.cost()返回结果1.29
run:House blend coffee $0.89DarkRoast, Mocha, Whip $1.29
调用关系图:
首先调用外层装饰者的cost方法,然后依次调用内层装饰者的cost方法,直到调用被装饰者的cost方法;首先被装饰者cost方法返回,然后最内层装饰者cost方法返回,然后依次返回外层装饰者cost方法,直到最外层装饰者cost方法返回。
- 设计模式学习(五) -- 装饰者模式 Decorator Pattern
- 设计模式学习总结:装饰者模式(Decorator Pattern)
- 设计模式学习--装饰者模式(Decorator Pattern)
- 设计模式学习--装饰者模式(Decorator Pattern)
- 设计模式学习笔记--装饰者模式(Decorator Pattern)
- 设计模式学习笔记十五:装饰模式(Decorator Pattern)
- 设计模式-装饰者模式(Decorator Pattern)
- 设计模式-装饰模式(Decorator Pattern)
- 设计模式笔记之装饰者模式(Decorator Pattern)
- 设计模式笔记3:装饰者模式(Decorator Pattern)
- C#设计模式之装饰者模式(Decorator Pattern)
- 设计模式系列(三)装饰者模式(Decorator Pattern)
- Java设计模式-装饰者模式(Decorator Pattern)
- 设计模式总结之Decorator Pattern(装饰者模式)
- Java设计模式:装饰者模式(Decorator Pattern)
- 装饰者设计模式(Decorator Pattern)
- 装饰设计模式(decorator design pattern)
- 设计模式(五):装饰模式(Decorator)
- LeetCode--Merge k Sorted Lists
- 关于No suitable driver found for com.mysql.jdbc.Driver问题的解决办法
- 胸怀大海,敢想敢做
- Android类动态加载技术
- C++中vector的使用
- 设计模式学习(五) -- 装饰者模式 Decorator Pattern
- 糟糕的程序员抵不过一款好工具
- opencv 学习
- 关于 PHP7 你必须知道的五件事
- 局部敏感哈希之KSH
- 微信、陌陌等著名IM软件设计架构详解
- Hive元数据管理《二》
- 新浪微博技术架构分析
- 二维标签在三维里显示 ---------------osg与qt