装饰器模式的正确应用

本文关键字:应用 模式 | 更新日期: 2023-09-27 18:09:16

所以装饰器模式允许您动态地为类添加行为,对吗?然而,装饰器必须从获得行为的类的基类继承,或者必须实现它的一个接口。事实上,我能回忆起的所有例子都有一个公开的函数,所以应用装饰器工作得很好,但是如果你想让一个装饰器添加行为,比如日志记录到不同的类,而这些类没有相同的接口,那就行不通了。我遗漏了什么吗?这是否暗示我想要记录的所有类都应该包装在相同的接口中,比如命令或其他东西?

例如

class A
{
    whatever();
    idontknow();
}
class B
{
    bananas();
}

我不能做一个装饰器来记录这些类中函数的调用,因为它们是不同的。

装饰器模式的正确应用

我相信您可能误解了装饰器模式,从您对问题的解释来看,似乎您实际上需要其他东西:您需要实现横切关注点—一些可以应用于完全不相关的行为的通用功能。例如,你想在不相关的函数中封装日志记录。

这被称为面向方面编程,或简称AOP。

有一些工具允许你拦截对方法的调用,并用期望的行为来增强它们,也就是说,你可以在方法调用周围添加日志记录,或者确保用户有足够的权限来执行调用,等等。. net中的一些工具通过修改IL来实现这一点,而其他工具则在运行时动态包装类型。

我在这个答案和这里都提供了一个例子。

只需要decorator能够像这样"模仿"基类:

Class ADecorator : A {
  ADecorator(A a) { /* etc */ }
  void whatever();
  void idontknow();
}
class BDecorator1 : B {
  BDecorator1(B b) { /* etc */ }
  void bananas();
}
class BDecorator2 : B {
  BDecorator2(B b) { /* etc */ }
  void bananas();
}

,并在其构造函数中接受基类的实例。