修饰模式,是
面向对象编程领域中,一种动态地往一个类中添加新的行为的
设计模式。就功能而言,修饰模式相比生成
子类更为灵活,这样可以给某个对象而不是整个类添加一些功能。
通过使用修饰模式,可以在运行时扩充一个类的功能。原理是:增加一个修饰类包裹原来的类,包裹的方式一般是通过在将原来的对象作为修饰类的构造函数的参数。装饰类实现新的功能,但是,在不需要用到新功能的地方,它可以直接调用原来的类中的方法。修饰类必须和原来的类有相同的接口。
当有几个相互独立的功能需要扩充时,这个区别就变得很重要。在有些面向对象的编程语言中,类不能在运行时被创建,通常在设计的时候也不能预测到有哪几种功能组合。这就意味着要为每一种组合创建一个新类。相反,修饰模式是面向运行时候的对象实例的,这样就可以在运行时根据需要进行组合。一个修饰模式的示例是JAVA里的Java I/O Streams的实现。
例如,一个窗口系统中的窗口,允许这个窗口内容滚动,我们希望给它添加水平或垂直滚动条。假设窗口通过“Window”类实例来表示,并且假设它没有添加滚动条功能。我们可以创建一个子类“ScrollingWindow”来提供,或者我们可以创建一个ScrollingWindowDecorator来为已存在的Window对象添加这个功能。在这点上,只要是解决方案就可以了。 现在我们假设希望选择给我们的窗口添加边框,同样,我们的原始Window类不支持。ScrollingWindow子类现在会造成一个问题,因为它会有效的创建一种新的窗口。如果我们想要给所有窗口添加边框,我们必须创建WindowWithBorder和ScrollingWindowWithBorder子类。显然,这个问题由于被添加类而变得更糟了。对于修饰模式,我们简单的创建一个新类BorderedWindowDecorator,在运行时,我们能够使用ScrollingWindowDecorator或BorderedWindowDecorator或两者结合来修饰已存在的窗口。 一个修饰能够被应用的另一个好例子是当有需要根据某套规则或者几个平行的规则集(不同的用户凭据等)限制访问对象的属性或方法时。
一个对象的属性或方法按照某组规则或几个并行规则(不同用户证书等)需要限制访问时,在这种情况下,不是在原始对象中实现访问控制而是在他的使用中不变或不知道任何限制,并且他被包装在一个访问控制修饰对象中,这个对象能够对允许的原始对象的接口子集服务。