设计模式--装饰者模式

来源:互联网 发布:用java编写验证码 编辑:程序博客网 时间:2024/06/05 02:24

装饰者模式

场景

小张的朋友小李在星巴滋(是的,和星巴克一样是卖饮料的,咖啡,茶),准备更新他们订单系统,小李找小张帮忙设计一下,订单系统里有:咖啡,茶,还有可以加的佐料:牛奶,糖,摩卡,柠檬…….
并且咖啡可以加佐料,并且可以加多份佐料。

小张的需求分析

如果直接设计,那么只要穷尽小李他们的咖啡,茶,和佐料的混合,建立对象就可以了,但是穷尽下来,类已经很多了,如果再有新的饮料和佐料加入,那么类的数量太多会造类爆炸,这样做是不符合设计原则的,并且也没有面向抽象编程。
小张想了一下,应该用下设计模式吧,但是不知道用哪种设计模式。

小张: 王哥,我这个有个问题,需要请教下你 …..(复述上述需求)…

老王:这个可以用装饰者模式,这个模式你应该在学java的时候就遇到了,java的io就是使用装饰者模式。

小张: 哦,怪不得当时用io的时候很难理解,那我去了解下装饰者模式

小张的装饰者实现

/** * *饮料类接口 * @Author xuelongjiang */public interface Beverage {    public int cost();}/** * * 咖啡 * @Author xuelongjiang */public class Coffee implements  Beverage {    public int cost() {        return 5;    }}/** * 茶 * @Author xuelongjiang */public class Tea implements  Beverage {    public int cost() {        return 4;    }}/** * 佐料 * @Author xuelongjiang */abstract class Condiment  implements  Beverage{}/** * 牛奶 * @Author xuelongjiang */public class Milk extends   Condiment {    private Beverage beverage;    public Milk(Beverage beverage) {        this.beverage = beverage;    }    public int cost() {        return 2+ beverage.cost();    }}/** * 摩卡 * @Author xuelongjiang */public class Mocha extends   Condiment {    private  Beverage beverage;    public Mocha(Beverage beverage) {        this.beverage = beverage;    }    public int cost() {        return 3+beverage.cost();    }}/** * 装饰者模式测试 * @Author xuelongjiang */public class DecoratorTest {    private static Logger logger = LoggerFactory.getLogger(DecoratorTest.class);    public static void main(String[] args) {        logger.info("纯咖啡");        Beverage coffee = new Coffee();        logger.info(""+coffee.cost());        logger.info("咖啡加牛奶");        coffee = new Milk(coffee);        logger.info(""+coffee.cost());        logger.info("咖啡加牛奶加摩卡");        coffee = new Mocha(coffee);        logger.info(""+coffee.cost());    }}

测试输出:

类图

我们佐料类作为装饰者,用来装饰咖啡和茶,这样我们可以在咖啡中无限的增加佐料,我只需要两个对象就可以。

装饰者模式

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

增加类的行为

要点

  • 继承属于扩展形式之一,但不见得是达到弹性设计的最佳方案
  • 在我们的设计中,应该允许行为可以为扩展,而无需修改现有的代码
  • 组合和委托可用于在运动时动态地加上新的行为
  • 除了继承,装饰者模式也可以让我们扩展行为
  • 装饰者会导致设计中出现很多小对象,如果过度使用,会让程序变得复杂(这也是java io api难以使用的原因)