ToB企服应用市场:ToB评测及商务社交产业平台

标题: 装饰者模式 [打印本页]

作者: 千千梦丶琪    时间: 2023-9-20 10:19
标题: 装饰者模式
装饰者模式

咖啡案例引入

方案1类图


方案1类图分析

方案2类图


类图分析

方案1会出现,咖啡单品 + 调料组合会造成类的倍增,因此可以做改进,将调料内置在Drink中,这样就不会出现类爆炸,提高项目的可维护性。说明milk,soy,chocolate可以设计为Boolean,表示是否要添加相应的调料。
基本介绍

装饰者原理举例

装饰者模式实现案例类图


说明,类图中的Decorator应该是继承Drink,然后在Decorator中组合一个 Drink drink属性;
  1. //饮品
  2. public abstract class Drink {
  3.     private String des;
  4.     private float price;
  5.     public String getDes() {
  6.         return des;
  7.     }
  8.     public void setDes(String des) {
  9.         this.des = des;
  10.     }
  11.     public float getPrice() {
  12.         return price;
  13.     }
  14.     public void setPrice(float price) {
  15.         this.price = price;
  16.     }
  17.     public abstract float cost();
  18. }
  19. //咖啡父类
  20. public class Coffee extends Drink {
  21.     @Override
  22.     public float cost() {
  23.         return super.getPrice();
  24.     }
  25. }
  26. public class Decaf extends Coffee{
  27.     public Decaf(){
  28.         setDes(" 无因咖啡 ");
  29.         setPrice(3.0f);
  30.     }
  31. }
  32. public class Espresso extends Coffee{
  33.     public Espresso(){
  34.         setDes(" 意大利咖啡 ");
  35.         setPrice(6.0f);
  36.     }
  37. }
  38. public class LongBlack extends Coffee{
  39.     public LongBlack(){
  40.         setDes(" 美式咖啡 ");
  41.         setPrice(5.0f);
  42.     }
  43. }
  44. public class ShortBlack extends Coffee{
  45.     public ShortBlack(){
  46.         setDes(" 黑咖啡 ");
  47.         setPrice(5.0f);
  48.     }
  49. }
  50. /**
  51. * @author 长名06
  52. * @version 1.0
  53. * 修饰者 是调料的父类
  54. */
  55. public class Decorator extends Drink{
  56.     private Drink drink;//组合一个drink
  57.     public Decorator(Drink drink){
  58.         this.drink = drink;
  59.     }
  60.     @Override
  61.     public float cost() {
  62.         //super.getPrice()代表小料的价格 drink.cost()代表饮料的价格
  63.         return super.getPrice() + drink.cost();
  64.     }
  65.     @Override
  66.     public String getDes() {
  67.         //重写描述方法
  68.         return super.getDes() + getPrice() + " && " + drink.getDes();
  69.     }
  70. }
  71. public class Milk extends Decorator{
  72.     public Milk(Drink drink){
  73.         super(drink);
  74.         setDes(" 牛奶 ");
  75.         setPrice(2.0f);
  76.     }
  77. }
  78. public class Soy extends Decorator{
  79.     public Soy(Drink drink){
  80.         super(drink);
  81.         setDes(" 豆浆 ");
  82.         setPrice(3.0f);
  83.     }
  84. }
  85. public class Chocolate extends Decorator{
  86.     public Chocolate(Drink drink){
  87.         super(drink);
  88.         setDes(" 巧克力 ");
  89.         setPrice(3.0f);
  90.     }
  91. }
  92. //测试
  93. public class Client {
  94.     public static void main(String[] args) {
  95.         //下订单,买2份巧克力 + 1份牛奶的LongBlack咖啡
  96.         //1.买一份LongBlack咖啡
  97.         //咖啡要用Drink接收,不能使用自己的咖啡类型
  98.         //因为被小料修饰过的咖啡的类型是对应的小料类型
  99.         //如果用自己的咖啡类型,就不能完成 修饰过的咖啡 赋给原有的咖啡了
  100.         Drink longBlack = new LongBlack();
  101.         System.out.println("LongBlack咖啡价格 " + longBlack.cost());
  102.         System.out.println("LongBlack咖啡描述 " + longBlack.getDes());
  103.         //2.给LongBlack咖啡,加一个牛奶小料
  104.         longBlack = new Milk(longBlack);
  105.         System.out.println("加一个牛奶小料的LongBlack咖啡价格 " + longBlack.cost());
  106.         System.out.println("加一个牛奶小料的LongBlack咖啡描述 " + longBlack.getDes());
  107.         //3.给LongBlack咖啡,加一个巧克力小料
  108.         longBlack = new Chocolate(longBlack);
  109.         System.out.println("加一个牛奶小料 加一个巧克力小料的LongBlack咖啡价格 " + longBlack.cost());
  110.         System.out.println("加一个牛奶小料 加一个巧克力小料的LongBlack咖啡描述 " + longBlack.getDes());
  111.         //4.给LongBlack咖啡,加两个巧克力小料
  112.         longBlack = new Chocolate(longBlack);
  113.         System.out.println("加一个牛奶小料 加两个巧克力小料的LongBlack咖啡价格 " + longBlack.cost());
  114.         System.out.println("加一个牛奶小料 加两个巧克力小料的LongBlack咖啡描述 " + longBlack.getDes());
  115.         System.out.println("==============");
  116.         Drink decaf = new Decaf();
  117.         System.out.println(decaf.cost());
  118.         System.out.println(decaf.getDes());
  119.         decaf = new Soy(decaf);
  120.         System.out.println("加一个豆浆小料的LongBlack咖啡价格 " + decaf.cost());
  121.         System.out.println("加一个豆浆小料的LongBlack咖啡描述 " + decaf.getDes());
  122.     }
  123. }
复制代码
装饰者模式在JDK应用分析

  1. import java.io.DataInputStream;
  2. import java.io.FileInputStream;
  3. /**
  4. * @author 长名06
  5. * @version 1.0
  6. */
  7. public class AnalysisDecoratorIO {
  8.     public static void main(String[] args) throws Exception{
  9.         //JDK源码中就使用到了装饰者模式
  10.         //1.InputStream是抽象类,类似我们前面讲的Drink
  11.         //2.FileInputStream是InputStream子类,类似我们前面的 DeCaf, LongBlack
  12.         //3. FilterInputStream是InputStream子类:类似我们前面的Decorator修饰者
  13.         //4. DataInputStream是 FilterInputStream子类,具体的修饰者,类似前面的Milk, Soy 等
  14.         // 5.FilterInputStream类有 protected volatile InputStream in属性 ;即含被装饰者
  15.         //6.分析得出在jdk 的io体系中,就是使用的装饰者模式
  16.         DataInputStream dis = new DataInputStream(new FileInputStream("d:\\abc.txt"));
  17.     }
  18. }
复制代码
只是为了记录自己的学习历程,且本人水平有限,不对之处,请指正。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4