【装饰者模式】重构代码 - 记一次装饰者模式的运用

背景

小七的朋友最近有一个烦恼,他想在不改变原有对象的基础上,将功能附加到对象上,问我有没有什么解决方案。小七第一个想到的就是继承和装饰者模式,因为装饰者模式相对继承来说,可以动态的给一个对象添加功能,并且这些功能还可以动态的撤销。

思考过程

假设我们我们有一个平板,它有描述和成本两个属性:

抽象的平板类

public abstract class AbstractTablet {
    /**
     * 描述
     *
     * @return {@link String}
     */
    protected abstract String getDesc();
    /**
     * 成本
     *
     * @return int
     */
    protected abstract int cost();
}

实际的平板类

public class Tablet extends AbstractTablet {
    /**
     * 描述
     *
     * @return {@link String}
     */
    @Override
    protected String getDesc() {
        return "平板电脑";
    }
    
    /**
     * 成本
     *
     * @return int
     */
    @Override
    protected int cost() {
        return 1200;
    }
}

然后我们构造一个顶级装饰者 - 平板电脑装饰者,这里有个关键点需要将自己继承的父类通过组合的方式变为自己的属性。

public class TabletDecorator extends AbstractTablet {
    /**
     * 关键点一:将自己的父类,组合成自己的属性
     */
    private AbstractTablet abstractTablet;
    public TabletDecorator(AbstractTablet abstractTablet) {
        this.abstractTablet = abstractTablet;
    }
    @Override
    protected String getDesc() {
        return abstractTablet.getDesc();
    }
    @Override
    protected int cost() {
        return abstractTablet.cost();
    }
}

具体装饰者一 - 是否可以插SIM卡,这个类需要继承顶级装饰者,并拓展自己的方法

public class TabletSimDecorator extends TabletDecorator {
    /**
     * 关键点二:子类装饰者调用父类装饰者的构造方法
     *
     * @param abstractTablet 抽象的平板电脑
     */
    public TabletSimDecorator(AbstractTablet abstractTablet) {
        super(abstractTablet);
    }
    /**
     * 关键点三:子类装饰者拓展自己的方法
     *
     * @return {@link String}
     */
    @Override
    protected String getDesc() {
        return super.getDesc() + " 可以插SIM卡";
    }
    /**
     * 关键点三:子类装饰者拓展自己的方法
     *
     * @return int
     */
    @Override
    protected int cost() {
        return super.cost() + 1000;
    }
}

具体装饰者二 - 是否可以拓展内存,这个类也需要继承顶级装饰者,并拓展自己的方法

public class TabletRomDecorator extends TabletDecorator{
    /**
     * 关键点二:子类装饰者调用父类装饰者的构造方法
     *
     * @param abstractTablet 抽象的平板电脑
     */
    public TabletRomDecorator(AbstractTablet abstractTablet) {
        super(abstractTablet);
    }
    /**
     * 关键点三:子类装饰者拓展自己的方法
     *
     * @return {@link String}
     */
    @Override
    protected String getDesc() {
        return super.getDesc() + " 可以拓展内存";
    }
    /**
     * 关键点三:子类装饰者拓展自己的方法
     *
     * @return int
     */
    @Override
    protected int cost() {
        return super.cost() + 1000;
    }
}

测试类:

public class Test {
    public static void main(String[]args){
        AbstractTablet abstractTablet;
        abstractTablet = new Tablet();
        abstractTablet = new TabletSimDecorator(abstractTablet);
        abstractTablet = new TabletRomDecorator(abstractTablet);
        System.out.println(abstractTablet.getDesc() + ":" + abstractTablet.cost());
    }
}

结果:

图片

URL类图

图片

总结

其实装饰者模式很简单,在jdk和开源框架里面也应用得比较广泛,比如说我们最常见的有IO的操作。以BufferedReader为例

图片

图片

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

第七人格

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值