装饰者模式

设计原则

  • 类应该对拓展开发,对修改关闭。

  • 针对接口编程,不针对实现编程。

  • 封装变化。

  • 多用组合,少用继承。

  • 为交互对象之间的松耦合设计而努力。

     

     

装饰者模式的定义:

       动态地将责任附加到对象上,若要拓展功能,装饰者提供了比继承更有弹性的替代方案对于设计模式。

总结:

先理解,搞清楚各大设计模式的好处。再在个人/公司项目中使用设计模式,对于安卓开发工程师,接触的设计模式,可能要比后台开发人员多一点。建议不会安卓开发的适当去了解了解安卓开发。如果想深入地了解设计模式的伙计们,建议去买一些相关书籍,书籍里面的解释往往更加生动,更加清楚。本人将自己做的一些代码练习放入了git中,想了解的伙计们,可以去git下载,git地址:https://git.dev.tencent.com/yangxiaojie123/designPattern.git

1.建立一个抽象的被装饰者的超类-水,所有的具体的水与将要加工的果汁都要继承它。

 1 package com.deckerPattern.basicClass;
 2  
 3  /**
 4   * @program: test
 5   * @description: 饮料抽象类,作为最底层的抽象类,所有加工料都必须继承此类
 6   * @author: Mr.Yang
 7   * @create: -- :
 8   **/
 9  public abstract class Water {
10     public String description="水";
11 
12     public String getDescription() {
13         return description;
14     }
15 
16     public void setDescription(String description) {
17         this.description = description;
18     }
19 
20     //得到价格
21     public abstract double getPrice();
22 }
View Code
 

2.建立一个抽象的装饰者超类,继承被装饰者,与被装饰者建立联系,拥有相同的“接口”,再由具体的装饰者类与被装饰者类,组合变成一个行为。

 1  package com.deckerPattern.basicClass;
 2  
 3  /**
 4   * @program: test
 5   * @description: 果汁类,用来装修beverage类,也是个抽象类
 6   * @author: Mr.Yang
 7   * @create: -- :
 8   **/
 9  public abstract class FruitJuice extends Water {
10 
11     public abstract String getDescription();
12 }
View Code
 

3.建立水(被装饰者)的一种具体实现-山泉水,继承被装饰者超类

 1  package com.deckerPattern.expandClass;
 2  
 3  import com.deckerPattern.basicClass.Water;
 4  
 5  /**
 6   * @program: test
 7   * @description: 山泉水,属于水的一种
 8   * @author: Mr.Yang
 9   * @create: -- :
10  **/
11 public class MountainSpringWater extends Water {
12     //属于山泉水的描述
13     private final static String name ="山泉水";
14     //山泉水的对外成本价格
15     private final static double basicPrice=1.2;
16 
17     //山泉水,需要属于自己的描述
18     public MountainSpringWater(){
19         description=name;
20     }
21 
22     public double getPrice() {
23         return basicPrice;
24     }
25 }
View Code
 

4.再建立水(被装饰者)的一种具体实现-井水,继承被装饰者超类

 1  package com.deckerPattern.expandClass;
 2  
 3  import com.deckerPattern.basicClass.Water;
 4  
 5  /**
 6   * @program: test
 7   * @description: 井水,属于水的一种
 8   * @author: Mr.Yang
 9   * @create: -- :
10  **/
11 public class WellWater extends Water {
12     //属于山泉水的描述
13     private final static String name ="井水";
14     //山泉水的对外成本价格
15     private final static double basicPrice=0.8;
16 
17     //山泉水,需要属于自己的描述
18     public WellWater(){
19         description=name;
20     }
21 
22     public double getPrice() {
23         return basicPrice;
24     }
25 }
View Code
 

