不看会后悔的装饰者模式 谁借莪1个温暖的怀抱¢ 2022-01-30 19:29 209阅读 0赞 星巴兹是以扩张速度最快而闻名的咖啡连锁店。因为扩张速度过快,他们准备更新订单系统,以合乎他们的饮料供应要求。他们原先类设计是这样的。。 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70][] 购买咖啡时,要求在其中加入各种调料,例如:蒸奶(steamed milk),豆浆(Soy)、摩卡(Mocha)或者其他。所以它们的订单系统必须考虑到调料部分。 他们尝试一次使用继承解决,如下图: ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 1][] 很明显如果每家一种调料都生成一个新类来继承父类Beverage,将会产生“类爆炸”,维护起来十分困难,如果调料价格上涨,新增调料,都会十分难以管理。 那么再尝试另外一种设计。 在父类Beverage中加上成员变量牛奶(milk)、豆浆(soy)、摩卡(mocha)、奶泡(whip.....) ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 2][] ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 3][] 这样的设计看起立已经比先前好多了。但是因为子类是直接继承父类的通用共享的成员变量和方法。所以扩展性,和代码会存在冗余。 例如:(1)增加新的饮料,比如茶,某些调料可能不适合,但在这个设计方式中,Tea子类仍将继承那些不合适的方法,例如hasWhip()(加奶泡) (2)调料的价钱改变需要改变现有代码 (3)顾客想要双倍摩卡咖啡 **认识装饰这模式** 现在我们知道继承很好的解决我们的问题,上面设计中我们遇到了:类数量爆炸、设计死板、以及基类加入的功能并不适合所有的子类。 所以现在我们采用装饰者模式:我们以饮料为主体,然后运行时以调料来装饰饮料,比方说顾客想要摩卡和奶泡深焙咖啡,要做的是: 1. 拿一个深焙咖啡(DarkRoast)对象 2. 以摩卡(Mocha)对象装饰它 3. 以奶泡(Whip)对象修饰它 4. 调用cost()方法,并依赖委托(delegate)将调料的将钱加上去 # 以装饰者构造饮料订单 # (1)以DarkRoast对象开始 ![20190520101814656.png][] (2)顾客想要摩卡(Mocha),所以建立一个摩卡(Mocha)对象,并用它将DarkRoast对象包装起来。 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 4][] (3)顾客也想要奶泡(Whip),所以要建立一个Whip装饰者,并用它将Mocha对象包起来。 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 5][] (4)现在,是为顾客算钱的时候了。通过调用最外圈装饰者(Whip)的cost()就可以办到。Whip的cost()会委托它的装饰的对象计算出价钱,然后再加上奶泡的价钱。 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 6][] 目前通过上面的信息我们可以知道 * 装饰者和被装饰者有相同的超类型。 * 你可以用一个或者多个装饰者包装一个对象 * 既然装饰者和被装饰对象有相同的类型,所以在任何需要原始对象(被包装的)场合,可以用装饰过的对象代替。 * 装饰者可以在所委托被装饰者的行为之前与/或之后,加上自己的行为,以达到特定的目的。 * 对象可以在任何时候被装饰,所以可以在运行时动态装饰想要装饰的对象。 # 定义装饰者模式 # 装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的方案。 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 7][] 装饰饮料 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 8][] 写饮料的具体代码 Beverage相当于Component类 public abstract class Beverage { String description = "Unknow Beverage"; public String getDescription() { return description; } public abstract double cost(); } DarkRost相当于具体组件 public class DarkRost extends Beverage { public DarkRost() { description = "DarkRost"; } @Override public double cost() { return 100; } } CondimentDecorator抽象装饰者 public abstract class CondimentDecorator extends Beverage{ public abstract String getDescription(); } 具体装饰者Mocha 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 20+ beverage.cost(); } } 具体装饰者Whip 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 30+beverage.cost(); } } 测试 public class Test { public static void main(String[] args) { Beverage beverage = new DarkRost(); System.out.println(beverage.description+" ,cost:"+beverage.cost()); beverage = new Mocha(beverage); System.out.println(beverage.getDescription()+" ,cost:"+beverage.cost()); beverage = new Whip(beverage); System.out.println(beverage.getDescription()+" ,cost:"+beverage.cost()); } } 输出结果:DarkRost ,cost:100.0 DarkRost,Mocha ,cost:120.0 DarkRost,Mocha,whip ,cost:150.0 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70]: /images/20220130/4ff5051f2966465f87a4c4b887a549d0.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 1]: /images/20220130/4e8d888702fc446285b7ec3f2b31603f.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 2]: /images/20220130/21f0976a1c694483802d9a216a5c7795.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 3]: /images/20220130/58a3964a684044ff8e9a2a3226240f46.png [20190520101814656.png]: /images/20220130/42f2121303f04b4798a8f04fefe2e4d8.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 4]: /images/20220130/18592fbb88e141fcb332580c5d4aef2d.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 5]: /images/20220130/48cad38325ba4fcdbc24f439c9473578.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 6]: /images/20220130/458a226764c349b29f4cc6e68ff7484d.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 7]: /images/20220130/17bc5d232afa484fa7b7918e570ce76f.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 8]: /images/20220130/27eee33677a14606b3dc312ded09ad82.png
相关 标签用法,不看会后悔! <table> <tbody> <tr> <td style="min-width:656px"> <div> http-equiv 妖狐艹你老母/ 2022年07月14日 02:13/ 0 赞/ 304 阅读
相关 装饰者模式 package C\_Decker; /\\ \ 设计原则:类应该对扩展开放,对修改关闭。 \ 装饰者模式:动态地将责任和行为附加到对象上。若要扩展功能,装饰者提供了 骑猪看日落/ 2022年07月12日 12:17/ 0 赞/ 209 阅读
相关 装饰者模式 作用:可以给一个对象添加职责,可以用来扩展,比继承更有弹性。 装饰者模式 Decorator模式(别名Wrapper):动态将职责附加到对象上 蔚落/ 2022年05月25日 07:49/ 0 赞/ 186 阅读
相关 装饰者模式 装饰者模式有一个设计非常巧妙的结构,可以为对象动态添加功能。在基本的设计原则中,有一个重要的原则叫做合成/聚合复用原则。根据该原则的思想,代码复用应该尽可能使用委托,而不是继承 红太狼/ 2022年05月14日 02:50/ 0 赞/ 214 阅读
相关 装饰者模式 装饰者模式: 动态的将责任附加到对象上.若要扩展功能,装饰者提供了比继承更加有弹性的代替方案 继承和组合的区别: 继承: 我就是我/ 2022年05月11日 14:12/ 0 赞/ 233 阅读
相关 装饰者模式 TB - top bottom(自上而下) BT - bottom top(自下而上) RL - right left(从右到左) LR - left 亦凉/ 2022年02月18日 11:23/ 0 赞/ 221 阅读
相关 不看会后悔的装饰者模式 星巴兹是以扩张速度最快而闻名的咖啡连锁店。因为扩张速度过快,他们准备更新订单系统,以合乎他们的饮料供应要求。他们原先类设计是这样的。。 ![watermark_type_Zm 谁借莪1个温暖的怀抱¢/ 2022年01月30日 19:29/ 0 赞/ 210 阅读
相关 装饰者模式 装饰者模式,在不改变一个对象本身功能的基础上给对象增加额外的新行为。比如,我们到书店买书,在不改变书籍本身的基础上,赠送个书签,或者要个包装袋 装饰者模式(Decora 谁践踏了优雅/ 2021年12月03日 15:25/ 0 赞/ 358 阅读
相关 装饰者模式 一 点睛 我们先来看一个快餐店的例子。 快餐店有炒面、炒饭这些快餐,可以额外附加鸡蛋、火腿、培根这些配菜,当然加配菜需要额外加钱,每个配菜的价钱通常不太一样,那么计算 悠悠/ 2021年07月24日 19:11/ 0 赞/ 392 阅读
还没有评论,来说两句吧...