设计模式—装饰模式

假设要开一家咖啡馆,流程是先选择一种咖啡,然后选择调料,调料不止一种,且可加也不可加。
如何设计:方案一:写一个基类,定义商品名字(description)和价格(cost),具体咖啡和调料都继承此基类。那么会发现,类非常多,意味着,维护变的更加困难。
   方案二:在基类里进行判断是否添加调料,如hasMilk(),setMilk(),hasWhip(),setWhip(),那么只要具体的咖啡继承此基类就行了,所以类是减少了,但相应的问题就来了,如果某种调料不要了,或有新增了一种,如果调料想加两份, 调料价格改变等等。
   也许要问,改就改了,感觉改的东西并不多啊,也不麻烦的样子,但是我们应该去尽力去遵守一项原则,*类应该对扩展开放,对修改关闭*。意思就是在不修改原有的代码情况下,可以搭配新的行为。
   所以现在来认识装饰模式,这里分为装饰者和基本组件,多个装饰者或单个来装饰组件,这说明他们有同一个超类,装饰者可以附加上自己的责任行为,在上面例子里,咖啡就是组件,调料就是装饰者。  可以想象做菜,肉,蔬菜,鱼之类的是组件,而盐,黄酒,味精之类的是装饰者,不同的调料加上菜中,那么菜的味道特性就会发生改变。

简化图

装饰者模式:动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
何谓动态,在客户端上可以自己定义,责任附加,一般意味着在原有基础上对数据进行处理。
   在Java API上I/O流就是运用了这个模式

以下是代码

系统段

顶层抽象类

public abstract class Beverage {

    String description = "Unknow Beverage";

    public String getDescription(){
        return description;
    }

    public abstract double cost();
}

组件A

public class HouseBlend extends Beverage{

    public HouseBlend(){
        description = "House Blend Coffee";
    }

    @Override
    public double cost() {
        return 0.89;
    }

}

组件B

public class Espresso extends Beverage{

    public Espresso(){
        description = "Espresso";
    }

    @Override
    public double cost() {
        return 1.99;
    }
}

装饰者接口

public abstract class CondimentDecorator extends Beverage{

    public abstract String getDescription();
}

装饰者A

public class Mocha extends CondimentDecorator{

    Beverage beverage;

    public Mocha(Beverage beverage){
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ",Mocha";
    }

    @Override
    public double cost() {
        return 0.20 + beverage.cost();
    }   
}

装饰者B

public class Sou extends CondimentDecorator{

Beverage beverage;

    public Sou(Beverage beverage){
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ",Sou";
    }

    @Override
    public double cost() {
        return 1.20 + beverage.cost();
    }
}

客户端

public class StarbuzzCoffee {

    public static void main(String[] args) {
        Beverage beverage = new Espresso();
        System.out.println(beverage.getDescription()
                +"$" + beverage.cost());

        Beverage beverage3 = new HouseBlend();
        beverage3 = new Mocha(beverage3);
        beverage3 = new Sou(beverage3);
        System.out.println(beverage3.getDescription()
                +"$" + beverage3.cost());
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值