【西瓜带你学设计模式 | 第十二期 - 装饰器模式】装饰器模式 —— 动态叠加功能实现、优缺点与适用场景
文章目录前言1. 装饰器模式是什么2. 装饰器模式解决什么问题3. 实现步骤4. 静态结构4.1 抽象组件Coffee统一接口4.2 具体组件SimpleCoffee基础咖啡4.3 装饰器抽象类CoffeeDecorator4.4 具体装饰器Milk / Sugar5. 动态结构 / 运行时替换点6. 优缺点6.1 优点6.2 缺点7. 和模板方法模式对比7.1 都能“增强行为”但侧重点不同7.2 谁来控制流程8. 和代理模式或外观模式的区别8.1 装饰器 vs 代理8.2 装饰器 vs 外观9. 总结前言在面向对象设计里我们经常遇到这样的需求给一个对象“加功能”而且不想改它的类也不想用继承把功能层层叠叠地搞爆。这时候装饰器模式Decorator Pattern就很合适。可以把它理解成在不改变原对象代码的前提下用“包装一层层”的方式给对象动态叠加职责。1. 装饰器模式是什么**装饰器模式**在不改变原对象结构的情况下通过创建一个包装类Decorator在运行时给对象增加额外功能。它的核心角色一般是Component抽象组件定义对象的公共接口业务能力ConcreteComponent具体组件真正的被装饰对象Decorator装饰器抽象类/基类持有一个Component并实现接口用于“转发 增强”ConcreteDecorator具体装饰器对某个/某类功能进行增强例如加日志、加缓存、加权限2. 装饰器模式解决什么问题典型场景是你想给对象增加功能但功能组合有很多种且希望可灵活启用/禁用。常见例子UI 控件增强文本框 边框文本框 边框 水印文本框 边框 校验 错误提示…请求/响应增强统一日志统一鉴权统一缓存统一压缩/序列化…流式处理输入流 解密输出流 编码输入流 校验 解密…电商价格/计费规则拼装基础价格 满减 优惠券 会员价…3. 实现步骤先抽象出公共接口Component明确“对象能做什么”核心方法签名写一个或多个ConcreteComponent提供基础能力被装饰者写装饰器基类Decorator内部持有一个Component大多数情况下先把调用转发给被包装对象写一个或多个ConcreteDecorator在转发前/后做增强也可以选择不转发、改变结果更灵活客户端按需“层层包裹”这一步带来装饰器模式的“动态叠加”能力4. 静态结构用一个“咖啡加料”例子来展示装饰器模式的静态结构与调用关系。4.1 抽象组件Coffee统一接口publicinterfaceCoffee{Stringmake();}4.2 具体组件SimpleCoffee基础咖啡publicclassSimpleCoffeeimplementsCoffee{OverridepublicStringmake(){return基础咖啡;}}4.3 装饰器抽象类CoffeeDecoratorpublicabstractclassCoffeeDecoratorimplementsCoffee{protectedCoffeecoffee;// 持有被装饰对象publicCoffeeDecorator(Coffeecoffee){this.coffeecoffee;}OverridepublicStringmake(){returncoffee.make();// 默认转发}}4.4 具体装饰器Milk / SugarpublicclassMilkDecoratorextendsCoffeeDecorator{publicMilkDecorator(Coffeecoffee){super(coffee);}OverridepublicStringmake(){returncoffee.make() 加奶;}}publicclassSugarDecoratorextendsCoffeeDecorator{publicSugarDecorator(Coffeecoffee){super(coffee);}OverridepublicStringmake(){returncoffee.make() 加糖;}}5. 动态结构 / 运行时替换点装饰器模式真正“动态”的地方在于运行时决定包裹哪些装饰器以及包裹顺序。客户端示例publicclassClient{publicstaticvoidmain(String[]args){CoffeecoffeenewSimpleCoffee();coffeenewMilkDecorator(coffee);// 动态叠加加奶coffeenewSugarDecorator(coffee);// 动态叠加再加糖System.out.println(coffee.make());// 输出基础咖啡 加奶 加糖}}你会发现SimpleCoffee不需要改MilkDecorator、SugarDecorator都只关心“自己要增加的部分”组合方式由客户端灵活决定6. 优缺点6.1 优点比继承更灵活不必为了每个组合创建大量子类可组合、可动态启用/禁用运行时自由叠加职责符合开闭原则新增功能通常只加新的装饰器类不改原类6.2 缺点装饰层级可能过多组合复杂时调用链会变长调试/排查问题更复杂因为行为来自一串包装层过度使用会让结构“绕”简单场景可能不需要装饰器7. 和模板方法模式对比7.1 都能“增强行为”但侧重点不同模板方法Template Method强调“固定流程骨架 子类替换步骤”装饰器Decorator强调“对象被包装 运行时叠加职责”可以这样记忆模板方法改的是“流程里的某些步骤继承替换”装饰器改的是“对象外面加了什么功能包装叠加”7.2 谁来控制流程模板方法父类控制流程顺序骨架算法装饰器调用沿着包装链传递谁在外层谁先/后增强顺序可控8. 和代理模式或外观模式的区别8.1 装饰器 vs 代理两者都“包装一个对象”但意图不同代理模式核心目标通常是控制访问/管理远程/延迟加载/权限比如懒加载真实对象、权限校验、记录谁访问了它装饰器模式核心目标是增强功能/增加职责比如日志、加糖加奶、加校验、加缓存等“附加行为”简单判断你包装它是为了“替你去做访问控制/转发到真实对象” → 更像代理你包装它是为了“在同一对象能力上继续加功能” → 更像装饰器8.2 装饰器 vs 外观外观模式把复杂系统封装成一个简单入口“统一门面”装饰器模式多层可组合地给单个对象“叠加职责”9. 总结装饰器模式的核心可以概括为一句话用包装Decorator在不修改原对象的前提下运行时动态叠加额外职责。它适合功能可组合且组合种类多希望减少继承导致的爆炸希望运行时决定增强哪些能力
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2486605.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!