概述
装饰者模式,不改变原有类的情况下,给一个类动态的增加方法
比如:A是超类,这个时候有个情况跟超类不一样,可以新建一个B类,继承B,C有些方法不一样,C继承B,甚至有D继承C,出现如下情况
D -> C -> B -> A
使用子类:通常可以使用继承来实现功能的拓展,如果这些需要拓展的功能的种类很繁多,那么势必生成很多子类,增加系统的复杂性,同时,使用继承实现功能拓展,我们必须可预见这些拓展功能,这些功能是编译时就确定了,是静态的。
使用装饰者模式
代码实例
中国女孩,黑头发,黄皮肤。。等等都是中国女孩的特性
美国女孩,金黄色头发,高
特性是动态的,可能是多个,不确定性
/**
* @Description 抽象类Gril
* @Date 2017/7/2 22:01
* @Since v1.7
* @Autor Nick
*/
public abstract class Girl {
String desc = "no particular";
public String getDesc() {
return desc;
}
}
创建中国女孩和美国女孩
/**
* @Description
* @Date 2017/7/2 22:04
* @Since v1.7
* @Autor Nick
*/
public class ChineseGirl extends Girl {
public ChineseGirl() {
desc = "+ChineseGirl";
}
}
/**
* @Description 美国Girl
* @Date 2017/7/2 22:02
* @Since v1.7
* @Autor Nick
*/
public class AmericanGril extends Girl {
public AmericanGril() {
desc = "+AmericanGril";
}
}
创建装饰者类
/**
* @Description 装饰者
* @Date 2017/7/2 22:06
* @Since v1.7
* @Autor Nick
*/
public abstract class GirlDesorator extends Girl {
public abstract String getDesc();
}
各种特征、优缺点等,里面是动态的,可以随时增加
/**
* @Description 黄头发
* @Date 2017/7/2 22:07
* @Since v1.7
* @Autor Nick
*/
public class GoldenHair extends GirlDesorator {
private Girl girl;
public GoldenHair(Girl girl) {
this.girl = girl;
}
@Override
public String getDesc() {
return girl.getDesc() + "+ with golden hair";
}
}
/**
* @Description 黑头发
* @Date 2017/7/21 22:26
* @Since v1.7
* @Autor Nick
*/
public class BlackHair extends GirlDesorator {
private Girl girl;
public BlackHair(Girl girl) {
this.girl = girl;
}
@Override
public String getDesc() {
return girl.getDesc() + "+ with black hair";
}
}
/**
* @Description 高
* @Date 2017/7/2 22:08
* @Since v1.7
* @Autor Nick
*/
public class Tall extends GirlDesorator {
private Girl girl;
public Tall(Girl girl) {
this.girl = girl;
}
@Override
public String getDesc() {
return girl.getDesc() + "+is very tall";
}
}
测试类
/**
* @Description 测试类
* 如果需要是美国女孩,只需要Girl g1 = new AmericanGril();
* @Date 2017/7/2 22:09
* @Since v1.7
* @Autor Nick
*/
public class MainTest {
public static void main(String[] args) {
Girl g1 = new ChineseGirl();
System.out.println(g1.getDesc());
BlackHair g2 = new BlackHair(g1);
System.out.println(g2.getDesc());
Tall g3 = new Tall(g2);
System.out.println(g3.getDesc());
}
}
装饰模式 VS 继承
装饰模式 | 继承 |
---|---|
用来扩展特定对象的功能 | 用来扩展一类对象的功能 |
不需要子类 | 需要子类 |
动态地 | 静态地 |
运行时分配职责 | 编译时分派职责 |
防止由于子类而导致的复杂和混乱 | 导致很多子类产生,在一些场合,报漏类的层次 |
更多的灵活性 | 缺乏灵活性 |
对于一个给定的对象,同时可能有不同的装饰对象,客户端可以通过它的需要选择合适的装饰对象发送消息 | 对于所有可能的联合,客户期望很容易增加任何的 困难 |