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来实现的。

下载示例

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值