引言
继续上一节的外观模式,我们在来说装饰模式。
示例地址
类图
定义
动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。
使用场景
需要透明且动态地扩展的功能时。
装饰模式角色介绍
1. Component:抽象组件,被装饰的原始对象。
2. ConcreteComponent: 组件具体实现类。装饰的具体对象。
3. Decorator:抽象的装饰者,用来装饰组件的。一般是为抽象类。如果装饰单一,该类可直接作为具体的装饰者。
4. ConcreteDecoratorA:装饰者具体实现类。
装饰模式示例
最近帮别人买了手机。然后他自己贴了一个钢化膜,买了一个手机外壳,加上一个吊坠,格外的珍惜。不过比之前漂亮了不少。突然发现这是典型的装饰模式啊。
1. 定义手机接口
/**
* 手机
*
* @author 512573717@qq.com
* @created 2018/7/25 下午5:30.
*/
public interface IPhone {
//装饰
void decorate();
}
2. 实现手机接口(被装饰的对象 华为手机)
/**
* 华为手机
*
* @author 512573717@qq.com
* @created 2018/7/26 下午1:59.
*/
public class HuaWeiPhone implements IPhone{
@Override
public void decorate() {
System.out.println("华为手机");
}
}
3. 装饰者(外壳)
/**
* 外壳
*
* @author 512573717@qq.com
* @created 2018/7/26 下午2:01.
*/
public abstract class Shell implements IPhone {
private IPhone mHuaWeiPhone;
public Shell(IPhone huaWeiPhone) {
mHuaWeiPhone = huaWeiPhone;
}
@Override
public void decorate() {
mHuaWeiPhone.decorate();
}
}
4. 粉红色的外壳加挂坠
/**
* 红色的外壳
*
* @author 512573717@qq.com
* @created 2018/7/26 下午2:05.
*/
public class RedShell extends Shell {
public RedShell(IPhone huaWeiPhone) {
super(huaWeiPhone);
}
public void shell() {
System.out.println("粉红色外壳");
}
public void pendant() {
System.out.println("小猪佩奇挂件");
}
@Override
public void decorate() {
super.decorate();
shell();
pendant();
}
}
5. 装饰者(贴膜)
/**
* 手机贴膜
*
* @author 512573717@qq.com
* @created 2018/7/26 下午2:17.
*/
public abstract class Membrane implements IPhone {
private IPhone mHuaWeiPhone;
public Membrane(IPhone huaWeiPhone) {
mHuaWeiPhone = huaWeiPhone;
}
@Override
public void decorate() {
mHuaWeiPhone.decorate();
}
}
6. 贴钢化膜
/**
* 钢化膜
*
* @author 512573717@qq.com
* @created 2018/7/26 下午2:22.
*/
public class TemperingMembrane extends Membrane {
public TemperingMembrane(IPhone huaWeiPhone) {
super(huaWeiPhone);
}
public void pasting() {
System.out.println("蓝光钢化膜");
}
@Override
public void decorate() {
super.decorate();
pasting();
}
}
7. Client
IPhone phone = new HuaWeiPhone();
System.out.println("装饰外壳");
RedShell redShell = new RedShell(phone);
redShell.decorate();
System.out.println("手机贴膜");
TemperingMembrane temperingMembrane = new TemperingMembrane(redShell);
temperingMembrane.decorate();
总结
装饰模式降低系统的耦合度,可以动态的增加或删除对象的职责,并使得需要装饰的具体构建类和具体装饰类可以独立变化,以便增加新的具体构建类和具体装饰类。
1. 优点:
扩展对象功能,比继承灵活,不会导致类个数急剧增加
可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象
具体构建类和具体装饰类可以独立变化,用户可以根据需要自己增加新的具体构件子类和具体装饰子类
2. 缺点:
产生很多小对象。大量小对象占据内存,一定程度上影响性能
装饰模式易于出错,调试排查比较麻烦