尚硅谷设计模式学习(9)---[装饰者模式]

本文通过一个星巴克咖啡订单项目的实例,介绍了如何使用Java设计模式中的装饰者模式来解决系统扩展性问题。装饰者模式允许在不修改原有类的基础上,动态地为对象添加新的行为,从而实现灵活的扩展。文章详细展示了装饰者模式的实现过程,包括抽象饮品类、具体饮料、装饰者类和调料类的定义,以及客户端如何模拟下单过程。这种方法避免了因添加新功能而引发的类爆炸问题,体现了开闭原则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

🚀🚀🚀尚硅谷传送门==>B站尚硅谷Java设计模式

❤❤❤感谢尚硅谷❤❤❤

🕒🕑🕐最近开始计划学习一下设计模式了,加油!!!



📢情景引入

星巴克咖啡订单项目(咖啡馆):

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

方案一

比较差的设计样例;耦合度过高;
如果说要添加扩展新的单品咖啡或者组合口味的咖啡,类的数量增加,就会引发"类爆炸".

在这里插入图片描述


方案二:

将调料内置到Drink类,不会造成类数量过多.

但是,添加或者删除调味品的种类时,需要改动维护.

在这里插入图片描述


⚡装饰者模式

装饰者模式动态的将新功能附加到对象上

在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(ocp).

方案三

在这里插入图片描述

比如说下单这样一杯咖啡;

2份巧克力 +一份牛奶的美式咖啡

先计算一份牛奶加美式咖啡,装饰者(牛奶) 包含 被装饰者(美式咖啡);
然后添加一份巧克力计算;装饰者(巧克力) 包含 被装饰者(牛奶+美式咖啡);
在添加一份巧克力计算,装饰者(巧克力) 包含 被装饰者 (牛奶+巧克力+美式咖啡)

在这里插入图片描述


抽象类 饮品类Drink

//饮品类;
public abstract class Drink {
    //对饮品的描述;
    private String description;

    //价格;
    private float price = 0.0f;

    //计算价格;  由子类去实现;
    public abstract float cost();

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }
}

缓冲类Coffee

//缓冲类;
public class Coffee extends Drink{
    public float cost() {
        return super.getPrice();
    }
}

美式咖啡LongBlackCoffee

//美式咖啡
public class LongBlackCoffee extends Coffee{
    //初始化;
    public LongBlackCoffee() {
        setDescription("来份美式咖啡");
        setPrice(15.0f);
    }
}

意大利咖啡EspressoCoffee

//意大利咖啡
public class EspressoCoffee extends Coffee{
    //初始化;
    public EspressoCoffee() {
        setDescription("来份意大利咖啡");
        setPrice(10.0f);
    }
}

浓缩咖啡ShortBlackCoffee

//浓缩咖啡;
public class ShortBlackCoffee extends Coffee{
    //初始化;
    public ShortBlackCoffee() {
        setDescription("来份浓缩咖啡");
        setPrice(12.0f);
    }
}

装饰者Decorator

//装饰者;
public class Decorator extends Drink{

    //被装饰者;
    private Drink object;

    //组合进来;
    public Decorator(Drink object) {
        this.object = object;
    }

    @Override
    public float cost() {
        //计算价格;
        return super.getPrice()+object.cost();
    }


    @Override
    public String getDescription() {
        return super.getDescription()+"<==>"+super.getPrice()+"<=添加到=>"+object.getDescription();
    }
}

调味品牛奶Milk

//牛奶
public class Milk extends Decorator{
    public Milk(Drink object) {
        super(object);
        setDescription("加份牛奶");
        setPrice(5.0f);
    }
}

巧克力Chocolate

//巧克力
public class Chocolate extends Decorator{
    public Chocolate(Drink object) {
        super(object);
        setDescription("加份巧克力");
        setPrice(4.0f);
    }
}

豆浆Soy

//豆浆;
public class Soy extends Decorator{
    public Soy(Drink object) {
        super(object);
        setDescription("加份豆浆");
        setPrice(3.0f);
    }
}

模拟客户下单;
两份巧克力+一份豆浆的美式咖啡

//模拟客户;
public class Client {
    public static void main(String[] args) {

        //两份巧克力+一份豆浆的美式咖啡;

        //1.先点美式咖啡;
        Drink result = new LongBlackCoffee();
        System.out.println("步骤一::"+result.getDescription());
        System.out.println("本次花费==>"+result.cost());

        //2.加份豆浆;
        result = new Soy(result);
        System.out.println("步骤二::"+result.getDescription());
        System.out.println("本次花费==>"+result.cost());

        //3.加份巧克力;
        result = new Chocolate(result);
        System.out.println("步骤三::"+result.getDescription());
        System.out.println("本次花费==>"+result.cost());

        //4.加份巧克力;
        result = new Chocolate(result);
        System.out.println("步骤四::"+result.getDescription());
        System.out.println("最终花费==>"+result.cost());
    }
}

测试输出

步骤一::来份美式咖啡
本次花费==>15.0
步骤二::加份豆浆<==>3.0<=添加到=>来份美式咖啡
本次花费==>18.0
步骤三::加份巧克力<==>4.0<=添加到=>加份豆浆<==>3.0<=添加到=>来份美式咖啡
本次花费==>22.0
步骤四::加份巧克力<==>4.0<=添加到=>加份巧克力<==>4.0<=添加到=>加份豆浆<==>3.0<=添加到=>来份美式咖啡
最终花费==>26.0

装饰者模式在Io中的应用

在这里插入图片描述

FilterInputStream类就是个装饰者(类似于咖啡案例的Decorator);它继承了抽象类InputStream(就类似于咖啡案例的Drink类)
FilterInputStream类下还有子类(具体的修饰者,类似于咖啡案例的Milk,Soy).

在这里插入图片描述

FilterInputStream

在这里插入图片描述

抽象类InputStream

在这里插入图片描述


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小智RE0-走在路上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值