经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
结构型模式————装饰器模式(3.1)
来源:cnblogs  作者:noneplus  时间:2019/8/15 12:15:02  对本文有异议

什么是装饰器模式?


【先吃三颗栗子:】


1.PC=主机+显示器+键盘+鼠标+鼠标垫

主机是核心,而其他的组成部分都是装饰。


2.手抓饼=+鸡蛋+培根+黄瓜

饼是核心,鸡蛋,培根是可选的,可以理解为装饰。


3.咖啡=咖啡+牛奶+冰+方糖

咖啡是核心,牛奶等可选。


比喻虽然形象生动,但是与实际或多或少会产生偏差。


抽象的解释:装饰器模式的目的——核心部分和装饰部分可以自由组合。

装饰器模式的功能

对于软件开发来说,聚焦于软件的灵活性和可扩展性。

装饰器模式要求:

  • 装饰可选
  • 装饰可扩展
  • 核心部分可扩展

手抓饼中的装饰器模式

实现饼加各种配料的价格计算。

思路:

1.定义抽象类手抓饼,其中包含获取种类的抽象方法和获取价格的抽象方法。

2.然后定义两个分别为大份手抓饼和中份手抓饼来继承这个抽象类,重写两个方法定义种类和价格。

3.定义具体的配料类继承手抓饼抽象类,先定义构造器传入已经创建的手抓饼种类,然后重写种类和价格方法。


在网上看的一些博客,是创建出一个抽象的配料类来继承抽象产品类,然后用具体的配料类来实现抽象配料类,实现装饰。

可是如果直接将抽象产品类的方法全部定义抽象方法,配料类直接继承重写,实现装饰,功能上也是可以实现的,如下所示,Bacon类直接继承HandPancake,然后重写getName和getCost方法,实现装饰。似乎也没有问题:

但是设计模式毕竟是一种经验总结,如果有已经看出端倪的小伙伴们在下方留言交流一下吧!

直接继承HandPancake

  1. abstract class HandPancake
  2. {
  3. public abstract String getName();
  4. public abstract int getCost();
  5. }
  6. class HandPancake_Big extends HandPancake
  7. {
  8. @Override
  9. public String getName() {
  10. return "大份手抓饼";
  11. }
  12. @Override
  13. public int getCost() {
  14. return 10;
  15. }
  16. }
  17. class HandPancake_Mid extends HandPancake
  18. {
  19. @Override
  20. public String getName() {
  21. return "中份手抓饼";
  22. }
  23. @Override
  24. public int getCost() {
  25. return 8;
  26. }
  27. }
  28. class Bacon extends HandPancake
  29. {
  30. private HandPancake handPancake;
  31. Bacon(HandPancake handPancake)
  32. {
  33. this.handPancake=handPancake;
  34. }
  35. @Override
  36. public String getName() {
  37. return handPancake.getName()+"加培根";
  38. }
  39. @Override
  40. public int getCost() {
  41. return handPancake.getCost()+1;
  42. }
  43. }
  44. class Cucumber extends HandPancake
  45. {
  46. private HandPancake handPancake;
  47. Cucumber(HandPancake handPancake)
  48. {
  49. this.handPancake=handPancake;
  50. }
  51. @Override
  52. public String getName() {
  53. return handPancake.getName()+"加黄瓜";
  54. }
  55. @Override
  56. public int getCost() {
  57. return handPancake.getCost()+2;
  58. }
  59. }
  60. class Ham extends HandPancake
  61. {
  62. private HandPancake handPancake;
  63. Ham(HandPancake handPancake)
  64. {
  65. this.handPancake=handPancake;
  66. }
  67. @Override
  68. public String getName() {
  69. return handPancake.getName()+"加火腿";
  70. }
  71. @Override
  72. public int getCost() {
  73. return handPancake.getCost()+1;
  74. }
  75. }
  76. public class APPlication
  77. {
  78. public static void main(String[] args) {
  79. HandPancake handPancake_big = new HandPancake_Big();
  80. System.out.println("啥也不加"+handPancake_big.getName()+":"+handPancake_big.getCost());
  81. handPancake_big = new Ham(handPancake_big);
  82. System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
  83. handPancake_big = new Cucumber(handPancake_big);
  84. System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
  85. handPancake_big = new Bacon(handPancake_big);
  86. System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
  87. System.out.println("==============================");
  88. HandPancake handPancake_mid = new HandPancake_Mid();
  89. System.out.println("啥也不加"+handPancake_mid.getName()+":"+handPancake_mid.getCost());
  90. handPancake_mid = new Ham(handPancake_mid);
  91. System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
  92. handPancake_mid = new Cucumber(handPancake_mid);
  93. System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
  94. handPancake_mid = new Bacon(handPancake_mid);
  95. System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
  96. }
  97. }

