模式定义
面向对象的其中一个重要概念就是继承。通过子类继承父类来扩充父类不具备的属性与方法,这个过程是在编译期完成的。假设我们现在需要一个不一样的功能,动态地扩充父类的方法,或者扩充其中一个子类的方法,或者组合各个子类的方法实现一个完整的功能,如果用继承的方式来实现,势必需要大量的不确定的定义类。因此可以采用装修者的模式在运行阶段动态的定义类。
使用范围
- 动态地扩充子类的功能
- 组合使用多个子类的功能
使用方法
通过建立一个Decorator类来包裹一个原始类,同时将这个原始类作为参数来传递给Decorator的实现子类来间接引用原始类的所有方法,同时实现子类可以扩充其他功能,这样一层套一层,就能动态实现类功能的组合,就好像装修一样。
举例说明
创建一个Windows风格的窗口,使用一个Draw的方法来完成窗口的绘制。首先定义一个接口Windows,期望它的实现类能完成接口定义的所有功能。
public interface Windows {
public void draw();
public String getDescription();
}
现在创建一个普通的窗口,比如画出矩形形状,绘出里面的菜单等等。
public class CommonWindows implements Windows{
public void draw(){
// draw menus
}
public String getDescription(){
return "Common Windows";
}
}
此刻,如果需要该窗口能含有水平滚动条,该如何做呢?最简单的方法是创建一个实现类来实现接口完成。都可以。同样道理,如果需要创建含有垂直滚动条的 窗口,那就定义一个类似的实现类来完成接口的定义。问题:如果需要创建一个既有水平滚动条又有水平滚动条,同时又是普通窗口(当然有复杂窗口)的window,该如何做呢?显然再定义一个类就不合适了。Decorator就派到了用场。
public abstract class WindowsDecorator implements Windows{
public Windows decoratedWindows;
public WindowsDecorator(Windows winToBeDecorated){
decoratedWindows = winToBeDecorated;
}
}
注意Windows在此处是作为参数被构造器包裹起来的,其作用就是要实现层层包裹,完成功能的装修。
然后开始定义水平滚动条的窗口,注意它不直接绘制菜单(交给被包裹的类去做),只负责自己的任务,既,画水平滚动条。
public class HorizontalBarWindows extends WindowsDecorator{
public HorizontalBarWindows(Windows winToBeDecorated) {
super(winToBeDecorated);
}
public void draw(){
drawHorizontalBar();
decoratedWindows.draw();
}
public void drawHorizontalBar(){
// draw horizontal bar codes here
}
public String getDescription(){
return decoratedWindows.getDescription() + " + Horizontal Bar";
}
}
再定义一个垂直的:
public class VerticalBarWindows extends WindowsDecorator{
public VerticalBarWindows(Windows winToBeDecorated) {
super(winToBeDecorated);
}
public void draw(){
drawHorizontalBar();
decoratedWindows.draw();
}
public void drawHorizontalBar(){
// draw horizontal bar codes here
}
public String getDescription(){
return decoratedWindows.getDescription() + " + Vertical Bar";
}
}
Windows该有的功能都有了,接下来就看客户端是如何动态的去装修。 定义一个含水平滚动条的普通窗口:
public class Client {
public static void main(String args[]){
Windows win = new HorizontalBarWindows(new CommonWindows());
System.out.println(win.getDescription());
}
}
定义一个含垂直滚动条的普通窗口:
public class Client {
public static void main(String args[]){
Windows win = new VerticalBarWindows(new CommonWindows());
System.out.println(win.getDescription());
}
}
定义一个含水平和垂直滚动条都包括的普通窗口:
public class Client {
public static void main(String args[]){
Windows win = new HorizontalBarWindows(new VerticalBarWindows(new CommonWindows()));
System.out.println(win.getDescription());
}
}
类结构示意
该样例的类结构如下:
注意WindowsDecorator对Windows的引用是通过自身的构造参数decoratedWindows来实现的。
本文深入探讨了动态类功能组合的概念,并通过装饰者模式实例展示了如何在运行阶段动态定义类,以实现子类功能的动态扩充、组合使用多个子类功能。以Windows风格窗口为例,演示了如何通过装饰者模式实现既有水平滚动条又有垂直滚动条的普通窗口,以及如何灵活组合不同功能,提供一种高效、灵活的类功能动态扩展方法。
387

被折叠的 条评论
为什么被折叠?



