现在的位置: 首页 > 综合 > 正文

装饰模式

2013年02月06日 ⁄ 综合 ⁄ 共 2758字 ⁄ 字号 评论关闭

java IO中使用了一个非常重要的设计模式:装饰模式。装饰模式的使用是复杂的IO变得简单,免除了实现IO操作需要的繁琐操作。理解装饰模式对于正确使用IO很重要。下面是简单的装饰模式例子,从过程上阐释了装饰模式的内涵。

首先,需要了解什么是装饰模式:装饰模式(Decorator Pattern)又叫包装模式(Wrapper Pattern),它以对客户端透明的方式扩展对象的功能。是继承关系的一种替代方案。

换言之,装饰模式用一种另外的方式实现了继承这一面向对象编程的基本功能。也就是说,装饰模式可以在不创造更多子类的情况下,将对象的功能加以扩展。

我们知道,java IO中需要完成对不同输入输出源的操作,如果单纯的使用继承这一方式,无疑需要很多的类。比如说,我们操作文件需要一个类,实现文件的字节读取需要一个类,实现文件的字符读取又需要一个类....一次类推每个特定的操作都需要一个特定的类。这无疑会导致大量的IO继承类的出现。显然对于编程是很不利的。而是用装饰模式则可以很好的解决这一问题,在装饰模式中:节点流(如FileInputStream)直接与输入源交互,之后通过过滤流(FilterInputStream)进行装饰,这样获得的io对象便具有某几个的功能。很好的拓展了IO的功能。

装饰模式的角色:

1.抽象构建角色(Component)

给出一个抽象接口,以规范准备接受附加责任的对象。显然,从功能上看,这一角色对应IO操作中的InputStream/OuputStream这些底层的抽象类。

2.具体构建角色(Concrete Component)

定义一个将要接收附加责任类的对象。也就是实现了抽象构建角色的方法声明。它应该对应IO操作中的节点流,即直接与输入输出源交互的流。

3.装饰角色(Decorator)

持有一个构建(Component)的引用,并定义一个与抽象构件接口一致的接口。它应该对应IO操作中的装饰流(即FilterInputStream)。

4.具体装饰角色(Concrete Decorator)

负责给构件对象“贴上”附加的责任。也就是扩展构件对象的功能。它对应于IO中的具体过滤流,即FilteInpuStreamr的子类。

以下是一个简单演示装饰模式的代码:

首先是抽象构建角色(Component.java)

/**
 * 装饰模式:是继承关系的扩展,增加对象的功能。可以在不创造更多子类的情况下
 * 对类的功能进行扩展
 *装饰模式的角色:
 *1.抽象构件角色(对应于io中的InputStream)
 *2.具体构件角色(对应于Io中的节点流)
 *3.装饰角色(对应于IO中的FilterStream)
 *4.具体装饰角色(对应于IO中的装饰器)
 */
public interface Component
{
	public void doSomething();
	
}

然后是具体构建角色(ConcreteComponent.java),实现了抽象构件中的方法

public class ConcreteComponent implements Component
{

	@Override
	public void doSomething()
	{
		System.out.println("功能A");
	}
	
}

接着是装饰角色(Decorator.java)持有一个构建(Component)的引用,并定义一个与抽象构件接口一致的接口。即引用了ConcreteComponent.java中的doSomeThing()方法。

public class Decorator implements Component
{
	private Component component;
	public Decorator(Component component)
	{
		this.component = component;
	}
	@Override
	public void doSomething()
	{
		component.doSomething();
	}
	
}

最后是具体的装饰角色,即直接呈现给用户的装饰角色。这里构建了两个装饰角色(ConcreteDecorator1.java 和ConcreteDecorator2.java)
 ConcreteDecorator1.java 

public class ConcreteDecorator1 extends Decorator
{

	public ConcreteDecorator(Component component)
	{
		super(component);
	}
	@Override
	public void doSomething()
	{
		super.doSomething();
		this.doAnotherThing();
	}
	private void doAnotherThing()
	{
		System.out.println("功能B");
	}
	
}

ConcreteDecorator2.java

public class ConcreteDecorator2 extends Decorator
{

	public ConcreteDecorator1(Component component)
	{
		super(component);
		
	}
	@Override
	public void doSomething()
	{
		super.doSomething();
		this.doAnotherThing();
	}
	private void doAnotherThing()
	{
		System.out.println("功能C");
	}
	
}

现在我们测试一下:

public class Client
{
	public static void main(String[] args)
	{
		Component component = new ConcreteComponent();
		//相当于 InputStream stream = new FileInputStream("filepath");得到节点流
		Component component2 = new ConcreteDecorator(component);
		//相当于 InputStream stream2 = new BufferedInputStream(stream);过滤流装饰节点流
		Component component3 = new ConcreteDecorator1(component2);
		//相当于 InputStream stream3 = new DataInputStream(stream2);过滤流装饰过滤流
		component3.doSomething();
		//相当于 stream3.read();调用方法
	
	}
}

打印结果:

功能A
功能B
功能C

通过测试结果我们看出,三个类一个接口最终实现了对象功能的扩展。(调用了三个方法)。用另一种方式,实现了继承所能完成的功能。这就是装饰模式。

抱歉!评论已关闭.