类图

package com.atguigu.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.atguigu.decorator;


public class Coffee extends Drink{
    @Override
    public float cost() {
        return getPrice();
    }
}
package com.atguigu.decorator;


public class Espresso extends Coffee{
    // 构造器
    public Espresso() {
        setDes("意大利咖啡");
        // 设置价格6块钱
        setPrice(6.0f);
    }
}
package com.atguigu.decorator;


public class LongBlack extends Coffee{
    public LongBlack() {
        setDes("没事咖啡");
        setPrice(5.0f)
    }
}
package com.atguigu.decorator;


public class ShortBlack extends Coffee{
    public ShortBlack() {
        setDes("单品咖啡");
        setPrice(4.0f);
    }
}
package com.atguigu.decorator;


public class Decorator extends Drink {
    private Drink obj;

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

    @Override
    public float cost() {
        // 自己价格getprice
        return super.getPrice() + obj.cost();
    }

    @Override
    public String getDes() {
        // 输出被装饰者信息
        return des + " " + getPrice() + "&&" + obj.getDes();
//        super不写也行
//        return super.des + " " + super.getPrice() + "&&" + obj.getDes();
    }
}
package com.atguigu.decorator;

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

/**
 * 
 */
public class Milk extends Decorator{
    public Milk(Drink obj) {
        super(obj);
        setDes("牛奶");
        setPrice(2.0f);
    }
}
package com.atguigu.decorator;


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

执行01

package com.atguigu.decorator;


public class CoffeeBar {
    public static void main(String[] args) {

        // 用装饰者模式下订单,: 2份巧克力+1份牛奶的LongBlack
        // 1. 点一份 LongBlack
        Drink order = new LongBlack();
        System.out.println("费用:"+order.cost());
        System.out.println("描述="+order.getDes());
        /*
        费用:5.0
        描述=没事咖啡

        Process finished with exit code 0
        * */
    }
}

执行02

package com.atguigu.decorator;


public class CoffeeBar {
    public static void main(String[] args) {

        // 用装饰者模式下订单,: 2份巧克力+1份牛奶的LongBlack
        // 1. 点一份 LongBlack
        Drink order = new LongBlack();
        System.out.println("费用:"+order.cost());
        System.out.println("描述="+order.getDes());

        // 2. 加一份牛奶
        order = new Milk(order);
        // 参数就是返回值,相当于order被装饰了
        // 相当于给我们第一份订单加入了一份牛奶

        System.out.println("order加入一份牛奶 费用="+order.cost());
        System.out.println("order加入一份牛奶 描述="+order.getDes());
        /*
        费用:5.0
        描述=没事咖啡
        order加入一份牛奶 费用=7.0
        order加入一份牛奶 描述=牛奶 2.0&&没事咖啡

        Process finished with exit code 0
        * */
    }
}

执行03

package com.atguigu.decorator;


public class CoffeeBar {
    public static void main(String[] args) {

        // 用装饰者模式下订单,: 2份巧克力+1份牛奶的LongBlack
        // 1. 点一份 LongBlack
        Drink order = new LongBlack();
        System.out.println("费用:"+order.cost());
        System.out.println("描述="+order.getDes());

        // 2. 加一份牛奶
        order = new Milk(order);
        // 参数就是返回值,相当于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());
        /*
        费用:5.0
        描述=没事咖啡
        order加入一份牛奶 费用=7.0
        order加入一份牛奶 描述=牛奶 2.0&&没事咖啡
        order加入一份牛奶和巧克力 费用=10.0
        order加入一份牛奶和巧克力 描述=巧克力 3.0&&牛奶 2.0&&没事咖啡
        * */
    }
}

执行04

package com.atguigu.decorator;


public class CoffeeBar {
    public static void main(String[] args) {

        // 用装饰者模式下订单,: 2份巧克力+1份牛奶的LongBlack
        // 1. 点一份 LongBlack
        Drink order = new LongBlack();
        System.out.println("费用:"+order.cost());
        System.out.println("描述="+order.getDes());

        // 2. 加一份牛奶
        order = new Milk(order);
        // 参数就是返回值,相当于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());
        /*
        费用:5.0
        描述=没事咖啡
        order加入一份牛奶 费用=7.0
        order加入一份牛奶 描述=牛奶 2.0&&没事咖啡
        order加入一份牛奶和巧克力 费用=10.0
        order加入一份牛奶和巧克力 描述=巧克力 3.0&&牛奶 2.0&&没事咖啡
        order加入一份牛奶和2巧克力 费用=13.0
        order加入一份牛奶和2巧克力 描述=巧克力 3.0&&巧克力 3.0&&牛奶 2.0&&没事咖啡
        * */
    }
}