1565696683438

官方做法:

  1. abstract class HandPancake
  2. {
  3. String name; //1
  4. public String getName()
  5. {
  6. return name;
  7. }
  8. public abstract int getCost();
  9. }
  10. class HandPancake_Big extends HandPancake
  11. {
  12. HandPancake_Big() //2.通过构造器赋值
  13. {
  14. name="大份手抓饼";
  15. }
  16. @Override
  17. public int getCost() {
  18. return 10;
  19. }
  20. }
  21. class HandPancake_Mid extends HandPancake
  22. {
  23. HandPancake_Mid() //2.通过构造器赋值
  24. {
  25. name="中份手抓饼";
  26. }
  27. @Override
  28. public int getCost() {
  29. return 8;
  30. }
  31. }
  32. abstract class Condiments extends HandPancake //3.定义抽象接口
  33. {
  34. public abstract String getName();
  35. }
  36. class Bacon extends Condiments //4.继承抽象接口
  37. {
  38. private HandPancake handPancake;
  39. Bacon(HandPancake handPancake)
  40. {
  41. this.handPancake=handPancake;
  42. }
  43. @Override
  44. public String getName() {
  45. return handPancake.getName()+"加培根";
  46. }
  47. @Override
  48. public int getCost() {
  49. return handPancake.getCost()+1;
  50. }
  51. }
  52. class Cucumber extends Condiments
  53. {
  54. private HandPancake handPancake;
  55. Cucumber(HandPancake handPancake)
  56. {
  57. this.handPancake=handPancake;
  58. }
  59. @Override
  60. public String getName() {
  61. return handPancake.getName()+"加黄瓜";
  62. }
  63. @Override
  64. public int getCost() {
  65. return handPancake.getCost()+2;
  66. }
  67. }
  68. class Ham extends Condiments
  69. {
  70. private HandPancake handPancake;
  71. Ham(HandPancake handPancake)
  72. {
  73. this.handPancake=handPancake;
  74. }
  75. @Override
  76. public String getName() {
  77. return handPancake.getName()+"加火腿";
  78. }
  79. @Override
  80. public int getCost() {
  81. return handPancake.getCost()+1;
  82. }
  83. }
  84. public class APPlication
  85. {
  86. public static void main(String[] args) {
  87. HandPancake handPancake_big = new HandPancake_Big();
  88. System.out.println("啥也不加"+handPancake_big.getName()+":"+handPancake_big.getCost());
  89. handPancake_big = new Ham(handPancake_big);
  90. System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
  91. handPancake_big = new Cucumber(handPancake_big);
  92. System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
  93. handPancake_big = new Bacon(handPancake_big);
  94. System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
  95. System.out.println("==============================");
  96. HandPancake handPancake_mid = new HandPancake_Mid();
  97. System.out.println("啥也不加"+handPancake_mid.getName()+":"+handPancake_mid.getCost());
  98. handPancake_mid = new Ham(handPancake_mid);
  99. System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
  100. handPancake_mid = new Cucumber(handPancake_mid);
  101. System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
  102. handPancake_mid = new Bacon(handPancake_mid);
  103. System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
  104. }
  105. }

1565696715504

手抓饼的扩展性

  • 创建手抓饼的种类
  • 创建配料种类

官方的扩展:创建一个小份手抓饼继承Hanpancake,然后创建配料继承Condiments。

贴一下直接继承HandPancake的情况:

