星巴嗝咖啡需要设计一款咖啡订单设计方案,他们的应用场景是:饮品中有底料和调料,饮品和底料都分别有各自的单价,需要计算出每一种类型饮品的单价。
这是他们的初版设计:

这样设计存在几个问题:
- 相同的底料,每增加一个调料就要创建相应的类。这会造成维护地狱,徒增维护工作量。
- 每个实现抽象类的类都需要单独实现cost方法来计算单价,复用性为零。
为了解决这个问题,他们又重新给出了一下设计方案:

这个设计方案解决了不同底料或调料类需要反复创建的问题,但是在以下需求改变后仍需要进行代码修改,违背了开闭原则(类应该对扩展开放,对修改关闭):
- 调料价钱的改变需要修改所有实现类。
- 出现新的调料,我们需要加上新的方法,并修改超类中的cost方法。
- 出现新的饮料,部分调料可能并不适合放在新饮料中,所以部分调料方法是多余的,但仍然会继承到。
- 双倍摩卡咖啡的场景并不容易实现。
装饰者模式:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性地替代方案。这是一般装饰者地类图:

为了解决以上问题,我们打算用装饰者模式改进以上设计方案:

这样在客户需要特定饮品时,就能通过创建底料,并在外层包装多层调料装饰类的情况下实现饮品的动态创建。
再进一步,将实现优化成接口实现,将抽象类改成接口,就是如下设计思路:

发表回复