Decorator 装饰者模式
面向对象的其中一个重要概念就是继承。通过子类继承父类来扩充父类不具备的属性与方法,这个过程是在编译期完成的。假设我们现在需要一个不一样的功能,动态地扩充父类的方法,或者扩充其中一个子类的方法,或者组合各个子类的方法实现一个完整的功能,如果用继承的方式来实现,势必需要大量的不确定的定义类。因此可以采用装修者的模式在运行阶段动态的定义类。
通过建立一个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来实现的。