设计模式《装饰模式》

引言

  继续上一节的外观模式,我们在来说装饰模式。

示例地址

  Demo

类图

image

定义

  动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。

使用场景

  需要透明且动态地扩展的功能时。

装饰模式角色介绍

  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. 缺点:
    产生很多小对象。大量小对象占据内存,一定程度上影响性能
    装饰模式易于出错,调试排查比较麻烦

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容