使用装饰器模式分离职责
我们因为安全、调试或是其他的什么原因,经常需要在我们的程序中插入记录日志的代码,在MS 的 Enterprise Library中, 也提供了日志程序块,由此可见,日志对于任何一个系统都是很重要的。
通常,我们记录的做法是这样的


















当然,假设我们使用工厂来创建业务对象。







调用代码



这些代码工作的很好,但是我们不难发现,我们写日志的代码夹杂在业务逻辑代码之中,而且,我们为了记录业务执行失败的情况,甚至在其中插入了本来可能不必要的异常处理—try/catch块。这使我们的业务逻辑代码变得臃肿而且难以维护。
记住 Fowler 告诉我们的:重构以使用模式。经过一段时间的冥思苦想,我发现 Decorator 模式正是用于解决此问题。重构的目的是将日志记录代码从业务逻辑代码中分离,重构步骤如下:
1、 新建一个 装饰类 ,从 Business 继承,并覆写其中的DoSomeWork 方法。
2、 将 异常处理和日志记录移至 派生类 中,使派生类中覆写的方法调用基类中的方法。
3、 更改工厂,使其返回派生类的实例。
重构以后的代码
业务类:









业务的装饰类
























工厂








工厂的使用者,根本没有意识到,他所使用的对象已经悄悄的发生了改变。这也正是 装饰器 模式的优点 --- 对象的使用者根本不知道他所使用的对象已经被装饰了,但装饰器已经开始工作了。另外,我们可以在运行的时候决定是否使用 装饰类,只要稍稍修改工厂--在工厂中根据上下文判断是返回装饰类还是原始类的实例--就可以了。我们可以对对象使用多重装饰,以使其具有多重职责,这一点也很有用。
个人认为,装饰器的作用在于通过扩展的方式把附加的职责添加到原始对象上,本文介绍的只是它的一个小小的应用。
也有人认为,凡是需要用到装饰器模式的地方,都是需要三段话都是需要使用AOP的地方。AOP带来了代码的优雅,然而使用AOP却是有代价的,效率的或者是其他的代价。