23种设计模式-建造者模式

建造者模式

建造者模式也属于创建型模式,它提供了一种创建对象的最佳方式。

定义:将一个复杂对象的构造与它的表示分离,使得同样的构建过程可以创建不同的表示。

主要解决:在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

假设此时我们需要建造一栋房子,一系列步骤简化为:

  1. 地基
  2. 钢筋工程
  3. 铺电线
  4. 粉刷

为了盖好这一栋房子,我们需要找到一个“建筑公司”或是“承包商(指挥者)”,承包商会指挥工人(具体建造者)过来造房子(产品),等待房子盖完,最后进行验收。

在这里插入图片描述

抽象的Builder类:

public abstract class Builder {
    abstract void BuildA(); // 地基
    abstract void BuildB(); // 钢筋工程
    abstract void BuildC(); // 铺电线
    abstract void BuildD(); // 粉刷
    abstract Product getProduct();
}

具体的产品(Product)类:

public class Product {
    private String BuildA;
    private String BuildB;
    private String BuildC;
    private String BuildD;

    public String getBuildA() { return BuildA; }
    
    public void setBuildA(String buildA) { BuildA = buildA; }
    
    public String getBuildB() { return BuildB; }
    
    public void setBuildB(String buildB) { BuildB = buildB; }
    
    public String getBuildC() { return BuildC; }
    
    public void setBuildC(String buildC) { BuildC = buildC; }
    
    public String getBuildD() { return BuildD; }
    
    public void setBuildD(String buildD) { BuildD = buildD; }

    @Override
    public String toString() {
        return "Product{" +
                "BuildA='" + BuildA + '\'' +
                ", BuildB='" + BuildB + '\'' +
                ", BuildC='" + BuildC + '\'' +
                ", BuildD='" + BuildD + '\'' +
                '}';
    }
}

具体的Builder类:

public class Worker extends Builder {
    private Product product;

    public Worker() {
        product = new Product();
    }

    @Override
    void BuildA() {
        product.setBuildA("地基");
        System.out.println("地基");
    }
    
    @Override
    void BuildB() {
        product.setBuildB("钢筋工程");
        System.out.println("钢筋工程");
    }
    
    @Override
    void BuildC() {
        product.setBuildC("铺电线");
        System.out.println("铺电线");
    }
    
    @Override
    void BuildD() {
        product.setBuildD("粉刷");
        System.out.println("粉刷");
    }
    
    @Override
    Product getProduct() {
        return product;
    }
}

指挥者(Director)类:

public class Directot {
    public Product build(Builder builder) {
        builder.BuildA();
        builder.BuildB();
        builder.BuildC();
        builder.BuildD();
        return builder.getProduct();
    }
}

测试类:

public class Test {
    public static void main(String[] args) {
        Directot directot = new Directot();
        Product product = directot.build(new Worker());
        System.out.println(product.toString());
    }
}

上述例子讲解的是Builder模式的常规用法,指挥者类Director在Builder模式中具有很重要的作用,它用于指导具体构建者如何构建产品,控制调用先后次序,并向调用者返回完整的产品类,但是有些时候需要简化一下系统,也就是说,可以把Director和抽象建造者进行结合。

我们可以通过静态内部类的方式实现零件无序装配构造,这汇使用方式更加灵活,更加符合定义。

当内部有复杂对象的默认实现,使用时可以根据用户需求自由定义更改内容,并且无需改变具体的构造方式,就可以生产出不同的复杂产品。例如:麦当劳的套餐,服务员(具体建造者)可以随意搭配任意几种产品组合成一种套餐,推送给消费者。

抽象的Builder类:

public abstract class Builder {
    abstract Builder BuildA(String msg);
    abstract Builder BuildB(String msg);
    abstract Builder BuildC(String msg);
    abstract Builder BuildD(String msg);
    abstract Product getProduct();
}

具体的产品(Product)类:

public class Product {
    private String BuildA = "汉堡";
    private String BuildB = "薯条";
    private String BuildC = "可乐";
    private String BuildD = "鸡块";

    public void setBuildA(String buildA) {
        BuildA = buildA;
    }

    public void setBuildB(String buildB) {
        BuildB = buildB;
    }

    public void setBuildC(String buildC) {
        BuildC = buildC;
    }

    public void setBuildD(String buildD) {
        BuildD = buildD;
    }

    @Override
    public String toString() {
        return "Product{" +
                "BuildA='" + BuildA + '\'' +
                ", BuildB='" + BuildB + '\'' +
                ", BuildC='" + BuildC + '\'' +
                ", BuildD='" + BuildD + '\'' +
                '}';
    }
}

具体的Builder类:

public class Worker extends Builder {
    private  Product product;

    public Worker() {
        product = new Product();
    }

    @Override
    Builder BuildA(String msg) {
        product.setBuildA(msg);
        return this;
    }

    @Override
    Builder BuildB(String msg) {
        product.setBuildB(msg);
        return this;
    }

    @Override
    Builder BuildC(String msg) {
        product.setBuildC(msg);
        return this;
    }

    @Override
    Builder BuildD(String msg) {
        product.setBuildD(msg);
        return this;
    }

    @Override
    Product getProduct() {
        return product;
    }
}

测试类:

public class Test {
    public static void main(String[] args) {
        Worker worker = new Worker();
        // 链式编程
        Product product = worker.BuildA("甜品").getProduct();
        System.out.println(product.toString());
    }
}

建造者模式的优点:

  • 产品的建造和表示分离,实现了解耦,使用建造者模式可以使客户端不必知道产品内部组成的细节
  • 将复杂产品的创建步骤分解在不同的方法中,使得创新过程更加清晰
  • 具体的建造者类之间是相互独立的,这有利于系统的扩展,增加新的具体建造者无需修改原有库存的代码,符合开闭原则

缺点:

  • 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;如果产品之间的差异性很大,则不

    适合使用建造者模式,因此使用范围将会受到一定的限制

  • 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大

应用场景:

  • 需要生成的产品对象有复杂的内部结构,这些产品对象具备共性;
  • 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。
  • 适合于一个具有较多的零件(属性)的产品(对象)的创建过程。

建造者与抽象工厂模式的比较:

  • 与抽象工厂模式相比,建造者模式返回一个组装好的完整产品,而抽象工厂模式返回一系列相关的产
    品,这些产品位于不同的产品等级结构构成了一个产品族
  • 在抽象工厂模式中,客户端实例化工厂类,然后调用工厂方法获取所需产品对象,而在建造者模式中,
    客户端可以不直接调用建造者的相关方法,而是通过指挥者类来指导如何生成对象,包括对象的组装
    过程和建造步骤,它侧重于一步步构造一个复杂对象,返回一个完整的对象
  • 如果将抽象工厂模式看成汽车配件生产工厂,生产一个产品族的产品,那么建造者模式就是一个汽车
    组装工厂,通过对部件的组装可以返回一辆完整的汽车
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值