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

案例说明

现在有几种饮品,都是单品咖啡,顾客可以点单品咖啡也可以点单品咖啡加调料。

首先有一个抽象类Drink

@Data
public abstract class Drink {
    //描述
    private String desc;
    //价格
    private float price = 0.0f;

    //计算价格的方法
    public abstract float cost();
}

然后有一个咖啡类继承Drink

public class Coffee extends Drink{

    @Override
    public float cost() {
        //不加调料的单品咖啡就是他的原价
        return getPrice();
    }
}

一种意大利咖啡继承咖啡类

public class Expresso extends Coffee{

    public Expresso(){
        setDesc("意大利咖啡");
        setPrice(6f);
    }
}

一种美式咖啡继承咖啡类

public class LongBlack extends Coffee {

    public LongBlack(){
        setDesc("美式咖啡");
        setPrice(10f);
    }
}

然后有一个装饰者类继承Drink,其中聚合了一个被装饰者对象

public class Decorator extends Drink {
    //聚合一个单品咖啡 //被装饰者
    private Drink drink;

    public Decorator(Drink drink){
        this.drink = drink;
    }

    @Override
    public float cost() {
        //调料自己的价格加上单品咖啡的价格
        return super.getPrice() + drink.cost();
    }

    @Override
    public String getDesc() {
        return super.getDesc() + super.getPrice() + drink.getDesc();
    }
}

有一个巧克力类继承装饰者类

public class Chocolate extends Decorator {

    public Chocolate(Drink drink) {
        super(drink);
        setDesc("巧克力");
        setPrice(2f);
    }
}

有一个牛奶类继承装饰者类

public class Milk extends Decorator {

    public Milk(Drink drink) {
        super(drink);
        setDesc("牛奶");
        setPrice(1f);
    }
}

这时可以创建一个咖啡厅类来点咖啡了

public class CoffeeBar {

    public static void main(String[] args) {
        //1 点一份单品美式咖啡
        Drink order = new LongBlack();
        System.out.println("费用:"+order.cost());

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

        //3 加入一份巧克力
        order = new Chocolate(order);
        System.out.println("费用:"+order.cost());
    }
}

输出结果

如果再添加一种新的咖啡或者一种新的调料,只需要去继承咖啡类或者装饰者类即可

装饰者模式在jdk中io流中有使用到

java的io结构中有一个InputStream类,这个类就好比上面案例中的Drink类

他的子类中有FileInputStream、StringBufferInputStream、ByteArrayInputStream,这几个就相当于上面案例中的单品咖啡,也就是被装饰者。

InputStream的子类还有一个FilterInputStream就是装饰者,FilterInputStream下面有几个子类,

BufferInputStream、DataInputStream、LineNumberInputStream就是上面案例中的调料

おすすめ

転載: blog.csdn.net/qq_41890624/article/details/118526725