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

栏目: 后端 · 发布时间: 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
复制代码

总结

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

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

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

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

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

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

查看所有标签

猜你喜欢:

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

Object-Oriented Design Heuristics

Object-Oriented Design Heuristics

Arthur J. Riel / Addison-Wesley Professional / 1996-05-10 / USD 64.99

Product Description Here is the first object-oriented development book to provide specific experience-based guidelines to help developers make the right design decisions. This book offers the next ......一起来看看 《Object-Oriented Design Heuristics》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

SHA 加密
SHA 加密

SHA 加密工具