简介
一般有两种方式可以给一个类或对象新增行为:
- 继承
子类在拥有自身方法同时还拥有父类方法。但这种是静态的,用户无法控制增加行为的方式和时机。 - 关联
将一个类的对象嵌入另一个对象,由另一个对象决定是否调用嵌入对象的行为以便扩展自身行为,这个嵌入的对象就叫做装饰器(Decorator)。
定义
对象结构型模式。
动态地给一个对象增加额外功能,装饰器模式比生成子类实现更为灵活。
装饰模式以对用户透明的方式动态给一个对象附加功能。用户不会觉得对象在装饰前、后有何不同。装饰模式可在无需创造更多子类情况下,扩展对象的功能。
角色
Component 接口: 抽象构件
定义了对象的接口,可以给这些对象动态增加功能
ConcreteComponent 具体类: 具体构件
定义了具体的构件对象,实现了 在抽象构件中声明的方法,装饰器可以给它增加额外的职责(方法)
Decorator 抽象类: 装饰类
抽象装饰类是抽象构件类的子类,用于给具体构件增加职责,但是具 体职责在其子类中实现;
ConcreteDecorator 具体类: 具体装饰类
具体装饰类是抽象装饰类的子类,负责向构 件添加新的职责。
代码实例
窗口 接口
public interface Window { // 绘制窗口 public void draw(); // 返回窗口的描述 public String getDescription(); }
无滚动条功能的简单窗口实现
public class SimpleWindow implements Window { @Override public void draw() { // 绘制窗口 } @Override public String getDescription() { return "simple window"; } }
以下类包含所有Window类的decorator,以及修饰类本身。
// 抽象装饰类 注意实现Window接口 public abstract class WindowDecorator implements Window { // 被装饰的Window protected Window decoratedWindow; public WindowDecorator (Window decoratedWindow) { this.decoratedWindow = decoratedWindow; } @Override public void draw() { decoratedWindow.draw(); } @Override public String getDescription() { return decoratedWindow.getDescription(); } } // 第一个具体装饰器 添加垂直滚动条功能 public class VerticalScrollBar extends WindowDecorator { public VerticalScrollBar(Window windowToBeDecorated) { super(windowToBeDecorated); } @Override public void draw() { super.draw(); drawVerticalScrollBar(); } private void drawVerticalScrollBar() { // Draw the vertical scrollbar } @Override public String getDescription() { return super.getDescription() + ", including vertical scrollbars"; } } // 第二个具体装饰器 添加水平滚动条功能 public class HorizontalScrollBar extends WindowDecorator { public HorizontalScrollBar (Window windowToBeDecorated) { super(windowToBeDecorated); } @Override public void draw() { super.draw(); drawHorizontalScrollBar(); } private void drawHorizontalScrollBar() { // Draw the horizontal scrollbar } @Override public String getDescription() { return super.getDescription() + ", including horizontal scrollbars"; } }