标签:java设计模式—–实验楼
什么是装饰者模式(decorator)
也就是动态地把职责附加到已有对象上去,实现功能扩展。这种特性,使得装饰者模式提供了比继承更具有弹性的解决方案,说到加在已有对象上,肯定包括强行装
装饰者模式的实例代码
情景:假如一辆车上有两种女孩,你要一一进行记录每个女孩的特点。主要分为中国女孩和美国女孩这两种。因为我们的目的是要记录每一位女孩的特点,但是一个女孩子一个单独的类实在是做不到,懒惰即是美德。我们的策略是:
先将女孩子大致分为两类,然后再新建很多的特点(类,身高,体重。头发等等),哪位女孩符合什么样的特点,直接进行标记添加,确实省了不少的力
//先来个总类,车上的都是女孩,将这个类供子类使用,虽然没有给方法,但是子类可以使用字段
public abstract class Girl {
String description = "no particular";
public String getDescription() {
return description;
}
}
//下面将女孩分为两大类,一种是美国的,一种是国产的(贴个标签)
public class AmericanGirl extends Girl {
public AmericanGirl() {
description = "+AmericanGirl";
}
}
public class ChineseGirl extends Girl {
public ChineseGirl() {
description = "+ChineseGirl";
}
}
//下面就写一些特点类加在女孩上(不管是美国还是中国都是可以加,因此我们对总类下手,相当于泛型)写个装饰器,专门用来添加,实际上装饰器的原理什么的就是在这里了,可以在这里添加无限多的动作或者特点(属性),当然其实我认为这里不用写这个DecoratorGirl类,直接在Girl中就抽象方法,直接继承Gril也是正确的方式,但是不是为了教学,便于大家看懂装饰者模式嘛。
public abstract class DecoratorGirl extends Girl {
public abstract String getDescription();
}
//下面来个金发特质专供,中国或者美国女孩都可以拥有的标签(特质)
public class GoldenHair extends DecoratorGirl {
private Girl girl;
public GoldenHair(Girl g) {
// TODO Auto-generated constructor stub
girl = g;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return girl.getDescription() + "+with golden hair ";
}
}
//再来个身高考核
public class Tall extends DecoratorGirl {
private Girl girl;
public Tall(Girl g) {
this.girl = g;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return girl.getDescription() + "+is very tall";
}
}
//特质就简单的加这么几种了,下面我们请出一位美国女孩,我们打上标签
public class Main {
public static void main(String[] args) {
Girl girl1 = new AmericanGirl();
System.out.println(girl1.getDescription());
GoldenHair girl2 = new GoldenHair(girl1);
System.out.println(girl2.getDescription());
Tall girl3 = new Tall(girl2);
System.out.println(girl3.getDescription());
}
}
金发高挑的美国女孩就是了
装饰器模式应用
当你需要动态地给一个对象添加功能,实现功能扩展的时候,就可以使用装饰者模式
当然Java IO类中有一个经典的装饰者模式的应用,BufferedReader 装饰 InputStreamReader
BufferedReader input=new BufferedReader(new InputStreamReader(System.in)
以前只是知道装饰这么使用,没想到是装饰者模式
- InputStreamReader(inputStream in) 读取dytes字节内容,然后转换成characters流输出
- BufferedReader(Reader in) 从characters 流中读取内容并缓存
(InputStreamReader就是传说中的适配器类,把字节流转换成字符流)
适配器模式与装饰者模式的区别
- 关于新职责:适配器也可以在转换的时候增加新的职责,但其主要目的并不是在这。而装饰者模式主要目的就是给装饰者增加新的职责
- 关于原接口:适配器模式是用新接口来调用原接口,原接口对新系统来说是不可见或者说是不可用的;而装饰者模式原封不动的使用原接口,系统对装饰者的对象也还是通过原接口来完成使用。
- 关于其包裹的对象:适配器是知道包裹对象被适配者的详细情况的,而装饰者只是知道接口是什么,至于其具体类型(是基类还是派生类)只有在运行的时候才知道。