首页 > 其他 > 详细

设计模式(三)装饰者模式

时间:2020-04-29 14:27:36      阅读:57      评论:0      收藏:0      [点我收藏+]

装饰者模式

大量不同的子类拥有固定的组件大量不同组合时,使用继承显然会造成滥用问题。

考虑到以下两个原则:

  • 分离变化与不变
  • 多用组合,少用继承

应当将固定的组件从这些不同的组合中提取出来,用它们来修饰子类。以咖啡为例。

初步想法

考虑到咖啡存在大量的种类,尤其是可以添加额外的调料,应当从咖啡的基类出发,用实例变量(布尔值)代表咖啡是否添加某种调料。

public abstract class Beverage {
    private String description;
    private boolean milk;
    private boolean soy;
    private boolean mocha;
    private boolean whip;
    
    public abstract String getDescription();
    public double cost();
    // getter和setter方法
    // ...
}

现在只需要针对不同的咖啡种类创建子类,大大降低了需要创建的子类数量。

然而,这种方式缺乏一定的可扩展性:

  • 当调料的价格改变时,需要修改咖啡基类的代码。
  • 当出现新的调料时,需要在咖啡基类中添加相应的代码。
  • 当出现新的咖啡种类时,可能无法将所有的调料都加入其中,这时代码存在调用不合适方法的隐患。
  • 当顾客想要添加双份调料时,目前的程序无法实现。

装饰类

分析可扩展性后,发现单纯地布尔值无法满足真实环境的需求。接下来介绍装饰者模式来解决这一问题。

装饰者模式动态地将责任与功能附加到基础对象上,提供了强大的扩展性。这就像是在使用谷歌浏览器的插件一样,用户可以使用根据自己的需求自由地组合各种功能,来实现浏览器的个性化。

装饰者模式设计一个抽象的组件基类,被修饰类装饰类继承这个基类,而抽象的装饰类也有不同的装饰者子类,它们拥有一个组件基类的实例变量。

利用这种结构,就能不断地在基础类上扩展新的装饰者,并且基础类不需要了解其装饰者的功能与责任,这些责任与功能由装饰者自身负责。

public abstract class Beverage {
    String description = "Unknown Beverage";
    
    public String getDescription() {
        return description;
    }
    public abstract double cost();
}
public class Espresso extends Beverage { // 类似地还有其他咖啡种类
    public Espresso() {
        description = "Espresso";
    }
    
    public double cost() {
        return 1.99;
    }
}
public abstract class CondimentDecorator extends Beverage {
    public abstract String getDescription();
}
public class Mocha extends CondimentDecorator { // 类似地还有其他调料种类
    Beverage beverage;
    
    public Mocha(Beverage beverage) {
        this.beverage = beverage;
    }
    
    public String getDescription() {
        return beverage.getDescription() + ", Mocha";
    }
    
    public double cost() {
        return 0.20 + beverage.cost();
    }
}

被装饰的咖啡种类只知道自己的种类所对应的价格,最终的饮品的价格由其所有的装饰者决定。

设计原则

  • 封装变化的部分
  • 多用组合,少用继承
  • 针对接口编程,不针对实现编程
  • 交互对象松耦合
  • 对扩展开放,对修改关闭

设计模式(三)装饰者模式

原文:https://www.cnblogs.com/aries99c/p/12801528.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!