class HandPancake_Smalll extends HandPancake
class Egg extends HandPancake

  1. abstract class HandPancake
  2. {
  3. public abstract String getName();
  4. public abstract int getCost();
  5. }
  6. class HandPancake_Big extends HandPancake
  7. {
  8. @Override
  9. public String getName() {
  10. return "大份手抓饼";
  11. }
  12. @Override
  13. public int getCost() {
  14. return 10;
  15. }
  16. }
  17. class HandPancake_Mid extends HandPancake
  18. {
  19. @Override
  20. public String getName() {
  21. return "中份手抓饼";
  22. }
  23. @Override
  24. public int getCost() {
  25. return 8;
  26. }
  27. }
  28. class Bacon extends HandPancake
  29. {
  30. private HandPancake handPancake;
  31. Bacon(HandPancake handPancake)
  32. {
  33. this.handPancake=handPancake;
  34. }
  35. @Override
  36. public String getName() {
  37. return handPancake.getName()+"加培根";
  38. }
  39. @Override
  40. public int getCost() {
  41. return handPancake.getCost()+1;
  42. }
  43. }
  44. class Cucumber extends HandPancake
  45. {
  46. private HandPancake handPancake;
  47. Cucumber(HandPancake handPancake)
  48. {
  49. this.handPancake=handPancake;
  50. }
  51. @Override
  52. public String getName() {
  53. return handPancake.getName()+"加黄瓜";
  54. }
  55. @Override
  56. public int getCost() {
  57. return handPancake.getCost()+2;
  58. }
  59. }
  60. class Ham extends HandPancake
  61. {
  62. private HandPancake handPancake;
  63. Ham(HandPancake handPancake)
  64. {
  65. this.handPancake=handPancake;
  66. }
  67. @Override
  68. public String getName() {
  69. return handPancake.getName()+"加火腿";
  70. }
  71. @Override
  72. public int getCost() {
  73. return handPancake.getCost()+1;
  74. }
  75. }
  76. //========================
  77. class HandPancake_Smalll extends HandPancake
  78. {
  79. @Override
  80. public String getName() {
  81. return "小份手抓饼";
  82. }
  83. @Override
  84. public int getCost() {
  85. return 5;
  86. }
  87. }
  88. class Egg extends HandPancake
  89. {
  90. private HandPancake handPancake;
  91. Egg(HandPancake handPancake)
  92. {
  93. this.handPancake=handPancake;
  94. }
  95. @Override
  96. public String getName() {
  97. return handPancake.getName()+"加鸡蛋";
  98. }
  99. @Override
  100. public int getCost() {
  101. return handPancake.getCost()+1;
  102. }
  103. }
  104. public class APPlication
  105. {
  106. public static void main(String[] args) {
  107. HandPancake handPancake_big = new HandPancake_Big();
  108. System.out.println("啥也不加"+handPancake_big.getName()+":"+handPancake_big.getCost());
  109. handPancake_big = new Ham(handPancake_big);
  110. System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
  111. handPancake_big = new Cucumber(handPancake_big);
  112. System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
  113. handPancake_big = new Bacon(handPancake_big);
  114. System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
  115. System.out.println("==============================");
  116. HandPancake handPancake_mid = new HandPancake_Mid();
  117. System.out.println("啥也不加"+handPancake_mid.getName()+":"+handPancake_mid.getCost());
  118. handPancake_mid = new Ham(handPancake_mid);
  119. System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
  120. handPancake_mid = new Cucumber(handPancake_mid);
  121. System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
  122. handPancake_mid = new Bacon(handPancake_mid);
  123. System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
  124. System.out.println("扩展性测试:");
  125. HandPancake handPancake_small = new HandPancake_Smalll();
  126. System.out.println("啥也不加"+handPancake_small.getName()+":"+handPancake_small.getCost());
  127. handPancake_small = new Egg(handPancake_small);
  128. System.out.println(handPancake_small.getName()+":"+handPancake_small.getCost());
  129. }
  130. }

运行结果:

1565696654138

原文链接:http://www.cnblogs.com/noneplus/p/11348102.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号