HeadFirst设计模式-装饰者模式(上)

本文通过咖啡店的订单系统实例,探讨了装饰者模式在解决扩展功能问题上的应用。传统的实现方式会导致类爆炸和维护困难,而装饰者模式提供了一种更为灵活的解决方案,允许在不修改原有代码的基础上动态增加对象的功能。文章详细解释了装饰者模式如何避免调料价格变化和新调料添加时的代码修改,以及如何更好地处理如双倍摩卡等特殊需求,以提高系统的可扩展性和可维护性。

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

概述

装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。即组合的方案。

使用装饰者,你将能够在不修改任何底层代码的情况下,给对象赋予新的职责。

咖啡店实例

以咖啡店为实例,讲解装饰者模式的使用。

一家咖啡店的扩张速度很快,他们准备更新订单系统,以符合他们的饮料供应要求。

他们原先的设计是这样的,Beverage(饮料)是一个抽象类,店内所提供的饮料都必须继承此类。

该类主要有两个方法:

  • getDescription()获取描述的方法,由每个子类设置,用来描述饮料,例如“超优深培(Dark Roast)”。

  • cost()计算价格的抽象方法,子类必须定义自己的实现。

购买咖啡时,也可以要求在其中加入各种调料,例如:蒸奶(Steamed Milk)、豆浆(Soy)、摩卡(Mocha,也就是巧克力风味)或覆盖奶泡。咖啡店会根据所加入的调料收取不同的费用。所以订单系统必须考虑到这些调料部分。

一个错误的示范

将各种调料和咖啡的每种组合,都设为一个类。这不仅造成类的爆炸,并且每个cost()方法都需单独算出咖啡和订单上各种调料的价钱。

很明显,这个设计制造了一个维护噩梦。如果豆浆价钱上涨怎么办?新增一种焦糖调料风味时,怎么办?

一个改进方案

改进方案,利用实例变量和继承,追踪这些调料。

先从Beverage基类下手,加上实例变量代表是否加上调料(牛奶、豆浆、摩卡、奶泡…)。

Beverage类中的cost()不再是一个抽象方法,我们提供了cost()的实现,让它计算要加入各种饮料的调料价钱。子类将覆盖cost(),但是会调用超类的cost(),计算出基本饮料加上调料的价钱。

该改进方案存在的问题:

1、调料价格的改变会使我们更改现有代码

2、一旦出现新的调料,就需要加上新的方法,并改变超类中的cost()方法。

3、以后可能会开发出新饮料。对一些饮料而言,例如冰茶,某些调料可能并不适合,但是在这个设计方案中,子类仍将继承那些不适合的方法,例如加奶泡hasWhip()。

4、万一顾客想要双倍摩卡咖啡,该类很难实现。

既然存在以上问题,那如何改进呢,看如何用装饰者模式实现:《HeadFirst设计模式-装饰者模式(中)》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值