技能成神之路:筹划模式(二十)装饰模式

[复制链接]
发表于 2026-1-12 09:02:51 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
干系文章:技能成神之路:二十三种筹划模式(导航页)
先容

   装饰模式(Decorator Pattern)是一种结构型筹划模式,它允许在不改变对象自身的环境下,动态地为对象添加额外的职责。这个模式通常用于加强或改变对象的功能。
  1.界说


装饰模式通过创建一个装饰类,将功能动态地添加到被装饰类的实例中。装饰类与被装饰类实现类似的接口或继承类似的父类,如许装饰对象就可以代替被装饰对象。
2. 重要作用




  • 动态地给一个对象添加额外的职责,而不改变其原来的结构。
  • 提供了比继承更机动的替换方案,通过组合而不是继承来扩展对象的功能。
3. 办理的标题




  • 必要在运行时为对象动态添加功能,而不修改对象本身。
  • 必要制止因类数量过多而导致的复杂性。
  • 必要在不影响其他对象的环境下扩展功能。
4. 模式原理


包罗脚色:

  • 组件接口(Component): 界说了一个接口,用于全部具体组件和装饰器。
  • 具体组件(ConcreteComponent): 实现了组件接口的具体类。
  • 装饰器(Decorator): 实现了组件接口并持有一个组件的引用,用于在其方法中调用被装饰对象的方法。
  • 具体装饰器(ConcreteDecorator): 继承自装饰器类,添加额外的功能。
UML类图:

代码示例:
  1. // Component接口
  2. public interface Coffee {
  3.     double cost();
  4.     String description();
  5. }
  6. // ConcreteComponent具体组件
  7. public class SimpleCoffee implements Coffee {
  8.     @Override
  9.     public double cost() {
  10.         return 5;
  11.     }
  12.     @Override
  13.     public String description() {
  14.         return "Simple Coffee";
  15.     }
  16. }
  17. // Decorator装饰器
  18. public abstract class CoffeeDecorator implements Coffee {
  19.     protected Coffee decoratedCoffee;
  20.     public CoffeeDecorator(Coffee coffee) {
  21.         this.decoratedCoffee = coffee;
  22.     }
  23.     @Override
  24.     public double cost() {
  25.         return decoratedCoffee.cost();
  26.     }
  27.     @Override
  28.     public String description() {
  29.         return decoratedCoffee.description();
  30.     }
  31. }
  32. // ConcreteDecorator具体装饰器
  33. public class MilkDecorator extends CoffeeDecorator {
  34.     public MilkDecorator(Coffee coffee) {
  35.         super(coffee);
  36.     }
  37.     @Override
  38.     public double cost() {
  39.         return super.cost() + 1.5;
  40.     }
  41.     @Override
  42.     public String description() {
  43.         return super.description() + ", Milk";
  44.     }
  45. }
  46. public class SugarDecorator extends CoffeeDecorator {
  47.     public SugarDecorator(Coffee coffee) {
  48.         super(coffee);
  49.     }
  50.     @Override
  51.     public double cost() {
  52.         return super.cost() + 0.5;
  53.     }
  54.     @Override
  55.     public String description() {
  56.         return super.description() + ", Sugar";
  57.     }
  58. }
复制代码
调用
  1. public class DecoratorPatternExample {
  2.     public static void main(String[] args) {
  3.         Coffee simpleCoffee = new SimpleCoffee();
  4.         System.out.println(simpleCoffee.description() + " $" + simpleCoffee.cost());
  5.         Coffee milkCoffee = new MilkDecorator(simpleCoffee);
  6.         System.out.println(milkCoffee.description() + " $" + milkCoffee.cost());
  7.         Coffee milkSugarCoffee = new SugarDecorator(milkCoffee);
  8.         System.out.println(milkSugarCoffee.description() + " $" + milkSugarCoffee.cost());
  9.     }
  10. }
复制代码
打印输出
  1. Simple Coffee \$5.0
  2. Simple Coffee, Milk \$6.5
  3. Simple Coffee, Milk, Sugar \$7.0
复制代码
上面示例,通过利用装饰者模式,步伐可以大概机动地添加新功能而不必要修改原有的 Coffee 实现。
装饰模式看似很简朴,实在一点也不复杂😁,我信赖看完一遍示例,再转头看下界说就会全懂了。
那么看似一个简朴的筹划模式,在我们开发中有哪些应用场景呢?下面举几个经典示例来加深下印象:
1.Java的输入/输出(I/O)库中利用了装饰者模式来加强流的功能。
比方,BufferedInputStream 和 DataInputStream 是装饰者,它们分别装饰 InputStream 类。通过这些装饰者,可以为根本流添加缓冲、数据格式等额外的功能。
emm… 上一篇文章,桥接模式也是举的这个例子,看来Java SDK利用的筹划模式不少啊。
  1. InputStream fileStream = new FileInputStream("file.txt");
  2. BufferedInputStream bufferedStream = new BufferedInputStream(fileStream);
  3. DataInputStream dataStream = new DataInputStream(bufferedStream);
复制代码
2.Android View 组件
安卓开发的同砚肯定都自界说过View吧,比方,创建一个自界说的TextView,通过扩展原始的TextView并添加一些额外的样式或功能。
  1. public class CustomTextView extends TextView {
  2.     public CustomTextView(Context context) {
  3.         super(context);
  4.     }
  5.     @Override
  6.     protected void onDraw(Canvas canvas) {
  7.         super.onDraw(canvas);
  8.         // 添加自定义绘制逻辑
  9.     }
  10. }
复制代码
尚有在 利用 Retrofit 网络哀求时,可以自界说的拦截器,Spring 框架的 AOP通过署理(proxy)对象,可以在不改变原始对象的环境下,动态地添加横切关注点(如日志日志记载、变乱管理等)等等… 这些都是装饰模式的经典案例。大概我们平常没留意,不知道它们用的是装饰模式,只要记着只要是 在运行时动态地添加举动和功能就可以以为是装饰者模式即可。
5. 优缺点


优点:


  • 机动性:可以动态地添加或修改对象的功能,而无需修改原始类。
  • 扩展性:可以通过添加新的装饰器类来扩展功能,不必要改变现有代码。
  • 符合开闭原则:原有类不必要改变,新增功能通过装饰器实现。
缺点:


  • 复杂性:利用装饰模式会增长体系的复杂性,特别是在多个装饰器层叠利用时。
  • 调试困难:由于装饰者的层级结构,调试时大概不容易追踪到具体的功能实现。
6. 应用场景




  • 在图形界面中,可以为组件如按钮、文本框等添加滚动条、边框等装饰。
  • 在Java的IO体系中,装饰模式被广泛应用于各种输入流和输出流的实现中,如BufferedInputStream装饰FileInputStream。
  • 必要在不改变原有类的环境下,动态地为对象添加功能。
7. 总结


装饰模式是一种强大的筹划模式,通过组合对象和装饰器的方式实现功能的动态扩展。它在实际开发中非常有用,可以大概有用地进步代码的机动性和可维护性。固然引入了额外的复杂性,但在许多环境下,这种复杂性是值得的,由于它使得体系可以更容易地顺应变革和需求。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表