装饰者模式(Decorator Pattern)(一):装饰者模式介绍

一、意图


装饰者模式(又称装饰模式、包装(Wrapper)模式):动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。



二、适用性


以下情况使用Decorator模式(摘自《设计模式》):

• 在不影响其他对象的情况下,以动态透明的方式给单个对象添加职责。

• 处理那些可以撤消的职责。

• 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。


三、组成


——抽象构件角色(Component)

给出一个个抽象接口,以规范准备接收附加责任的对象。是被装饰类和装饰类的父接口。


——具体构建角色(Concrete Component)

定义一个将要接受附加责任的类,即被装饰的类。


——装饰角色(Decorator)

装饰者,持有一个构件(Component)对象的引用,并定义一个与抽象构件接口一致的接口。


——具体装饰角色(Concrete Decorator)

具体装饰者,负责给构件对象“贴上”附加的责任(扩展功能)



四、结构


装饰者模式(Decorator Pattern)(一):装饰者模式介绍_第1张图片


五、简单实现


1.抽象构件角色

public interface Component
{
  public void doSomething();
}


2.具体构件角色

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

(具体构件可以单独使用)


3.装饰者角色

public class Decorator implements Component
{
	//持有一个Component类型的引用,可以包装具体构件或装饰者(只要实现了Component接口)
	Component component;
	public Decorator(Component component)
	{
		this.component=component;
	}
	@Override
	public void doSomething()
	{
		this.component.doSomething();
	}
}

4.具体装饰者


(1)具体装饰者A

public class ConcreteDecoratorA extends Decorator
{
	public ConcreteDecoratorA(Component component)
	{
		super(component);
	}
	
	@Override
	public void doSomething()
	{
		super.doSomething();
		this.doAnotherThing();
	}

	public void doAnotherThing()
	{
		System.out.println("功能 B");
	}
}

(2)具体装饰者B

public class ConcreteDecoratorB extends Decorator
{

	public ConcreteDecoratorB(Component component)
	{
		super(component);
	}
	
	@Override
	public void doSomething()
	{
		this.doAnotherThing();
		super.doSomething();

	}

	public void doAnotherThing()
	{
		System.out.println("功能 C");
	}
}

5.客户端测试

public class Client
{
	public static void main(String[] args)
	{
		//具体构件
		Component component = new ConcreteComponent();

		// 具体装饰者装饰具体构件
		Component decorator = new ConcreteDecoratorA(component);
		decorator.doSomething();

		// 具体装饰者可以装饰具体装饰者(实际上它并不知道)
		Component decorator2 = new ConcreteDecoratorB(decorator);
		decorator2.doSomething();
	}
}

六、设计原则


设计原则:类应该对扩展开放,对修改关闭。


装饰者模式完全遵循开放-关闭原则,装饰者可以在被装饰者的行为之前或之后,加上自己的行为,以达到特定的目的(此即扩展),并且不用修改被装饰者的代码(此即关闭)。这样使得所设计的系统更具有弹性,可以接受新的功能来应付变化的需求。



七、Java I/O中的装饰者模式


装饰者模式(Decorator Pattern)(一):装饰者模式介绍_第2张图片


对于java.io.OutputStream、java.io.Reader和java.io.writer也是如此



八、其他



1.装饰者和被装饰者对象具有相同的超类型,所以在任何使用被装饰者对象的场合,可以用装饰过的对象来代替它。(所以装饰者类反映出被装饰的组件的类型)


2.装饰者不仅可以装饰具体构件,还可以装饰装饰者。


3.装饰者和被装饰者都继承(或实现)自相同的超类型(Component),我们是利用继承达到“类型匹配”,而不是利用继承获得“行为”。当我们将装饰者与组件(或装饰者)组合时,加入的新的行为并不是继承自超类,而是由组合对象(ConcreteComponent或ConcreteDecorator)得来的。


4.虽然装饰者模式可以为设计注入弹性,但装饰者也常常造成设计中有大量的小对象,如果过度使用会让程序变得很复杂。


5.装饰模式VS继承:装饰模式是使用组合和委托用来扩展特定对象的功能,不需要子类,动态地在运行时给对象加上新的行为,防止了由于子类而导致的复杂和混乱,具有更多的灵活性。而继承是用来扩展一类对象的功能,需要子类,静态地在编译时分派职责,导致了很多子类的产生,缺乏灵活性。


6.装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型


7.Decorator装饰者角色并不是必须的,当你仅需要添加一个职责时,没有必要定义抽象Decorator类。你常常需要处理现存的类层次结构而不是设计一个新系统,这时你可以把Decorator向Component转发请求的职责合并到Concrete Decorator中。


8.改变对象外壳与改变对象内核:我们可以将Decorator看作一个对象的外壳,它可以改变这个对象的行为。另外一种方法是改变对象的内核。例如, Strategy(策略)模式就是一个用于改变内核的很好的模式。


转载请注明出处:http://blog.csdn.net/jialinqiang/article/details/8881855

你可能感兴趣的:(设计模式)