【设计模式】学习笔记3:装饰者模式(Decorator )

本文出自 http://blog.csdn.net/shuangde800

 

认识装饰者模式

在星巴克购买咖啡时,可以根据自己的要求,加入各种调料,例如:蒸奶、豆浆、摩卡或覆盖奶泡。星巴克会根据所加入的调料收取不同的费用。

如何设计这个类?

用装饰者模式,我们将以饮料为主体,然后再运行时以各种调料来“装饰”饮料。比如说,顾客想要摩卡和奶泡深焙咖啡:

1、拿一杯深焙咖啡作为主体对象

2、以摩卡对象装饰它

3、以奶泡对象装饰它

4、调用cost方法计算出总价钱。

定义装饰者模式

装饰者模式是动态地将责任附加到对象上。若要拓展功能,装饰者模式提供了比继承更有弹性的替代方案。

类图

用装饰者模式的Java I/O:

java中的I/O的设计中大量的用到了装饰模式
 
BufferedInputStream 及LineNumberInputStream都拓展自FilterInputStream,而FilterInputStream是一个抽象的装饰类
 
 
装饰java.io类
 
“输出流”的设计方式也是一样的。
 
 
 
编写自己的Java I/O装饰者:
 
编一个装饰者,把输入流内的所有大写字符转成小写、
 
 


 
 
package headfirst.decorator.io;

import java.io.*;

public class LowerCaseInputStream extends FilterInputStream {

	public LowerCaseInputStream(InputStream in) {
		super(in);
	}
 
	public int read() throws IOException {
		int c = super.read();
		return (c == -1 ? c : Character.toLowerCase((char)c));
	}
		
	public int read(byte[] b, int offset, int len) throws IOException {
		int result = super.read(b, offset, len);
		for (int i = offset; i < offset+result; i++) {
			b[i] = (byte)Character.toLowerCase((char)b[i]);
		}
		return result;
	}
}


 
 
测试类:
package headfirst.decorator.io;

import java.io.*;

public class InputTest {
	public static void main(String[] args) throws IOException {
		int c;

		try {
			InputStream in = 
				new LowerCaseInputStream(
					new BufferedInputStream(
						new FileInputStream("test.txt")));

			while((c = in.read()) >= 0) {
				System.out.print((char)c);
			}

			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


缺点

但是Java I/O也引出装饰者模式的一个“缺点”:利用装饰者模式,常常照成设计中有大量的小类,数量是在是太多,可能会照成使用此API程序员的困扰。
但是,了解了装饰者的工作原理,以后使用别人的大量装饰的API时,就可以很容易地辨识出他们的装饰者类是如何组织的,以方便用包装方式取得想要的行为。
 
 
 

设计原则

开放-关闭原则:类应该对拓展开放,对修改关闭

设计的目标是允许类容易拓展,在不修改现有代码的情况下,就可搭配新的行为。

 
 

猜你喜欢

转载自shangxun.iteye.com/blog/1937584