装饰者模式
装饰者模式
星巴克咖啡订单项目:
1)咖啡种类/单品咖啡:Espresso(意大利浓咖啡)、ShortBlack(浓缩咖啡)、LongBlack(美式咖啡)、Decaf(无因咖啡)
2)调料:Milk、Soy(豆浆)、Chocolate
3)要求在扩展新的咖啡种类的时候,具有良好的扩展性、改动方便、维护方便。
4)使用OO(面向对象)的方法来计算不同种类咖啡的费用:客户可以点单品咖啡,也可以点单品咖啡+调料组合。
方案一 较差的传统方案
这种解决方案会造成类爆炸
方案二 对方案一进行改进
前面分析到方案一因为咖啡单品+调料组合会造成类爆炸,因此可以做改进,将调料内置到Drink类中,这样就不会造成类的数量过多。从而提高了代码的可维护性。
说明:milk,soy.chocolate可以设计为boolean类型,表示是否需要添加相应的调料。
方案二问题分析:
- 方案二可以控制类的数量,不至于造成类的数量过多。
- 在增加或者删除调料类的时候,代码的维护量很大(因为都要在同一个Drink类中进行修改)
- 考虑到用户可以添加多份调料的时候,可以将hasMilk 返回一个对应的int 类型
- 所以我们考虑使用装饰者模式
装饰者模式定义
代码演示:
package com.sky.decorator; /** * 将各种单品咖啡做一个缓存层 */ public class Coffee extends Drink { @Override public float cost() { return super .getPrice(); } } package com.sky.decorator; /** * 意大利咖啡 要继承缓存层 */ public class Espresso extends Coffee { // 通过构造器,初始化意大利咖啡 描述 和 价格 public Espresso(){ setDes( " 意大利咖啡 " ); setPrice( 6 .0f); } } package com.sky.decorator; /** * 美式咖啡 */ public class LongBlack extends Coffee { public LongBlack(){ setDes( " 美式咖啡 " ); setPrice( 5 .0f); } } package com.sky.decorator; /** * 浓缩咖啡 单品咖啡 */ public class ShortBlack extends Coffee { public ShortBlack(){ setDes( " 浓缩咖啡 " ); setPrice( 4 .0f); } } package com.sky.decorator; /** * 无因咖啡 */ public class Decaf extends Coffee { public Decaf(){ setDes( " 无因咖啡 " ); setPrice( 3 .0f); } } package com.sky.decorator; /** * 抽象类 */ public abstract class Drink { private String des; // 描述 private float price = 0 .0f; // 价格 // 添加set get 方法 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.sky.decorator; /** * 装饰者 */ public class Decorator extends Drink { private Drink obj; // 被装饰者 public Decorator(Drink obj){ // 体现的是一种组合关系 this .obj = obj; } @Override public float cost() { // super.getPrice() 表示自己的价格,其中super.是可以不写的 return super .getPrice() + obj.cost(); } @Override public String getDes() { // 其中super.是可以不写的 // obj.getDes() 表示输出被装饰者的信息 return super .getDes() + " " + super .getPrice() + " " + obj.getDes() + " " + obj.getPrice(); } } package com.sky.decorator; /** * 调味品 巧克力 */ public class Chocolate extends Decorator { public Chocolate(Drink obj) { super (obj); setDes( " 巧克力 " ); setPrice( 3 .0f); } } package com.sky.decorator; /** * 调味品 牛奶 */ public class Milk extends Decorator { public Milk(Drink obj) { super (obj); setDes( " 牛奶 " ); setPrice( 2 .0f); } } package com.sky.decorator; /** * 调味品 豆浆 */ public class Soy extends Decorator { public Soy(Drink obj) { super (obj); setDes( " 豆浆 " ); setPrice( 1 .5f); } } package com.sky.decorator; public class CoffeeBar { public static void main(String[] args) { // 使用装饰者模式点一份美式咖啡和两份牛奶 // 1.先点一份美式咖啡 Drink order = new LongBlack(); System.out.println( " 描述:" + order.getDes()); System.out.println( " 费用:" + order.cost()); // 2.再加一份牛奶 order = new Milk(order); System.out.println( " 描述:" + order.getDes()); System.out.println( " 费用:" + order.cost()); // 3.再加入一份巧克力 order = new Chocolate(order); System.out.println( " 描述:" + order.getDes()); System.out.println( " 费用:" + order.cost()); // 3.再加入一份巧克力 order = new Chocolate(order); System.out.println( " 描述:" + order.getDes()); System.out.println( " 费用:" + order.cost()); System.out.println( "===================================" ); System.out.println( "===================================" ); Drink order2 = new Decaf(); System.out.println( " 描述:" + order2.getDes()); System.out.println( " 费用:" + order2.cost()); order2 = new Milk(order2); System.out.println( " 描述:" + order2.getDes()); System.out.println( " 费用:" + order2.cost()); } } 描述: 美式咖啡 费用: 5.0 描述: 牛奶 2.0 美式咖啡 5.0 费用: 7.0 描述: 巧克力 3.0 牛奶 2.0 美式咖啡 5.0 2.0 费用: 10.0 描述: 巧克力 3.0 巧克力 3.0 牛奶 2.0 美式咖啡 5.0 2.0 3.0 费用: 13.0 =================================== =================================== 描述: 无因咖啡 费用: 3.0 描述: 牛奶 2.0 无因咖啡 3.0 费用: 5.0 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY