经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
设计模式之装饰者模式
来源:cnblogs  作者:迷途纸鸢  时间:2019/8/8 8:54:05  对本文有异议

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

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

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

各样的咖啡)。

原本的设计如下:

 

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

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

 

不错,你看到了类爆炸

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

 

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

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

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

来看个例子:

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

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

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

       ③以奶泡(Whip)装饰它

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

   如何工作?

       ①以DarkRoast对象开始

           

 

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

           

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

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

          

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

          

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

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

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

 

  1. 1 public abstract class Beverage {
  2. 2 String description = "Unknown Beverage";
  3. 3
  4. 4 public String getDescription(){
  5. 5 return description;
  6. 6 }
  7. 7
  8. 8 public abstract double cost();
  9. 9 }

 

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

  1. 1 public abstract class CondimentDecorator extends Beverage{
  2. 2 Beverage beverage;
  3. 3
  4. 4 public abstract String getDescription();
  5. 5 }

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

Espresso.java:

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

DarkRoast.java:

  1. 1 public class DarkRoast extends Beverage {
  2. 2 public DarkRoast() {
  3. 3 description = "Dark Roast Coffee";
  4. 4 }
  5. 5
  6. 6 public double cost() {
  7. 7 return .99;
  8. 8 }
  9. 9 }

HouseBlend.java:

  1. 1 public class HouseBlend extends Beverage {
  2. 2 public HouseBlend() {
  3. 3 description = "House Blend Coffee";
  4. 4 }
  5. 5
  6. 6 public double cost() {
  7. 7 return .89;
  8. 8 }
  9. 9 }

 

开始协调料代码:

Mocha.java:

  1. 1 public class Mocha extends CondimentDecorator {
  2. 2 public Mocha(Beverage beverage) {
  3. 3 this.beverage = beverage;
  4. 4 }
  5. 5
  6. 6 public String getDescription() {
  7. 7 return beverage.getDescription() + ", Mocha";
  8. 8 }
  9. 9
  10. 10 public double cost() {
  11. 11 return .20 + beverage.cost();
  12. 12 }
  13. 13 }

Milk.java:

  1. 1 public class Milk extends CondimentDecorator {
  2. 2 public Milk(Beverage beverage) {
  3. 3 this.beverage = beverage;
  4. 4 }
  5. 5
  6. 6 public String getDescription() {
  7. 7 return beverage.getDescription() + ", Milk";
  8. 8 }
  9. 9
  10. 10 public double cost() {
  11. 11 return .10 + beverage.cost();
  12. 12 }
  13. 13 }

Soy.java:

  1. 1 public class Soy extends CondimentDecorator {
  2. 2 public Soy(Beverage beverage) {
  3. 3 this.beverage = beverage;
  4. 4 }
  5. 5
  6. 6 public String getDescription() {
  7. 7 return beverage.getDescription() + ", Soy";
  8. 8 }
  9. 9
  10. 10 public double cost() {
  11. 11 return .15 + beverage.cost();
  12. 12 }
  13. 13 }

Whip.java:

  1. 1 public class Whip extends CondimentDecorator {
  2. 2 public Whip(Beverage beverage) {
  3. 3 this.beverage = beverage;
  4. 4 }
  5. 5
  6. 6 public String getDescription() {
  7. 7 return beverage.getDescription() + ", Whip";
  8. 8 }
  9. 9
  10. 10 public double cost() {
  11. 11 return .10 + beverage.cost();
  12. 12 }
  13. 13 }

测试代码:

Main.java:

  1. 1 public class Main {
  2. 2
  3. 3 public static void main(String[] args) {
  4. 4 Beverage beverage = new Espresso();
  5. 5 System.out.println(beverage.getDescription()
  6. 6 + " $" + beverage.cost());
  7. 7
  8. 8 Beverage beverage2 = new DarkRoast();
  9. 9 beverage2 = new Mocha(beverage2);
  10. 10 beverage2 = new Mocha(beverage2);
  11. 11 beverage2 = new Whip(beverage2);
  12. 12 System.out.println(beverage2.getDescription()
  13. 13 + " $" + beverage2.cost());
  14. 14
  15. 15 Beverage beverage3 = new HouseBlend();
  16. 16 beverage3 = new Soy(beverage3);
  17. 17 beverage3 = new Mocha(beverage3);
  18. 18 beverage3 = new Whip(beverage3);
  19. 19 System.out.println(beverage3.getDescription()
  20. 20 + " $" + beverage3.cost());
  21. 21 }
  22. 22 }

结果:

 

原文链接:http://www.cnblogs.com/Trojan00/p/11316983.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号