设计模式 —— 建造者模式

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

内容简介:在软件开发中,存在大量复杂对象,它们拥有一系列成员属性,这些成员属性中有些是引用类型的成员对象。而且在这些复杂对象中,还可能存在一些限制条件,如某些属性没有赋值则复杂对象不能作为一个完整的产品使用;有些属性的赋值必须按照某个顺序,一个属性没有赋值之前,另一个属性可能无法赋值等。由于组合部件的过程很复杂,因此,这些部件的组合过程往往被“外部化”到一个称作建造者的对象里,建造者返还给客户端的是一个已经建造完毕的完整产品对象,而用户无须关心该对象所包含的属性以及它们的组装方式,这就是建造者模式的模式动机。建造者模

在软件开发中,存在大量复杂对象,它们拥有一系列成员属性,这些成员属性中有些是引用类型的成员对象。而且在这些复杂对象中,还可能存在一些限制条件,如某些属性没有赋值则复杂对象不能作为一个完整的产品使用;有些属性的赋值必须按照某个顺序,一个属性没有赋值之前,另一个属性可能无法赋值等。

由于组合部件的过程很复杂,因此,这些部件的组合过程往往被“外部化”到一个称作建造者的对象里,建造者返还给客户端的是一个已经建造完毕的完整产品对象,而用户无须关心该对象所包含的属性以及它们的组装方式,这就是建造者模式的模式动机。

建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的 设计模式 属于创建型模式,它提供了一种创建对象的最佳方式。

实例

建造者模式包含如下角色:

Builder
ConcreteBuilder
Director
Product

电脑是每个 程序员 的标配,主要配件有:CPU、主板、内存、显卡、电源。当前主要有两大平台: AMDIntel ,但是两个平台的一些零件是不一样的。所以肥宅在组装两个平台时选择的配件也是不一样的。

产品(电脑):

public class Computer {
    /**
     * cpu
     */
    private String cpu;
    /**
     * 主板
     */
    private String motherboar;
    /**
     * 内存
     */
    private String ram;
    /**
     * 显卡
     */
    private String graphicsCard;
    /**
     * 电源
     */
    private String power;

    //setter and getter
    // toString
}
复制代码

抽象工厂:

abstract class AbstractComputerBuilder {
    /**
     * 选择CPU
     */
    abstract void buildCPU();
    /**
     * 选择主板
     */
    abstract void buildMotherboar();
    /**
     * 选择内存
     */
    abstract void buildRam();
    /**
     * 选择显卡
     */
    abstract void buildGraphicsCard();
    /**
     * 选择电源
     */
    abstract void buildPower();
    /**
     * 获取电脑
     */
    abstract Computer getComputer();
}
复制代码

具体建造者:

// AMD电脑 建造者
public class AmdComputerBuilder extends AbstractComputerBuilder {
    private Computer computer = new Computer();
    @Override
    void buildCPU() {
        computer.setCpu("2700x");
    }
    @Override
    void buildMotherboar() {
        computer.setMotherboar("华硕 ROG X470");
    }
    @Override
    void buildRam() {
        computer.setRam("芝奇 DDR4 8G");
    }
    @Override
    void buildGraphicsCard() {
        computer.setGraphicsCard("vega 56");
    }
    @Override
    void buildPower() {
        computer.setPower("EVGA 750W");
    }
    @Override
    Computer getComputer() {
        return computer;
    }
}

// Intel 电脑建造者
public class IntelComputerBuilder extends AbstractComputerBuilder {
    private Computer computer = new Computer();
    @Override
    void buildCPU() {
        computer.setCpu("i7 8700");
    }
    @Override
    void buildMotherboar() {
        computer.setMotherboar("微星 Z370");
    }
    @Override
    void buildRam() {
        computer.setRam("金士顿 DDR4 8G");
    }
    @Override
    void buildGraphicsCard() {
        computer.setGraphicsCard("GTX 1080Ti");
    }
    @Override
    void buildPower() {
        computer.setPower("海韵 750W");
    }
    @Override
    Computer getComputer() {
        return computer;
    }
}
复制代码

指挥者:

public class ComputerDirector {
    public void construct(AbstractComputerBuilder builder) {
        builder.buildCPU();
        builder.buildMotherboar();
        builder.buildRam();
        builder.buildGraphicsCard();
        builder.buildPower();
    }
}
复制代码

测试:

public class Fz {
    @Test
    public void build() {
        ComputerDirector director = new ComputerDirector();

        AmdComputerBuilder amdComputerBuilder = new AmdComputerBuilder();
        director.construct(amdComputerBuilder);
        Computer amdComputer = amdComputerBuilder.getComputer();
        System.out.println("选择AMD平台配件:" + amdComputer);

        IntelComputerBuilder intelComputerBuilder = new IntelComputerBuilder();
        director.construct(intelComputerBuilder);
        Computer intelComputer = intelComputerBuilder.getComputer();
        System.out.println("选择Intel平台配件:" + intelComputer);

    }

}
复制代码

类图

设计模式 —— 建造者模式

优点

  1. 建造者模式的封装性很好。使用建造者模式可以有效的封装变化,在使用建造者模式的场景中,一般产品类和建造者类是比较稳定的,因此,将主要的业务逻辑封装在导演类中对整体而言可以取得比较好的稳定性。
  2. 在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
  3. 可以更加精细地控制产品的创建过程。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。
  4. 建造者模式很容易进行扩展。如果有新的需求,通过实现一个新的建造者类就可以完成,基本上不用修改之前已经测试通过的代码,因此也就不会对原有功能引入风险。符合开闭原则。

缺点

  1. 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
  2. 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

适用场景

在以下情况下可以使用建造者模式:

  1. 需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员属性。
  2. 需要生成的产品对象的属性相互依赖,需要指定其生成顺序。
  3. 对象的创建过程独立于创建该对象的类。在建造者模式中引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类中。
  4. 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。

总结

建造者模式与工厂模式类似,适用的场景也很相似。建造者模式仅仅只比工厂模式多了一个”指挥者”的角色。在建造者模式的类图中,假如把这个导演类看做是最终调用的客户端,那么图中剩余的部分就可以看作是一个简单的工厂模式了。

建造者模式一般用来创建更为复杂的对象,因为对象的创建过程更为复杂,因此将对象的创建过程独立出来组成一个新的类——导演类。也就是说,工厂模式是将对象的全部创建过程封装在工厂类中,由工厂类向客户端提供最终的产品;而建造者模式中,建造者类一般只提供产品类中各个组件的建造,而将具体建造过程交付给导演类。由导演类负责将各个组件按照特定的规则组建为产品,然后将组建好的产品交付给客户端。建造者模式更加关注与零件装配的顺序。

一般来说,如果产品的建造很复杂,那么请用工厂模式;如果产品的建造更复杂,那么请用建造者模式。


以上所述就是小编给大家介绍的《设计模式 —— 建造者模式》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

HTML5

HTML5

Matthew David / Focal Press / 2010-07-29 / USD 39.95

Implement the powerful new multimedia and interactive capabilities offered by HTML5, including style control tools, illustration tools, video, audio, and rich media solutions. Understand how HTML5 is ......一起来看看 《HTML5》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

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

正则表达式在线测试

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具