装饰器模式
装饰器模式就是动态地给一个对象添加一些额外的职责,扩展对象的功能.对于增加功能来说,装饰器模式比生成子类更为灵活.
装饰器模式的结构
通常来说,给一个对象添加一些额外的功能,可以通过继承来实现,但是这并不能动态地给对象添加职责,如果要添加一些职责,只能改变原有对象. 这时候就需要有装饰器模式出现了. 装饰器模式并不是利用继承和多态来扩展和复用功能,是基于对象组合的方式 .
装饰器模式的角色有:
- 抽象的对象角色 给出一个抽象接口,以规范准备接受附加功能的对象
- 具体的被装饰者 一个将要接受附加功能的具体实现,就是被装饰者,需要实现抽象的对象接口
- 装饰抽象类 持有一个被装饰者的实例,并实现抽象对象接口,为具体的装饰功能提供一个统一的接口
- 具体装饰角色 就是具体的装饰对象,继承子装饰抽象类,是用来给被装饰者添加附加功能的.
看类图:
装饰对象和被装饰对象实现的都是同一个接口,装饰对象也可以是一个接口,下面还可以有更多的具体的装饰对象.通过调用一个方法来装饰被装饰对象,以此来添加新的功能附件.
实例
比如我们现在要实现一个给人动态添加服装的功能.
首先定义一个接口,就是被装饰者实现的接口 里面有一个方法就是为人动态添加衣服1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18public abstract class Person {
private String name ;
private String sex;
protected String getSex() {
return sex;
}
protected void setSex(String sex) {
this.sex = sex;
}
protected String getName() {
return name;
}
protected void setName(String name) {
this.name = name;
}
public abstract void show();
}
接着实现具体要穿衣服的人1
2
3
4
5
6
7
8
9
10
11
12public class Man extends Person {
public Man(String name, String sex) {
super.setName(name);
super.setSex(sex);
}
public void show() {
System.out.println("装扮"+getName()+getSex());
}
}
在实现装饰抽象类 定义一个统一的装饰接口1
2
3
4
5
6
7
8
9
10
11
12
13
14public abstract class Decorator extends Person {
protected Person person;
public void decorator(Person person){
this.person = person;
}
public void show() {
if(person != null){
person.show();
}
}
}
具体装饰实现类1
2
3
4
5
6
7
8
9
10
11
12
13
14public class TShirts extends Decorator {
public void show() {
System.out.println("穿T恤");
super.show();
}
}
public class Shorts extends Decorator {
public void show() {
System.out.println("穿短裤");
super.show();
}
}
测试:
1 | public class Test { |
这个例子中每一个装饰对象都会调用自己装饰的那个对象,这个样子其实有点像责任链模式,不过责任链是将消息传递出去,而装饰模式是修饰已经已有的对象,一层一层的装饰.为对象动态的添加功能,最后形成一个完整的有用的对象.
在java中 输出输入流就是使用到了装饰器模式,在java中我们经常能见到这种写法.比如:1
2
3InputStream in = new FileInputStream("文件1");
BufferedInputStream bfi = new BufferedInputStream(in);
DataInputStream dis = new DataInputStream(bfi);
在这中写法中应该能够看出来这就是应用了装饰器模式,所有的这些输入流都继承InputStream类,通过一层一层的包装,来为输入流添加不同的功能.而他们每个类都有着上一层的一个实例对象,通过对此实例对象进行包装,就能够添加想要的功能.