课堂休息

同学有没有发现,这个模式的优势,我如果想要扩展,一个新的种类的咖啡,比如 DeCaf 咖啡,我只需要新建这个类之后,他就能和各个调料进行关联了

秒啊

看代码

我现在加上这个

package com.atguigu.decorator;


public class DeCaf extends Coffee{
    public DeCaf() {
        setDes("无因咖啡");
        setPrice(1.0f);
    }
}

然后,看我操作

package com.atguigu.decorator;


public class CoffeeBar {
    public static void main(String[] args) {
        System.out.println("-----------------------------");

        // 用装饰者模式下订单,: 2份巧克力+1份牛奶的LongBlack
        // 1. 点一份 LongBlack
        Drink order = new LongBlack();
        System.out.println("order没事费用:"+order.cost());
        System.out.println("order没事描述="+order.getDes());

        // 2. 加一份牛奶
        order = new Milk(order);
        // 参数就是返回值,相当于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());

        System.out.println("-----------------------------");

        // 第二个订单,我喝无因咖啡
        Drink order2 = new DeCaf();

        System.out.println("order2无因费用:"+order2.cost());
        System.out.println("order2无因描述="+order2.getDes());
        /*
        -----------------------------
        order没事费用:5.0
        order没事描述=没事咖啡
        order加入一份牛奶 费用=7.0
        order加入一份牛奶 描述=牛奶 2.0&&没事咖啡
        order加入一份牛奶和巧克力 费用=10.0
        order加入一份牛奶和巧克力 描述=巧克力 3.0&&牛奶 2.0&&没事咖啡
        order加入一份牛奶和2巧克力 费用=13.0
        order加入一份牛奶和2巧克力 描述=巧克力 3.0&&巧克力 3.0&&牛奶 2.0&&没事咖啡
        -----------------------------
        order2无因费用:1.0
        order2无因描述=无因咖啡
        * */
    }
}

我还可以直接用之前的调料ex牛奶

package com.atguigu.decorator;


public class CoffeeBar {
    public static void main(String[] args) {
        System.out.println("-----------------------------");

        // 用装饰者模式下订单,: 2份巧克力+1份牛奶的LongBlack
        // 1. 点一份 LongBlack
        Drink order = new LongBlack();
        System.out.println("order没事费用:"+order.cost());
        System.out.println("order没事描述="+order.getDes());

        // 2. 加一份牛奶
        order = new Milk(order);
        // 参数就是返回值,相当于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());

        System.out.println("-----------------------------");

        // 第二个订单,我喝无因咖啡
        Drink order2 = new DeCaf();

        System.out.println("order2无因费用:"+order2.cost());
        System.out.println("order2无因描述="+order2.getDes());

        // 5. 加一份牛奶
        order2 = new Milk(order2);
        // 参数就是返回值,相当于order2被装饰了
        // 相当于给我们第一份订单加入了一份牛奶
        System.out.println("order2加入一份牛奶 费用="+order2.cost());
        System.out.println("order2加入一份牛奶 描述="+order2.getDes());
        /*
        -----------------------------
        order没事费用:5.0
        order没事描述=没事咖啡
        order加入一份牛奶 费用=7.0
        order加入一份牛奶 描述=牛奶 2.0&&没事咖啡
        order加入一份牛奶和巧克力 费用=10.0
        order加入一份牛奶和巧克力 描述=巧克力 3.0&&牛奶 2.0&&没事咖啡
        order加入一份牛奶和2巧克力 费用=13.0
        order加入一份牛奶和2巧克力 描述=巧克力 3.0&&巧克力 3.0&&牛奶 2.0&&没事咖啡
        -----------------------------
        order2无因费用:1.0
        order2无因描述=无因咖啡
        order2加入一份牛奶 费用=3.0
        order2加入一份牛奶 描述=牛奶 2.0&&无因咖啡
        * */
    }
}

这你看,给我说NB

扩展思考

那我怎么减去一种咖啡呢

总结

这个不就是python中的装饰器么,搞得这么复杂


results matching ""

    No results matching ""