装饰模式又名包装(Wrapper)模式,以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。


装饰模式的角色包含如下:

1)抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。

2)具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。

3)装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。

4)具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。


定义通用接口,代码如下:

package com.yoodb;

public interface Job {
	/**
	 * 准备工作,以老鼠、猫、狗三种动物,做饭的小故事为例
	 */
	public void prepare();
	
}


老鼠工作内容,代码如下:

package com.yoodb;

public class Mouse implements Job{

	@Override
	public void prepare() {
		// TODO Auto-generated method stub
		System.out.println("老鼠用锅盛满了水.\n");
	}
	
}


小猫工作内容,代码如下:

package com.yoodb;

public class Cat implements Job{
	//被装饰者
	private Job job;

	public Cat() {}

	public Cat(Job job) {
		this.job = job;
	}

	@Override
	public void prepare() {
		// TODO Auto-generated method stub
		//装饰者职责
		System.out.println("小猫正在准备柴进行点火工作.\n");
		//被装饰者职责
		job.prepare();
		//装饰者职责
		System.out.println("小猫将锅上架并把火点着了.\n");
	}

}


小狗工作内容,代码如下:

package com.yoodb;

public class Dag implements Job{

	private Job job;
	
	public Dag(Job job) {
		this.job = job;
	}

	public Dag() {}

	@Override
	public void prepare() {
		// TODO Auto-generated method stub
		//装饰者做的职责
		System.out.println("小狗正在做食材的准备工作\n");
		///被装饰者职责
		job.prepare();
		//装饰者做的职责
		System.out.println("小狗已把食材准备成功,放入锅中!\n");
	}
}


测试Main,代码如下:

package com.yoodb;

public class DecoratorMain {

	public static void main(String[] args) {
		Job mouse = new Mouse();
		mouse.prepare();
		Job cat = new Cat(mouse);
		cat.prepare();
		Job dag = new Dag(cat);
		dag.prepare();
	}
	
}


输出结果如下:

老鼠用锅盛满了水.

小猫正在准备柴进行点火工作.

老鼠用锅盛满了水.

小猫将锅上架并把火点着了.

小狗正在做食材的准备工作

小猫正在准备柴进行点火工作.

老鼠用锅盛满了水.

小猫将锅上架并把火点着了.

小狗已把食材准备成功,放入锅中!


装饰模式的优点:

1)装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。装饰模式允许系统动态决定“贴上”一个需要的“装饰”,或者除掉一个不需要的“装饰”。继承关系则不同,继承关系是静态的,它在系统运行前就决定了。

2)通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。


装饰模式的缺点:

由于使用装饰模式,可以比使用继承关系需要较少数目的类。使用较少的类,当然使设计比较易于进行。但是,在另一方面,使用装饰模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难,特别是这些对象看上去都很相像。

评论

分享:

支付宝

微信