【设计模式】

设计模式——建造者模式

本片文章总结于《狂神说Java》的设计模式篇章:
B站链接

一、建造者模式

简介:
建造者模式提供了一种创建对象的一种最佳的方法
作用
将一个复杂的对象的构建于他的表示进行分离,通过同样的构建方式可以创建出不同的方法。(例如造房子,可以通过大体的步骤:地基 —> 钢筋 —> 电线 —> 水泥创建出不同的房子,但大体步骤相似)
用户在不需要知道对象创建的建造过程和细节就可以直接创建对象

二、具体实现

1.类图

在这里插入图片描述

  • Director:监管者,类似于造房子的包工头(也是核心,因为他设计到建造的一个整体顺序和流程是如何进行的)
  • Build:大体要进行哪些步,类似造房子的图纸
  • 具体的Build:具体的实现过程,建造的具体过程
  • Produce:最终的产品

2.案例实现

首先定义最终获得的产品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) {
        this.buildA = buildA;
    }

    public String getBuildB() {
        return buildB;
    }

    public void setBuildB(String buildB) {
        this.buildB = buildB;
    }

    public String getBuildC() {
        return buildC;
    }

    public void setBuildC(String buildC) {
        this.buildC = buildC;
    }

    public String getBuildD() {
        return buildD;
    }

    public void setBuildD(String buildD) {
        this.buildD = buildD;
    }

    @Override
    public String toString() {
        return "Product{" +
                "buildA='" + buildA + '\'' +
                ", buildB='" + buildB + '\'' +
                ", buildC='" + buildC + '\'' +
                ", buildD='" + buildD + '\'' +
                '}';
    }
}

接着定义一个抽象的Build,里面只涉及到创建的大体步骤过程

public abstract class Builder {
    abstract void buildA();//地基
    abstract void buildB();//钢筋
    abstract void buildC();//电线
    abstract void buildD();//水泥
    // 得到产品
    abstract Product getProduct();
}

定义一个Work具体实现Build,即创建房子的工人,每一步需要进行什么工作
注意:Worker构造类里面没有参数,内部自己new一个,用户不需要自己建造

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;
    }
}

监工,告诉Work的工作顺序

public class Director {
    // 指挥工作
    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) {
        // 监工
        Director director= new Director();
        // 指挥具体工人
        Product build = director.build(new Worker());
        System.out.println(build.toString());
    }
}

运行结果
在这里插入图片描述


三、建造者模式与内部类结合(Build的链式编程)

上述的建造者过程有一个Director的角色用于指挥整体的创建过程以及调用顺序,并在最后返回产品,但有些情况下我们需要简化这个过程,将Director与抽象建造这进行结合,例如点餐,可以有默认套餐,也可以我们任意搭配自选。
通过静态内部类方法实现无序的装配构造形式,这种方式更灵活自由,更加符合定义。内部有默认的方法实现,也可以根据需求自定义更改,从而生产出不同的复杂的产品。

产品类(与上面不同的是这次产品有了默认的值)

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 + '\'' +
                '}';
    }
}

抽象的Build类

public abstract class Builder {
    abstract Builder builderA(String builderA);
    abstract Builder builderB(String builderB);
    abstract Builder builderC(String builderC);
    abstract Builder builderD(String builderD);
    abstract Product getProduct();
}

具体Worker(构造方法还是一样,返回新对象,但不同的是可以对产品的属性进行set)

public class Work extends Builder{
    Product product;
    public Work(){
        product = new Product();
    }
    @Override
    Builder builderA(String builderA) {
        product.setBuildA(builderA);
        return this;
    }

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

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

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

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

测试

public class Test {
    public static void main(String[] args) {
        Work work = new Work();
        // 链式编程
        Product product = work.builderA("鸡翅").builderD("蛋挞")
                .getProduct();
        System.out.println(product.toString());

    }
}

运行结果
在这里插入图片描述

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

  • 与抽象工厂模式相比,建造者模式返回一个组装好的完整产品,而抽象工厂模式返回的是**一系列相关的产品,**这些产品位于不同的产品等级结构,构成一个产品族。(比如抽象工厂可能返回的是某个具体工厂里面生产的不同产品,例如小米工厂生产手机和路由器,这两个不是同一个产品等级,但是构成产品族)。
  • 抽象工厂中,客户端实例化工厂,调用工厂方法获得所需要的对象;而在建造者模式之中,可以不直接调用建造者的相关方法,调用指挥者类指导如何生产对象(即上述中不调用Worker,而是调用Director去完成),包括对象的组装过程和建造的步骤,侧重于一步一步构建一个复杂的对象(链式编程),返回一个完整的对象。
  • 如果将抽象工厂模式看作是汽车配件生产厂,生产一个产品族的产品,那么建造者模式就是一个汽车的组装工厂,通过组装返回一个完整汽车

总结

优点:

  • 产品的构建与他的表示进行分离,实现了解耦。使用者不必知道产品内部的组成细节
  • 将复杂的创建步骤分解在不同的方法之中,使得创建更为简单
  • 具体的建造者类之间是相互独立的,这有利于系统的扩展。增加新的具体建造者无需改变原有代码,符合开闭原则

缺点:

  • 建造者模式所创建的产品一般都有比较多的共同点,其组成部分相似;如果产品之间的差异性比较大,不适合使用
  • 如果产品内部结构比较复杂,可能会需要定义比较多的具体建造者来实现这种变化,导致系统变得很庞大

使用场景:

  • 生产的产品有复杂的内部结构,但他们具有共性
  • 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建出不同的产品
  • 适用于一个具有较多的零件(属性)的产品(对象)的创建过程
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值