设计模式第三讲-装饰者模式

栏目: 后端 · 发布时间: 5年前

内容简介:装饰模式也算一种比较常见的设计模式,工作过程中很少刻意的去实现这种模式,因为这种模式也会带来一些问题。比如小类太多,组织起来比较麻烦,对客户端完全可见,如果不了解各个类的功能会很乱等等当然也有很多优点: 可以动态的给类增加一些职责,增加功能更加灵活,比起继承来说也更加具有弹性

装饰模式也算一种比较常见的设计模式,工作过程中很少刻意的去实现这种模式,因为这种模式也会带来一些问题。

比如小类太多,组织起来比较麻烦,对客户端完全可见,如果不了解各个类的功能会很乱等等

当然也有很多优点: 可以动态的给类增加一些职责,增加功能更加灵活,比起继承来说也更加具有弹性

下面我们来看看它究竟是什么样子的

场景设置

以买车业务模型为例(本人未买过车,业务场景纯属臆想)

车里面还有很多装备可以选择,根据不同的选择装饰决定最后到手的价格:

商品 价格
裸车 100000
加热座椅(可选) 4000
真皮内饰(可选) 8000
蹦迪音响(可选) 5000

第一版本实现(我们在一个类里面完成)

package car;

public class Car {

    //总价
    private int allPrice = 0;

    //裸车价格 --实际数值从数据库查询,此处略
    private int nakedPrice = 100000;

    //加热座椅
    private int heatedSeat = 4000;

    //真皮内饰
    private int dermalInteriors = 8000;

    //蹦迪音响
    private int bengdiSound = 5000;


    public Car() {
        this.allPrice += this.nakedPrice;
    }

    /**
     * 添加真皮座椅
     */
    public void addHeatedSeat() {
        this.allPrice += this.heatedSeat;
    }

    /**
     * 添加真皮内饰
     */
    public void addDermalInteriors() {
        this.allPrice += this.dermalInteriors;
    }

    /**
     * 添加蹦迪音响
     */
    public void addBengdiSound() {
        this.allPrice += this.bengdiSound;
    }

    /**
     * 获取总价
     *
     * @return
     */
    public int cost() {
        return this.allPrice;
    }

}

复制代码

客户端调用:

package car;

public class Main {

    public static void main(String[] args) {

        Car car = new Car();

        car.addBengdiSound();
        System.out.println("总花费价格:" + car.cost());

    }

}

复制代码

output:

花费价格105000
复制代码

看起来很简洁呢,并且也很好的实现了功能

首先这是我们的场景足够的简单,所涉及的配套组件也比较少,实际中可能针对某个方法可能有很复杂的获取和计算逻辑,组件也会有很多种选择,会造成类爆炸,无法继续维护下去

如果我们使用装饰模式,会带来什么改变呢,会给我们带来什么样的体验呢

设计:

设计模式第三讲-装饰者模式

实现:

声明抽象类(被装饰者和装饰者继承此类,目的对实现方法进行规正)

package car;

public abstract class Car {

    public String name;

    public abstract String cost();
}
复制代码

主角:被装饰者类-裸车

package car;

/**
 * 被装饰的类 -> 裸车
 */
public class NakeCar extends Car {

    //裸车价格 --实际数值从数据库查询,此处略
    private int nakedPrice = 100000;


    public NakeCar() {
        this.name = "裸车";
    }

    /**
     * 获取总价
     *
     * @return
     */
    public String cost() {
        return this.name + ":" + this.nakedPrice;
    }
}
复制代码

具体装饰类:

加热座椅

package car;

/**
 * 装饰组件
 */
public class HeatedSeat extends Car {

    //加热座椅
    private int heatedSeat = 4000;

    //汽车对象
    private Car car;

    public HeatedSeat(Car car) {
        this.name = "加热座椅";
        this.car = car;
    }

    /**
     * 获取价格
     *
     * @return
     */
    public String cost() {
        //todo
        return this.car.cost() + "||" + this.name + ":" + this.heatedSeat;
    }

}

复制代码

真皮内饰

package car;

public class DermalInteriors extends Car {

    //真皮内饰
    private int dermalInteriors = 8000;

    //汽车对象
    private Car car;

    public DermalInteriors(Car car) {
        this.name = "真皮内饰";
        this.car = car;
    }

    /**
     * 获取价格
     *
     * @return
     */
    public String cost() {
        //todo
        return this.car.cost() + "||" + this.name + ":" + this.dermalInteriors;
    }

}

复制代码

蹦迪音响

package car;

public class BengdiSound extends Car {

    //蹦迪音响
    private int bengdiSound = 5000;

    //汽车对象
    private Car car;

    public BengdiSound(Car car) {
        this.name = "蹦迪音响";
        this.car = car;
    }

    /**
     * 获取价格
     *
     * @return
     */
    public String cost() {
        //todo
        return this.car.cost() + "||" + this.name + ":" + this.bengdiSound;
    }
}

复制代码

客户端调用:

package car;

public class Main {

    public static void main(String[] args) {

        NakeCar car = new NakeCar();

        HeatedSeat heatedSeat = new HeatedSeat(car);
        BengdiSound bengdiSound = new BengdiSound(heatedSeat);
        System.out.println("总花费价格:" + bengdiSound.cost());
    }
}
复制代码

output:

总花费价格:裸车:100000||加热座椅:4000||蹦迪音响:5000
复制代码

总结

  • 装饰模式的优点: 可以为已有的功能(被装饰对象)动态的添加功能,简化原有类。在我们的例子中, 裸车是主类,相当于业务中的核心,而一些动态的组件可以根据实际情况使用,也就相当于我们业务线中的附属拓展功能。

    主逻辑和拓展逻辑的区分会使我们的代码更具拓展性。

  • 装饰模式的缺点: 我们可以看到装饰模式的引入会增多类的数量,以及客户端的使用会有复杂度上升。装饰模式的类依赖特定的类型,需要严格遵守规约(抽象类的约束)

更多精彩内容关注公众号:

设计模式第三讲-装饰者模式

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

大转换

大转换

尼古拉斯·卡尔 / 闫鲜宁、张付国 / 中信 / 2016-2 / 49

1、我们这个时代最清醒的思考者之一尼古拉斯·卡尔继《浅薄》《玻璃笼子》之后又一重磅力作。 2、在这部跨越历史、经济和技术领域的著作中,作者从廉价的电力运营方式对社会变革的深刻影响延伸到互联网对我们生活的这个世界的重构性影响。 3、《快公司》《金融时报》《华尔街日报》联袂推荐 简介 早在2003年,尼古拉斯·卡尔先生发表在《哈佛商业评论》上的一篇文章——IT Doesn't ......一起来看看 《大转换》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具