因此,装饰器模式允许您动态地向类添加行为,对吧?但是,装饰器必须从获取行为的类的基类继承,或者必须实现其中一个接口。实际上,我可以回想起的所有示例都有一个公开的函数,所以应用装饰器很有效但是如果你想让装饰器添加行为,例如记录到不具有相同接口的各种类 - 它将无法工作。我在这里错过了什么吗?这是一个暗示,我想要记录的所有类应该包含在同一个接口中,比如命令或其他东西?
例如
class A
{
whatever();
idontknow();
}
class B
{
bananas();
}
我无法让装饰器记录这些类中函数的调用,因为它们是不同的。
答案 0 :(得分:2)
我相信你可能误解了装饰模式,而且从你对问题的解释来看,你似乎确实需要别的东西:你需要实现一个跨领域的关注 - 一些可以完全应用的常见功能不相关的行为。例如。你想包装不相关函数的日志。
这被称为aspect oriented programming,简称AOP。
有些工具允许您拦截对方法的调用,并使用所需的行为来扩充它们,即您可以添加方法调用的日志记录,或者确保用户有足够的权限来执行调用等。 .NET中的这些工具通过修改IL来实现这一点,而其他工具则在运行时动态地封装类型。
我在this answer和here too中提供了一个示例。
答案 1 :(得分:1)
装饰器只需要能够像这样“模仿”基类:
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();
}
并在其构造函数中接受基类的实例。