白话设计模式_装饰者模式

  装饰者模式,见名知意。装饰装饰,何为装饰,无非就是在某个东西上外面再套一层东西,装饰者模式大概就是这样的。

 

   比如现在有一个类A,我们想为它增加一些新的功能,但又不想修改它原来的代码,怎么办?直接的想法是继承,但继承灵活性并不好,推荐多用组合,少用继承。

  应用组合:新建一个类B(装饰者),把A(被装饰者)组合到B中,就可以让B行使A的职能,但应该注意两点:

  一、A和B应该有相同的超类或接口,这样才能够利用多态在使用A的地方使用B,我们采用继承,让B继承自A。

  二、让B继承自A并不是为了继承A类中的方法,而仅仅是声明一个共同的类型,使得在外人看来,A和B是一样的。

上例子:

     这是被装饰者

public class Obj {
	public void doSth(){
		System.out.print("i do sth.");
	}
	public void doSthElse(){
		System.out.print("i do sth else.");
	}
}

        现在,我们要扩展它的功能,使得Obj实例在执行doSth()方法时,在后面添加执行时间,而在执行doSthElse()时,在后面添加执行地点。

 这是装饰者:

public class DecoraterObj extends Obj {
	private Obj obj;
	
	public DecoraterObj(Obj obj){
		this.obj = obj;
	}
	public void doSth() {
		obj.doSth();
		System.out.println(" at " + new Date());
	}
	public void doSthElse() {
		obj.doSthElse();
		System.out.println(" at somewhere.");
	}
}

        装饰者DecoraterObj继承自被装饰者Obj,故二者拥有相同的对外“接口”,我们本来要使用Obj的地方,现在可以直接使用DecoraterObj了,而且就像在使用Obj一样,因为DecoraterObj中组合了一个Obj引用,它提供了原来Obj的功能,唯一不同的是,我们可以在DecoraterObj中对原Obj进行扩展,可以随意在它之前或之后添加功能。

   测试:

public class Main {
	public static void main(String[] args) {
		Obj obj = new DecoraterObj(new Obj());
		
		obj.doSth();
		obj.doSthElse();
	}
}

  就这样,我们看起来在使用Obj,其实我们已经在它外面又包装了一层。

  这个是不是很眼熟?装饰者模式在java I/O中用得非常多,所以我们经常可以看到比如以下代码:

new InputStreamReader(new ButteredInputStream(new InputStream()))

      InputStream类提供最简单的二进制读取,外面包装一层BufferedInputStream,提供缓冲功能,然后外面再包装一层InputStremReader,提供以字符方式读取功能。

  总结:

  装饰者模式的关键在于:统一对外“接口”、多态调用。

猜你喜欢

转载自tgw.iteye.com/blog/1672884