设计者模式 -- 建造者模式(builder)

建造者模式定义:

讲一个复杂对象的构造与其表示进行分离,使同样的构建过程可以创建不同的表示。其实就是将一个复杂对象分解为多个简单的对象,然后一步一步构建而成,将变与不变进行分析,也就是说产品的组成部分不变,但每一部分都可以进行灵活选择。

其优点:

  • 每个具体的建造着相对独立,这样有利于系统扩展
  • 客户端不必知道产品内部的组成细节,便于控制细节风险

其缺点:

  • 产品的组成部分必须相同,使用范围会受限
  • 如果产品内部变化较为复杂,这样会增加很多的建造着类。

建造者模式注重的就是零部件的组装过程。

结构:

  • 产品角色(Product):包含多个组成组件的复杂对象,有具体的建造者来创建其各个部件
  • 抽象建造者(Builder):一个包含创建产品各个自组件的抽象方法的接口,通常包含一个返回复杂产品的方法getResult()
  • 具体建造者(Concrete Builder):实现Builder接口,完成复杂产品的各个部件的具体创建方法
  • 指挥者(Director):调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。

上述图就是鉴照着模式的结构图,看一下代码的具体实现

产品角色:包含多个组成部件

package builder.module;

/**
 * 产品角色
 */
public class Product {

    private String part1;

    private String part2;

    private String part3;

    public void setPart1(String part1) {
        this.part1 = part1;
    }

    public void setPart2(String part2) {
        this.part2 = part2;
    }

    public void setPart3(String part3) {
        this.part3 = part3;
    }

    /**
     * 显示产品特性
     */
    public void show(){
        System.out.println(part1);
        System.out.println(part2);
        System.out.println(part3);
    }
}

抽象构建者:包含创建产品各个不见得抽象方法

package builder.module;

/**
 * 抽象构建者
 */
public abstract class Builder {

    protected Product product = new Product();

    public abstract void buildPart1();

    public abstract void buildPart2();

    public abstract void buildPart3();

    /**
     * 返回产品对象
     *
     * @return 产品对象
     */
    public Product getResult() {
        return product;
    }
}

具体建造者:实现抽象建造着的方法,完成复杂对象的创建

/**
 * 具体建造者  需要实现抽象建造着接口
 */
public class ConcreteBuilder extends Builder{
    @Override
    public void buildPart1() {
        product.setPart1("建造 part1");
    }

    @Override
    public void buildPart2() {
        product.setPart2("建造 part2");
    }

    @Override
    public void buildPart3() {
        product.setPart3("建造 part3");
    }
}

指挥者:调用建造着中的方法完成复杂对象的创建

package builder.module;

/**
 * 指挥者
 */
public class Director {

    private Builder builder;

    public Director(Builder builder){
        this.builder = builder;
    }

    /**
     * 产品构建以及组装方法
     * @return 完成构建的产品
     */
    public Product construct(){
        builder.buildPart1();
        builder.buildPart2();
        builder.buildPart3();
        return builder.getResult();
    }
}

客户端:客户端根据需求选定指定指定建造着

package builder.module;

public class Client {
    public static void main(String[] args) {
        // 使用具体的建造者
        Builder builder = new ConcreteBuilder();
        // 指挥者实例话,指定具体的建造着
        Director director = new Director(builder);
        // 通过指挥者根据对应的具体构建者创建产品
        Product product = director.construct();
        // 展示产品
        product.show();
    }
}

 建造者模式通常的应用场景:

创建的对象比较复杂,可能会有多个部件构成,各个部件面临着复杂的变化,但组成部分的建造顺序是稳定的

创建复杂对象的算法独立于该对象的组成部分以及他们的装配方式,也就是说产品的构建过程和最终的表示是相对独立的。

接下来搞个简单的demo:

比如所有的车的工序都是一样的只需要轮子,logo,价格,那么做一个汽车模型Car,这个就是产品,接下来抽象一个工厂Factory,这个就是抽象建造着,然后实现比亚迪工厂BYDFactory,宝马工厂BMWFactory,特斯拉工厂TESLAFactory,这个就是具体建造着,一个4s店的代理商Agent,这个就是指挥者,然后客户就可以科举需求来购买指定的汽车

产品Car

package builder.demo;

public class Car {

    private String wheel;

    private String logo;

    private String price;

    public void setWheel(String wheel) {
        this.wheel = wheel;
    }

    public void setLogo(String logo) {
        this.logo = logo;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    public void show() {
        System.out.println("我是:" + logo + ",有" + wheel + "个轮子,我的售价" + price + "万元");
    }
}

抽象建造者Factory

package builder.demo;

/**
 * 抽象工厂
 */
public abstract class Factory {

    // 创建产品对象
    protected Car car = new Car();

    public abstract void buildWheel();

    public abstract void buildLogo();

    public abstract void buildPrice();

    /**
     * 返回产品对象
     * @return 汽车产品
     */
    public Car getResult(){
        return car;
    }
}

具体建造者BMWFactory

package builder.demo;

/**
 * 宝马工厂
 */
public class BMWFactory extends Factory {
    @Override
    public void buildWheel() {
        car.setWheel("4");
    }

    @Override
    public void buildLogo() {
        car.setLogo("BMW");
    }

    @Override
    public void buildPrice() {
        car.setPrice("40");
    }
}

剩下两个具体建造者类似

指挥者Agent

package builder.demo;

/**
 * 4s销售点
 */
public class Agent {
    private Factory factory;

    public Agent(Factory factory){
        this.factory = factory;
    }

    public Car construct(){
        factory.buildWheel();
        factory.buildLogo();
        factory.buildPrice();
        return factory.getResult();
    }
}

客户端

package builder.demo;

/**
 * 客户
 */
public class Client {

    public static void main(String[] args) {
        Factory factory;
        // 通过指定的厂商获取具体工厂实例
        factory = (Factory) Util.getObject("BMWFactory");
        // 获取经销商实例
        Agent agent = new Agent(factory);
        // 经销商订货
        Car car = agent.construct();
        // 展示
        car.show();
    }
}

一个小工具类,就是通过类名实例化类

package builder.demo;

public class Util {

    public static Object getObject(String name){
        String cName = "builder.demo.." + name;
        System.out.println("新类名:"+cName);
        Class<?> c = null;
        try {
            // 根据名称获取类
            c = Class.forName(cName);
            // 调用该类的无参构造方法并获取实例
            return c.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            // 异常
            e.printStackTrace();
            return c;
        }
    }
}

源码地址:https://github.com/yang-shixiong/design/tree/master/src/builder

适用场景:

  • 创建的对象较复杂,由多个部件构成,各部件面临着复杂的变化,但构件间的建造顺序是稳定的。
  • 创建复杂对象的算法独立于该对象的组成部分以及它们的装配方式,即产品的构建过程和最终的表示是独立的。
原文地址:https://www.cnblogs.com/yangshixiong/p/12566510.html