润饰模式 [取自wikipedia]
修饰模式 [取自wikipedia]
修饰模式,是面向对象编程领域中,一种动态地往一个类中添加新的行为的设计模式。
通过使用修饰模式,可以在运行时扩充一个类的功能。原理是:增加一个修饰类包裹原来的类,包裹的方式一般是通过在将原来的对象作为修饰类的构造函数的参数。装饰类实现新的功能,但是,在不需要用到新功能的地方,它可以直接调用原来的类中的方法。修饰类必须和原来的类有相同的接口。
修饰模式是类继承的另外一种选择。类继承在编译时候增加行为,而装饰模式是在运行时增加行为。
当有几个相互独立的功能需要扩充时,这个区别就变得很重要。在有些面向对象的编程语言中,类不能在运行时被创建,通常在设计的时候也不能预测到有哪几种功能组合。这就意味着要为每一种组合创建一个新类。相反,修饰模式是面向运行时候的对象实例的,这样就可以在运行时根据需要进行组合。一个修饰模式的示例是JAVA里的Java I/O Streams的实现。
例如,一个窗口系统中的窗口,允许这个窗口内容滚动,我们希望给它添加水平或垂直滚动条。假设窗口通过“Window”类实例来表示,并且假设它没有添加滚动条功能。我们可以创建一个子类“ScrollingWindow”来提供,或者我们可以创建一个ScrollingWindowDecorator来为已存在的Window对象添加这个功能。在这点上,只要是解决方案就可以了。 现在我们假设希望选择给我们的窗口添加边框,同样,我们的原始Window类不支持。ScrollingWindow子类现在会造成一个问题,因为它会有效的创建一种新的窗口。如果我们想要给所有窗口添加边框,我们必须创建WindowWithBorder和ScrollingWindowWithBorder子类。显然,这个问题由于被添加类而变得更糟了。对于修饰模式,我们简单的创建一个新类BorderedWindowDecorator,在运行时,我们能够使用ScrollingWindowDecorator或BorderedWindowDecorator或两者结合来修饰已存在的窗口。 一个修饰能够被应用的另一个好例子是当有需要根据某套规则或者几个平行的规则集(不同的用户凭据等)限制访问对象的属性或方法时。
The following classes contain the decorators for all Window classes, including the decorator classes themselves..
以下是一个测试程序,它创建了一个包含多重装饰的Window实例(如,包含了垂直的和水平的滚动条),然后输出它的描述:
修饰模式,是面向对象编程领域中,一种动态地往一个类中添加新的行为的设计模式。
通过使用修饰模式,可以在运行时扩充一个类的功能。原理是:增加一个修饰类包裹原来的类,包裹的方式一般是通过在将原来的对象作为修饰类的构造函数的参数。装饰类实现新的功能,但是,在不需要用到新功能的地方,它可以直接调用原来的类中的方法。修饰类必须和原来的类有相同的接口。
修饰模式是类继承的另外一种选择。类继承在编译时候增加行为,而装饰模式是在运行时增加行为。
当有几个相互独立的功能需要扩充时,这个区别就变得很重要。在有些面向对象的编程语言中,类不能在运行时被创建,通常在设计的时候也不能预测到有哪几种功能组合。这就意味着要为每一种组合创建一个新类。相反,修饰模式是面向运行时候的对象实例的,这样就可以在运行时根据需要进行组合。一个修饰模式的示例是JAVA里的Java I/O Streams的实现。
例如,一个窗口系统中的窗口,允许这个窗口内容滚动,我们希望给它添加水平或垂直滚动条。假设窗口通过“Window”类实例来表示,并且假设它没有添加滚动条功能。我们可以创建一个子类“ScrollingWindow”来提供,或者我们可以创建一个ScrollingWindowDecorator来为已存在的Window对象添加这个功能。在这点上,只要是解决方案就可以了。 现在我们假设希望选择给我们的窗口添加边框,同样,我们的原始Window类不支持。ScrollingWindow子类现在会造成一个问题,因为它会有效的创建一种新的窗口。如果我们想要给所有窗口添加边框,我们必须创建WindowWithBorder和ScrollingWindowWithBorder子类。显然,这个问题由于被添加类而变得更糟了。对于修饰模式,我们简单的创建一个新类BorderedWindowDecorator,在运行时,我们能够使用ScrollingWindowDecorator或BorderedWindowDecorator或两者结合来修饰已存在的窗口。 一个修饰能够被应用的另一个好例子是当有需要根据某套规则或者几个平行的规则集(不同的用户凭据等)限制访问对象的属性或方法时。
// the Window interface interface Window { public void draw(); // draws the Window public String getDescription(); // returns a description of the Window } // implementation of a simple Window without any scrollbars class SimpleWindow implements Window { public void draw() { // draw window } public String getDescription() { return "simple window"; } }
The following classes contain the decorators for all Window classes, including the decorator classes themselves..
// abstract decorator class - note that it implements Window abstract class WindowDecorator implements Window { protected Window decoratedWindow; // the Window being decorated public WindowDecorator (Window decoratedWindow) { this.decoratedWindow = decoratedWindow; } } // the first concrete decorator which adds vertical scrollbar functionality class VerticalScrollBarDecorator extends WindowDecorator { public VerticalScrollBarDecorator (Window decoratedWindow) { super(decoratedWindow); } public void draw() { drawVerticalScrollBar(); decoratedWindow.draw(); } private void drawVerticalScrollBar() { // draw the vertical scrollbar } public String getDescription() { return decoratedWindow.getDescription() + ", including vertical scrollbars"; } } // the second concrete decorator which adds horizontal scrollbar functionality class HorizontalScrollBarDecorator extends WindowDecorator { public HorizontalScrollBarDecorator (Window decoratedWindow) { super(decoratedWindow); } public void draw() { drawHorizontalScrollBar(); decoratedWindow.draw(); } private void drawHorizontalScrollBar() { // draw the horizontal scrollbar } public String getDescription() { return decoratedWindow.getDescription() + ", including horizontal scrollbars"; } }
以下是一个测试程序,它创建了一个包含多重装饰的Window实例(如,包含了垂直的和水平的滚动条),然后输出它的描述:
public class DecoratedWindowTest { public static void main(String[] args) { // create a decorated Window with horizontal and vertical scrollbars Window decoratedWindow = new HorizontalScrollBarDecorator ( new VerticalScrollBarDecorator(new SimpleWindow())); // print the Window's description System.out.println(decoratedWindow.getDescription()); } }