设计模式---装饰者模式

目录

 

1、咖啡订单项目

2、方案1-解决咖啡订单项目

3、方案1-解决咖啡订单项目问题分析

4、方案2-解决咖啡订单项目(改进)

5、方案2-解决咖啡订单项目问题分析

6、装饰者定义

7、装饰者模式原理

8、装饰者模式解决咖啡订单项目

9、装饰者模式下的订单:2份巧克力+一份牛奶的LongBlack

10、装饰者模式咖啡订单项目应用实例

11、装饰者模式在JDK应用的源码分析


1、咖啡订单项目

  1. 咖啡种类(单品咖啡):Espresso(意大利浓咖啡)、ShortBlack、LongBlack(美式咖啡)、Decaf(无因咖啡)
  2. 调料:Milk、Soy(豆浆)、Chocolate
  3. 要求在扩展新的咖啡种类时,具有良好的扩展性、改动方便、维护方便
  4. 使用OO的方式来计算不同种类咖啡的费用:客户可以点单品咖啡,也可以单品咖啡+调料组合。

2、方案1-解决咖啡订单项目

较差的方案:

设计模式---装饰者模式_第1张图片

3、方案1-解决咖啡订单项目问题分析

Drink 是一个抽象类,表示饮料

description是对咖啡的描述,比如咖啡的名字

cost() 方法就是计算费用,Drink类中做成一个抽象方法.

Decaf就是单品咖啡,继承自Drink,并实现了cost(每种咖啡的价格不同)

Espress&Milk 就是单品咖啡+饮料,这个组合很多

问题:这样设计,会有很多类,当我们增加一个单品咖啡,或者一个新的调料,就会发生类爆炸。

4、方案2-解决咖啡订单项目(改进)

设计模式---装饰者模式_第2张图片

前面分析到方案1会产生类爆炸,那么我们就想到将调料作为Drink类的属性,这样就不会造成类数量过多,从而提高维护性

 

5、方案2-解决咖啡订单项目问题分析

  • 方案2可以控制类的数量,不至于造成很多的类。
  • 在增加或者删除调料种类时,代码的维护量很大
  • 考虑到用户可以添加多份调料时,可以将hasMilk返回一个对应的int
  • 考虑使用装饰者模式

6、装饰者定义

装饰者模式:动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(ocp)

这里提到的动态的将新功能附加到对象和ocp原则,在后面的应用实例上会以代码的形式体现。

7、装饰者模式原理

装饰者模式就像打包一个快递

主体(Component):比如:陶瓷、衣服等,这些被称为被装饰者,比如前面的Drink

包装(Decorator):比如:报纸填充、塑料泡沫、纸板、木板,比如前面的调料

8、装饰者模式解决咖啡订单项目

设计模式---装饰者模式_第3张图片

9、装饰者模式下的订单:2份巧克力+一份牛奶的LongBlack

设计模式---装饰者模式_第4张图片

10、装饰者模式咖啡订单项目应用实例

package com.mayun.study.designpattern.decorator;

public abstract class Drink {

    public String des;
    private float price =0.0f;

    public String getDes() {
        return des;
    }

    public void setDes(String des) {
        this.des = des;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }
    //计算费用的抽象方法
    //子类来实现
    public abstract float cost();
}

 

package com.mayun.study.designpattern.decorator;

/**
 * 缓冲层
 */
public class Coffee extends Drink{
    @Override
    public float cost() {
        return super.getPrice();
    }
}

 

package com.mayun.study.designpattern.decorator;

public class LongBlack extends Coffee {
    public LongBlack() {
        setDes("LongBlack");
        setPrice(5.0f);
        
    }
}
package com.mayun.study.designpattern.decorator;

public class Espresso extends Coffee {
    public Espresso() {
        setDes(" 意大利咖啡");
        setPrice(6.0f);
    }
}
package com.mayun.study.designpattern.decorator;

public class ShortBlack extends Coffee {
    public ShortBlack() {
        setDes("shortblack");
        setPrice(4.0f);
    }
}

 

package com.mayun.study.designpattern.decorator;

/**
 * 这个是关键类,继承+组合
 */
public class Decorator extends Drink {
    private Drink obj;

    public Decorator(Drink obj) {//组合
        this.obj = obj;
    }

    @Override
    public float cost() {
        return getPrice() + obj.cost();
    }

    @Override
    public String getDes() {
        //obj.getDes() 输出了被装饰者的信息
        return des +" "+super.getPrice()+"&&"+obj.getDes();
    }
}

 

package com.mayun.study.designpattern.decorator;

/**
 * 具体的Decorator ,这里就是调味品
 */
public class Chocolate extends Decorator {
    public Chocolate(Drink obj) {
        super(obj);
        setDes(" 巧克力");
        setPrice(3.0f);//调味品的价格
    }
}

 

package com.mayun.study.designpattern.decorator;

public class Milk extends Decorator {
    public Milk(Drink obj) {
        super(obj);
        setDes(" 牛奶");
        setPrice(2.0f);//调味品的价格
    }
}

 

package com.mayun.study.designpattern.decorator;

public class Soy extends Decorator {
    public Soy(Drink obj) {
        super(obj);
        setDes(" 豆浆");
        setPrice(1.5f);
    }
}

 

package com.mayun.study.designpattern.decorator;

/**
 * 测试类
 */
public class CoffeeBar {

    public static void main(String[] args) {
        //装饰者模式下的订单:2份巧克力+一份牛奶的LongBlack
        //1.点一份LongBlank
        Drink order = new LongBlack();
        System.out.println("费用1=" + order.cost());
        System.out.println("描述1=" + order.getDes());

        //2.加一份牛奶
        order = new Milk(order);
        System.out.println("order 加一份牛奶 费用= " + order.cost());
        System.out.println("order 加一份牛奶 描述=" + order.getDes());

        //3.加一份巧克力
        order = new Chocolate(order);
        System.out.println("order 加一份牛奶 加一份巧克力 费用= " + order.cost());
        System.out.println("order 加一份牛奶  加一份巧克力 描述=" + order.getDes());

        //4.再加一份巧克力
        order = new Chocolate(order);
        System.out.println("order 加一份牛奶 加2份巧克力 费用= " + order.cost());
        System.out.println("order 加一份牛奶  加2份巧克力 描述=" + order.getDes());


    }
}

11、装饰者模式在JDK应用的源码分析

Java的Io结构,FilterInputStream就是一个装饰者。

设计模式---装饰者模式_第5张图片

你可能感兴趣的:(设计模式,设计模式)