5.建立一个果汁(装饰者)的具体实现类-苹果汁

 1  package com.deckerPattern.expandClass;
 2  
 3  import com.deckerPattern.basicClass.FruitJuice;
 4  import com.deckerPattern.basicClass.Water;
 5  
 6  import java.math.BigDecimal;
 7  
 8  /**
 9   * @program: test
10  * @description: 苹果汁,果汁的一种,装饰者的实现类,继承果汁抽象类,
11  * @author: Mr.Yang
12  * @create: -- :
13  **/
14 public class AppleJuice extends FruitJuice {
15 
16     //苹果汁的描述
17     private final static String name="苹果汁";
18 
19     //苹果汁的对外成本价
20     private final static double orangePrice=2.2;
21 
22     //让水(被装饰者)记录到变量中
23     Water water;
24 
25     public AppleJuice(Water water){
26         this.water=water;
27     }
28 
29     public String getDescription() {
30         return water.getDescription()+"  "+name;
31     }
32 
33     public double getPrice() {
34         //先得到成本价,使用double,可能会有精度丢失的情况,bigDecimal的构造方法中最好传入,String类型的数字字符串
35         BigDecimal bigDecimal = new BigDecimal(String.valueOf(orangePrice));
36         //成本价,加上水的价格
37         BigDecimal afterPrice = bigDecimal.add(new BigDecimal(String.valueOf(water.getPrice())));
38         return afterPrice.doubleValue();
39     }
40 }
View Code
 

6.建立一个果汁(装饰者)的具体实现类-橙子汁

 1  package com.deckerPattern.expandClass;
 2  
 3  import com.deckerPattern.basicClass.FruitJuice;
 4  import com.deckerPattern.basicClass.Water;
 5  
 6  import java.math.BigDecimal;
 7  
 8  /**
 9   * @program: test
10  * @description: 橙子汁,果汁的一种,装饰者的实现类,继承果汁抽象类,
11  * @author: Mr.Yang
12  * @create: -- :
13  **/
14 public class OrangeJuice extends FruitJuice {
15 
16     //橙子汁的描述
17     private final static String name="橙子汁";
18 
19     //橙子汁的对外成本价
20     private final static double orangePrice=3.2;
21 
22     //让水(被装饰者)记录到变量中
23     Water water;
24 
25     public OrangeJuice(Water water){
26         this.water=water;
27     }
28 
29     public String getDescription() {
30         return water.getDescription()+"  "+name;
31     }
32 
33     public double getPrice() {
34         //先得到成本价,使用double,可能会有精度丢失的情况,bigDecimal的构造方法中最好传入,String类型的数字字符串
35         BigDecimal bigDecimal = new BigDecimal(String.valueOf(orangePrice));
36         //成本价,加上水的价格
37         BigDecimal afterPrice = bigDecimal.add(new BigDecimal(String.valueOf(water.getPrice())));
38         return afterPrice.doubleValue();
39     }
40 }
View Code
 

7.测试类

 1  package com.deckerPattern.patternTest;
 2  
 3  import com.deckerPattern.basicClass.Water;
 4  import com.deckerPattern.expandClass.AppleJuice;
 5  import com.deckerPattern.expandClass.MountainSpringWater;
 6  import com.deckerPattern.expandClass.OrangeJuice;
 7  import com.deckerPattern.expandClass.WellWater;
 8  
 9  /**
10  * @program: test
11  * @description: 测试装饰者类
12  * @author: Mr.Yang
13  * @create: -- :
14  **/
15 public class Test {
16     public static void main(String[] args) {
17         System.out.println("A:我要一杯井水,我想尝尝");
18         Water wellWater = new WellWater();
19         System.out.println("服务员:这是 "+wellWater.getDescription()+" 价格是"+wellWater.getPrice());
20 
21         System.out.println("B:点一杯山泉水,兑橙子汁,再来个苹果汁,放一起,我试试味道");
22         Water mountainSpringWater = new MountainSpringWater();
23         mountainSpringWater=new OrangeJuice(mountainSpringWater);
24         mountainSpringWater=new AppleJuice(mountainSpringWater);
25         System.out.println("服务员:这是 "+mountainSpringWater.getDescription()+" 价格是"+mountainSpringWater.getPrice());
26 
27     }
28 }
View Code

 

posted @ 2018-11-24 13:41  晟初智启  阅读(220)  评论(0)    收藏  举报