# 装饰者模式

今天在复习java的IO时，知道了Java的IO流使用了装饰器模式，它将IO流分成底层节点流和上层处理流。

## 1. 简介

装饰者模式(Decorator)的意图就是动态地给一个对象添加一些额外的职责。就新增功能来说，装饰者模式比生成子类更为灵活。有时，我们希望给每个对象而不是整个类添加一些功能，这个时候就需要用到装饰者模式了。

**装饰者模式具有以下特征：**

* 它必须具有一个装饰的对象；
* 它必须拥有与被装饰对象相同的接口；
* 它可以给被装饰的对象添加额外的功能；

总的来说就是：保持接口，增强性能。

## 2. 实例代码

现在我们用装饰者模式实现一个需求：当前系统下学生只有学习的能力，现在要给他增加运动和音乐的能力。

Person类

```java
package com.wangjun.designPattern.decorator;

public interface Person {
	public void function();
}
```

Student类

```java
package com.wangjun.designPattern.decorator;

public class Student implements Person {

	@Override
	public void function() {
		System.out.println("学生具有学习的能力。");
	}

}
```

装饰器1

```java
package com.wangjun.designPattern.decorator;

public class Decorator1 implements Person {
	
	private Person person;
	
	public Decorator1(Person person) {
		this.person = person;
	}

	@Override
	public void function() {
		System.out.println("装饰器1增加功能：体育能力。");
		person.function();
	}

}
```

装饰器2

```java
package com.wangjun.designPattern.decorator;

public class Decorator2 implements Person {
	
	private Person person;
	
	public Decorator2(Person person) {
		this.person = person;
	}

	@Override
	public void function() {
		System.out.println("装饰器2增加能力：音乐。");
		person.function();
	}

}
```

测试类

```java
package com.wangjun.designPattern.decorator;

public class App {
	public static void main(String[] args) {
		//原始对象
		Person person = new Student();
		
		//装饰类对象
		Person decorator = new Decorator2(new Decorator1(person));
		decorator.function();
	}
}
```

运行结果

```
装饰器2新增能力：音乐。
装饰器1增加功能：体育能力。
学生具有学习的能力。
```

从结果可以看出，使用装饰者模式增强了类的功能。

## 3. 装饰器模式与代理模式的区别

看到装饰器模式的功能和实现，很容易想到代理模式，也是这么实现的啊，功能类似。那这两种模式有什么区别呢？先来看一下两种模式的定义：

**装饰者模式：** 动态的将责任附加到被装饰者对象上，用于扩展对象的功能，是继承关系的替代方案。Java IO的设计即是装饰者模式的典型应用。

**代理模式：** 对其他对象进行代理，以控制对被代理对象的访问。Spring AOP是代理模型的一个典型应用。

二者的实现机制确实类似，可以看到两者的实现代码也有很多重复的地方。但是从作用上看，两种模式是相反的。其实设计模式的作用是为了让程序员更好的理解程序，在一个地方上写装饰模式，大家就知道你是在新增功能，在一个地方上写代理模式，大家就知道你是在控制对象的访问。

## 4. Java IO流实现装饰者模式
