使用Decorator模式 java程序员知道可以通过扩展一个类来改变类的行为和扩展一个类的功能。这个行为被称为继续,它是面向对象编程的一个重要的特性. 举例来说,假如你想得到一个带有边框的Swing类型标签,你可以子类化javax.swing.JLabel类。然而,子类化并不总是有效。当继续不能解决问题的时候,你不得不求助与其它的方式。比如,使用Decorator模式。 这篇文章解释了Decorator模式是什么,并说明什么时候应该子类化,什么时候应该采用Decorate模式。 在Java语言中要害字extends被提供来子类化(扩展)一个类。具有丰富的面向对象编程经验的程序员知道子类化的威力。通过扩展一个类,我们能够改变这个类的行为。以列表1所讲的JBorderLabel类为例,它扩展了javax.swing.JLabel类,除了多了一个边框,它和JLabel类具有相同的外观和行为。 the JBorderLabel class, an example of subclassing package decorator;
public void paint(Graphics g) { super.paint(g); int height = this.getHeight(); int width = this.getWidth(); g.drawRect(0, 0, width - 1, height - 1); } } 注重,这个BorderDecorator扩展了JComponent,它的构造函数接受一个JComponet类型的参数。这个BorderDecorator类有一个类型为JComponent的属性child,它是传进来的Jcomponent对象的一个引用。 构造函数将被修饰的组件赋值给child变量,并且将这个组件作为一个子组件增加给装饰者。注重,我们使用了BorderLayout作为装饰者的布局。这意味着被增加的这个JComponent将占据这个装饰者的整个区域。 现在,让我们关注一下paint方法。它首先调用了父类的paint方法。这-步操作将画出装饰者,在第一次得到装饰者的长宽以后,我们在装饰者所在区域的边缘画一个长方形。 Figure 1 shows a JFrame with three components: • An instance of JBorderLabel. • A decorated JLabel. • A decorated JCheckBox.
Figure 1 -- comparing subclassing and the Decorator pattern JBorderLabel的一个实例和一个被装饰过的JLabel对象实例从外表看没有什么不同。这说明,Decorator模式可以作为子类化的一个替代方案。第三个组件证实,你能够使用同一个装饰者去扩展不同对象的实例的行为。从这点来看,装饰者是一个(超类)superior,因为仅仅需要创建一个类(BorderDecorator)就可以扩张不同类型的多个对象的功能。 显示了图1中的JFrame类的实现代码。 -- using the BorderDecorator class package decorator;