设计模式——装饰模式

DECORATOR 装饰模式

 

1、 意图

动态地给一个对象添加一些额外的职责。就添加功能来说,Decorator模式就比生成子类更灵活。

2、 适用性

  • 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
  • 处理那些可以撤销的职责。
  • 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

3、 结构


4、 参与者

Component

——定义一个对象接口,可以给这些对象动态地添加职责。

ConcreteComponent

——定义一个对象,可以给这些对象添加一些职责。

Decorator

——维持一个指向Component对象的指针,并定义一个与Component接口一致的接口。

ConcreteDecorator

——向组件添加职责。

5、 协作

Decorator将请求转发给它的Component对象,并有可能在转发请求前后执行一些附加的动作。

6、 效果

Decorator模式至少有两个主要优点和两个缺点:

1)  比静态继承更灵活。与对象的静态继承(多重继承)相比,Decorator模式提供了更加灵活的向对象添加职责的方式。可以用添加和分离的方法,用装饰在运行时刻添加或删除职责。

2)  避免在层次结构高层的类有太多的特征。Decorator模式提供了一种“即用即付”的方法来添加职责。它并不试图在一个复杂的可定制的类中支持所有可预见的特征,相反,你可以定义一个简单的类,并且用Decorator类给它逐渐地添加功能。

3)  Decorator与它的Component不一样。Decorator是一个透明的包装。如果我们从对象标识的观点出发,一个被装饰了的组件与这个组件是有差别的,因此,使用装饰时不应该依赖对象标识。

4)  有很多的小对象。采用Decorator模式进行系统设计往往会产生许多看上去类似的小对象,这些对象仅仅在他们互相连接的方式上有所不同,而不是它们的类或是它们的属性值有所不同。

7、 实现

1)  接口的一致性。装饰对象的接口必须与它所装饰的Component的接口是一致的,因此,所有的ConcreteDecorator类必须有一个公共的父类。

2)  省略抽象的Decorator类;当你仅需要添加一个职责时,没有必要定义抽象Decorator类。

3)  保持Component类的简单性。为了保证接口的一致性,组件和装饰必须有一个公共的Component父类。因此保持这个类的简单性很重要;即,它应集中与定义接口而不是存储数据。

4)  改变对象外壳与改变对象内核;我们可以将Decorator看作一个对象的外壳,它可以改变对象的行为。另一种方法是改变对象的内核。

8、 代码示例

Component

package com.examples.pattern.decorator;

/**
 * 组件对象的接口,可以给这些对象动态地添加职责
 */
public abstract class Component {

	public abstract void operation();

}

ConcreteComponent

package com.examples.pattern.decorator;

/**
 * 具体实现组件对象接口的对象
 */
public class ConcreteComponent extends Component {

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

}

Decorator

package com.examples.pattern.decorator;

/**
 * 装饰器接口,维持一个指向组件对象的接口对象,并定义一个与组件接口一致的接口
 */
public abstract class Decorator extends Component {

	protected Component component;

	/**
	 * 构造方法,传入组件对象
	 * 
	 * @param component
	 *            组件对象
	 */
	public Decorator(Component component) {
		this.component = component;
	}

	@Override
	public void operation() {
		// 转发请求给组件对象,可以在转发前后执行一些附加动作
		component.operation();
	}

}

ConcreteDecorator

package com.examples.pattern.decorator;

/**
 * 装饰器的具体实现对象,向组件对象添加职责
 */
public class ConcreteDecoratorA extends Decorator {

	public ConcreteDecoratorA(Component component) {
		super(component);
	}

	/**
	 * 添加的状态
	 */
	private String addedState;

	public String getAddedState() {
		return addedState;
	}

	public void setAddedState(String addedState) {
		this.addedState = addedState;
	}

	public void operation() {
		super.operation();
		System.out.println("ConcreteDecoratorA :" + addedState);
	}

}
package com.examples.pattern.decorator;

/**
 * 装饰器的具体实现对象,向组件对象添加职责
 */
public class ConcreteDecoratorB extends Decorator {

	public ConcreteDecoratorB(Component component) {
		super(component);
	}

	/**
	 * 添加的状态
	 */
	private String addedState;

	public String getAddedState() {
		return addedState;
	}

	public void setAddedState(String addedState) {
		this.addedState = addedState;
	}

	public void operation() {
		super.operation();
		System.out.println("ConcreteDecoratorB :" + addedState);
	}

}
Client
package com.examples.pattern.decorator;

public class Client {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		ConcreteComponent cc = new ConcreteComponent();
		ConcreteDecoratorA cda = new ConcreteDecoratorA(cc);
		ConcreteDecoratorB cdb = new ConcreteDecoratorB(cc);

		cda.setAddedState("this is a");
		cdb.setAddedState("this is b");

		cda.operation();
		cdb.operation();

	}

}

9、 相关模式 

Adapter模式:Decorator模式不同于Adapter模式,因为装饰仅改变对象的职责而不改变它的接口;而适配器将给对象一个全新的接口。

Composite模式:可以将装饰视为一个退化的、仅有一个组件的组合。然而,装饰仅给对象添加一些额外的职责——它的目的不在于对象聚集。

Strategy模式:用一个装饰你可以改变对象的外表;而Strategy模式使得你可以改变对象的内核。这是改变对象的两种途径。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值