修饰者模式

发布时间:2022-06-20 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了修饰者模式脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

 

经典案例:

星巴克咖啡订单项目(咖啡馆〉:1)咖啡种类/单品咖啡:Espresso(意大利浓咖啡)、ShortBlack、LongBlack(美式咖啡)、Decaf(无因咖啡)2)调料:Milk、Soy(豆浆)、Chocolate3)要求在扩展新的咖啡种类时,具有良好的扩展性、改动方便、维护方便4)使用OO的来计算不同种类咖啡的费用:客户可以点单品咖啡,也可以单品咖啡+调料组合。————————————————版权声明:本文为CSDN博主「金轮哥哥小坏蛋」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/weixin_46633487/article/details/110010533

 

修饰者模式

 

 

 

  1. 装饰者模式:动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(ocp)’
  2. 这里提到的动态的将新功能附加到对象和ocp原则,在后面的应用实例上会以代码的形式体现.
  3. 自认为装饰者模式内部是通过被装饰类来作为传递媒介,通过向上转型是的新添加的被修饰类与修饰类都可以在不修改内部代码的前提下可实现功能,体现了ocp原则
  4. 上图中装饰类之所以与被装饰类是继承与组合的关系,我认为继承是将Milk、Chocolate视作被装饰类(相对于Decaf、ShortBlack等具体咖啡类),因为Milk也是由它的Prica与Desc的,所以继承也是为了让调料子类得以新增
  5. 接4、而组合则是为了让咖啡类可以被调料类装饰(这正是我们需要实现的核心功能,即装饰)。
  6. 个人感觉被装饰类类名可以改为Product(Drink总让我感觉怪怪的,因为装饰类也要继承Drink类,但Chololate貌似不是一种Drink吧)

代码如下:

  被装饰抽象类

public abstract class Product {    public String desc;    private float price;    public String getDesc() {        return desc;    }    public void setDesc(String desc) {        this.desc = desc;    }    public float getPrice() {        return price;    }    public void setPrice(float price) {        this.price = price;    }    /**     * 计算价格的     * @return     */    public abstract float cost();}

如果咖啡类很多还可以抽象出一个类,主要用于实现共有特性,比如下面这个类

public class Coffee extends Product{    /**     * 计算咖啡的价格     * @return 咖啡的价格     */    public float cost() {        return super.getPrice();    }}具体咖啡类(具体被装饰类),我写了两个
public class BlackCoffee extends Coffee{    public BlackCoffee() {        setDesc("黑咖啡");        setPrice(4.0f);    }}
public class WitheCoffee extends Coffee{    public WitheCoffee() {        setDesc("白咖啡");        setPrice(3.0f);    }}
--------------------------------------------------------------上面一部分实现的是UML图的左半边下面是UML图的右半边--------------------------------------------------------------
/** * 装饰者类 */
public class Decorator extends Product{/** 这里用的是obj也表明了 此传进来的不仅仅是具体Coffee,还有可能是Milk里面包含具体Coffee,甚至是Chololate包含Milk,Milk包含j打Coffee*/    private Product obj;    public Decorator(Product obj) {        this.obj = obj;    }    /**     * 计算咖啡与补充物的价格总和     * @return 合计价格     */    public float cost() {        return super.getPrice() + obj.cost();    }    /**     * 订单内容     * @return     */    public String getDesc() {        return super.getDesc() + " " + super.getPrice() + "&&" + obj.getDesc();    }}
具体装饰类
public class Chocolate extends Decorator{    public Chocolate(Product coffee) {        super(coffee);        setDesc("巧克力");        setPrice(7.5f);    }}
public class Milk extends Decorator{    public Milk(Product coffee) {        super(coffee);        setDesc("牛奶");        setPrice(9.0f);    }}测试代码
public class DecoratorTest {    public static void main(String[] args) {        /**         * 1、先点一杯白咖啡         */        Product order = new WitheCoffee();        System.out.println("费用一:" + order.cost());        System.out.println("描述:" + order.getDesc());        /**         * 加入一份牛奶         */        order = new Milk(order);        System.out.println("费用二:" + order.cost());        System.out.println("描述:" + order.getDesc());        /**         * 加入一份巧克力         */        order = new Chocolate(order);        System.out.println("费用三:" + order.cost());        System.out.println("描述:" + order.getDesc());        /**         * 加入一份巧克力         */        order = new Chocolate(order);        System.out.println("费用四:" + order.cost());        System.out.println("描述:" + order.getDesc());    }}结果;

费用一:3.0描述:白咖啡费用二:12.0描述:牛奶 9.0&&白咖啡费用三:19.5描述:巧克力 7.5&&牛奶 9.0&&白咖啡费用四:27.0描述:巧克力 7.5&&巧克力 7.5&&牛奶 9.0&&白咖啡

 

代码流程解释:

1、先点一分咖啡,首先构造WitheCoffee具体咖啡类,cost方法会进入Coffee类下执行,getDesc()会进入Product类下执行

2、加入一份牛奶后,首先会构造Milk类,Milk内部会将传进来的coffee会传递到父类也就是Decorator类中,调用Decorator的有参构造方法,注意此时Decorator下的Product order代表的是WitheCoffee这个类的对象,

接着执行cost方法,会进入Decorator类下执行,将Milk的价格与WitheCoffee的价格合计返回,getDesc(),也是一样的

3、再加入巧克力后,注意此时的Decorator下的Product order代表的是Milk这个类的对象,所以再执行Decorator类的cost()时,对于obj.cost,会先执行Milk的Decorator类的cost(),再去执行chocolate的cost(),这样也就实现了价格的总计(实际上这里就是迭代了)。。。。

脚本宝典总结

以上是脚本宝典为你收集整理的修饰者模式全部内容,希望文章能够帮你解决修饰者模式所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: