23个java设计模式(三)-- 装饰模式

2016年03月08日 原创
关键词: java 设计模式
摘要 装饰模式就是动态地给对象添加一些额外的职责,就功能来说装饰模式相比生成子类更为灵活。

一、概述。

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

装饰模式是动态地扩展一个对象的功能,而不需要改变原始类代码的一种成熟模式。

简单的说,在装饰模式中,“被装饰者”的引用被“装饰者”包含,因此“装饰者”可以动态的装饰“被装饰者”。

二、装饰模式的结构。

装饰模式的结构中包括四种角色。

  • 抽象组件(Component):抽象组件是一个抽象类。抽象组件定义了“被装饰者”需要进行“装饰”的方法。
  • 具体组件(ConcreteComponent):具体组件是抽象组件的一个子类,具体组件的实例称作“被装饰者”。
  • 装饰(Decorator):装饰也是抽象组件的一个子类,但装饰还包含一个抽象组件声明的变量以保存“被装饰者”的引用。装饰可以是抽象类也可以是一个非抽象类,如果是非抽象类,那么该类的实例称作“装饰者”。
  • 具体装饰(ConcreteDecorator):具体装饰是装饰的一个非抽象子类,具体装饰的实例称作“装饰者”。

三、一个简单的例子。

比如说有一个麻雀类,该类有一个fly()方法可以飞100米远。现在需要让麻雀可以飞150米,200米远。我们就可以用装饰模式来实现。

抽象组件

public abstract class Bird {
	public abstract int fly();
}

具体组件

public class Sparrow extends Bird{
	public final int DISTANCE = 100;
	@Override
	public int fly() {
		return DISTANCE;
	}

}

装饰

public abstract class Decorator extends Bird{
	protected Bird bird;

	public Decorator(Bird bird) {
		this.bird = bird;
	}

	public Decorator() {
		super();
	}
	
}

具体装饰

public class SparrowDecorator extends Decorator{
	public final int DISTANCE = 50;
	
	public SparrowDecorator() {
		super();
	}

	public SparrowDecorator(Bird bird) {
		super(bird);
	}

	@Override
	public int fly() {
		return bird.fly()+DISTANCE;
	}
}

测试代码

public class Example1Test {
	public void showBird(Bird bird) {
		System.out.println("这只鸟能飞行"+bird.fly()+"米");
	}
	@Test
	public void testMain() {
		Bird sparrow = new Sparrow();
		Bird sparrowDecorator1 = new SparrowDecorator(sparrow);
		Bird sparrowDecorator2 = new SparrowDecorator(sparrowDecorator1);
		showBird(sparrow);
		showBird(sparrowDecorator1);
		showBird(sparrowDecorator2);
	}
}

四、装饰模式的优点。

  1. 被装饰者和装饰者是松耦合关系。由于装饰(Decorator)仅仅是依赖于抽象组件(Component),因此具体装饰只知道它要装饰的对象是抽象组件某一个子类的实例,但不知道是哪一个具体子类。
  2. 装饰模式满足“开-闭原则”。不必修改具体组件,就可以增加新的针对该具体组件的具体装饰。
  3. 可以使用多个具体装饰来装饰具体组件的实例。

五、适合使用装饰模式的情景。

  1. 程序希望动态地增强类的某个对象的功能,而又不影响到该类的其他对象。
  2. 采用继承来增强对象功能不利于系统的扩展和维护。

 

更多的例子程序可以查看博主的github  https://github.com/cxylpy/design-patterns.git