Java设计模式-结构型-修饰模式

什么是修饰模式

 

修饰模式是面向对象模式的一种,该模式可以动态向类中添加新的功能。动态指的是在程序运行时候,而我们常用的扩展功能的方法是写一个子类继承父类,这样的继承是静态的,因为这样的扩展方法是程序编译时候就体现出来了。

 

在上图中可以看到,接口类Component有2个实现,ConcreteComponent类和Decorator类,Decorator类和它的2个子类对ConcreatedComponent类做了修饰, 这样的实现方式就是修饰模式。子类ConcreteDectoratorExtendingFunctionality和ConcreteDecoratorExtendingState类在ConcreatedComponent类的基础之上增加了新的功能。

 

修饰模式存在的作用

 

之前讨论定义时候说到动态的增加类的功能是修饰模式的作用,而子类增加功能的方式是静态的。子类这样的增加方式并不完美。假设这样的情况,需要给一个类PClass增加特性A,于是我们有了子类APClass, 需要特性B,于是有了BPClass, 需要特性C,有了CPClass, 现在需要特性AB,可以定义子类ABPClass,这已经有了很多的子类了,如果我们还需要把这些特性任意的组合的话,这个子类就更加的复杂了。并且,我们在编译这个子类的时候,实例化了ABPClass, BPClass , PClass这三个类。于是, 功能就像是类的模板的一样,不同的功能不同的模板,极度不方便。

修饰模式解决的就是这样的问题,修饰类在PClass的基础可以直接添加特性A和B, 没有子类BPClass需要被实例化。并且调用PClass的实例也是在代码的运行时,这个就是动态的了。

 

请看下面的代码。代码源自wikipedia.

 

//接口,我们想要扩展的就是window类的功能
public interface Window {
	public void draw();
	public String getDescription();
}

 

//实现类
public class SimpleWindow implements Window {

	@Override
	public void draw() {
		System.out.println("draw window");
	}

	@Override
	public String getDescription() {
		return "Simple Window";
	}

}
//window的修饰类,这里使用的修饰方法为将window做参数传入构造方法中,这样的话,修饰类的子类可以动态的增加新的功能,也就是不需要编译时候就实例化window类了。
public abstract class WindowDecorator implements Window {
	protected Window decoratedWindow;
	
	public WindowDecorator(Window decoratedWindow){
		this.decoratedWindow = decoratedWindow;
	}
}

 

//修饰类的一个子类。为window类增加了新的方法 drawVScrollBar.
public class VScrollBarDecorator extends WindowDecorator {

	public VScrollBarDecorator(Window decoratedWindow) {
		super(decoratedWindow);
	}

	//这里可以看到window的功能方便的被扩展了,调用decoratedWindow.draw之前还可以增加其他的功能。并且在使用该方法的时候,才会去实例化window和decoratedWindow
	@Override
	public void draw() {
		drawVScrollBar();
		decoratedWindow.draw();
	}

	private void drawVScrollBar(){
		
	}
	
	@Override
	public String getDescription() {
		return decoratedWindow.getDescription() + "-- include vscorllbar";
	}

}
//另外一个增加了功能那个的类
public class HScrollBarDecorator extends WindowDecorator{

	public HScrollBarDecorator(Window decoratedWindow) {
		super(decoratedWindow);
	}

	@Override
	public void draw() {
		drawHScrollBar();
		decoratedWindow.draw();
	}

	private void drawHScrollBar(){
	}

	@Override
	public String getDescription() {
		return decoratedWindow.getDescription() + "--include hscrollbar";
	}

}

 

public class DecoratedWindowTest {
	
	public static void main(String[] args){
		//这里可以看到原来见到的SimpleWindow就有了HScrollbar和VScrollBar
		Window decoratedWindow = new HScrollBarDecorator(
				new VScrollBarDecorator(new SimpleWindow()));
		System.out.println(decoratedWindow.getDescription());
	}
	
}


上面的代码中,给SimpleWindow增加2个特性HScrollBar和VScrollBar。若是在用子类的情况下,那么就需要定义至少三个子类。但是在使用修饰模式的情况下, 新的特性只需要在实例化时当作参数传进去就可以了。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值