zoukankan      html  css  js  c++  java
  • 设计模式之装饰者模式

    装饰者模式动态的将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。假如设计一个咖啡店的订单系统,咖啡有很多种,比如:HouseBlend,DarkRoast,Decaf 等等,同时,可以在咖啡里面加入很多调料,比如:豆浆(Soy),摩卡(Mocha)等等,这样会造成搭配方式有很多种,该如何来计算一杯咖啡的价格就成了问题,下面是最容易想到的办法。

    //定义咖啡的抽象类
    public abstract class Beverage {    
    
        String description = "Unknown Beverage";
        public String getDescription() {
            return description;
        }
        public abstract double cost();    
    }
    
    //加豆浆的HouseBlend
    public Class HouseBlendWithSoy extends Beverage {
    
        public HouseBlendWithSoy() {
            description = "HouseBlendWithSoy";
        }
        public double cost() {
            return 1.99;
        }
    }
    //加摩卡的DarkRoast
    public Class DarkRoastWithMocha extends Beverage {
    
        public DarkRoastWithMocha() {
            description = "DarkRoastWithMocha";
        }
        public double cost() {
            return 2.90;
        }
    }
    //..........

    显然如果这样通过构造类来逐个算价格是很累人的,并且不利于扩展,假如某个原料价格改变,就要改变很多类,

    下面用装饰者模式来解决这个问题:

    public abstract class Beverage {    
    
        String description = "Unknown Beverage";
        public String getDescription() {
            return description;
        }
        public abstract double cost();    
    }
    //定义调料的抽象类,让它继承Beverage
    public abstract class CondimentDecorator extends Beverage {
        public abstract String getDescription();
    }
    //这里很关键,让摩卡继承调料的抽象类,这样摩卡也是Beverage的子类,同时
    //在摩卡类里面用一个实例变量记录Beverage
    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 1.1 + beverage.cost();
        }
    }

    这里的继承作用在于让装饰者和被装饰者保持一样的类型,也就是有共同的超类,而不是利用继承获得“行为”,它的行为主要是通过装饰者与组件组合时会加入新的行为,是由组合对象而来。

  • 相关阅读:
    spring和mybatis整合配置文件
    点击不同按钮,加载不同的页面(不使用iframe的情况下)
    两个完整的jquery slide多方面滑动效果实例
    autofac无法解析一例
    c# Random太快产生的随机数会重复
    linq和ef关于group by取最大值的两种写法
    JavaScript 汉字与拼音互转终极方案 附JS拼音输入法
    使用USB Key(加密狗)实现身份认证
    让Dreamweaver支持cshtml (MVC Razor环境)
    使用EF扩展EntityFramework.BulkInsert实现批量插入
  • 原文地址:https://www.cnblogs.com/fengz/p/6751987.html
Copyright © 2011-2022 走看看