设计模式(四):建造者模式的详细解析

如果大家对java架构相关感兴趣,可以关注下面公众号,会持续更新java基础面试题, netty, spring boot,spring cloud等系列文章,一系列干货随时送达, 超神之路从此展开, BTAJ不再是梦想!

架构殿堂

概述

建造者模式属于创建型设计模式,它主要是将一个复杂对象的构建与表示分离,使用多个简单的对象一步一步构建成一个复杂的对象,它提供了一种创建对象的最佳方式。

建造者模式将复杂产品的构建过程封装在不同的方法中,使得创建过程非常清晰,能够让我们更加精确的控制复杂产品对象的创建过程,同时它隔离了复杂产品对象的创建和使用,使得相同的创建过程能够创建不同的产品。

但是如果某个产品的内部结构过于复杂,将会导致整个系统变得非常庞大,不利于控制,同时若干个产品之间存在较大的差异,则不适用建造者模式。其UML结构图如下:

在这里插入图片描述

1、定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
2、主要作用:在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象。
3、如何使用:用户只需要给出指定复杂对象的类型和内容,建造者模式负责按顺序创建复杂对象(把内部的建造过程和细节隐藏起来)
4、解决的问题
(1)、方便用户创建复杂的对象(不需要知道实现过程)
(2)、代码复用性 & 封装性(将对象构建过程和细节进行封装 & 复用)
5、注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序,一般用来创建更为复杂的对象

四个角色

  • Product(产品对象):一个具体的产品对象
  • Bulider(抽象建造者):创建一个Product对象的各个部件指定的 接口/抽象类 。指定建造流程
  • ConcreteBulider(具体建造者):实现接口,构建和装配各个部件
  • Director(指挥者):构建一个使用Bulider接口的对象,它主要是用于创建一个复杂的对象,它隔离了客户和对象的生产过程,还负责控制整个产品对象的生产过程

示例

Product

public class Product
{
    private String partA; //可以是任意类型

    private String partB;

    private String partC;

    public String getPartA()
    {
        return partA;
    }

    public void setPartA(String partA)
    {
        this.partA = partA;
    }

    public String getPartB()
    {
        return partB;
    }

    public void setPartB(String partB)
    {
        this.partB = partB;
    }

    public String getPartC()
    {
        return partC;
    }

    public void setPartC(String partC)
    {
        this.partC = partC;
    }

    @Override
    public String toString()
    {
        return "Product [partA=" + partA + ", partB=" + partB + ", partC=" + partC + "]";
    }
}

Builder

public abstract class Builder {

    protected Product product = new Product();

    public abstract void buildPartA();

    public abstract void buildPartB();

    public abstract void buildPartC();

    public Product getResult()
    {
        return product;
    }
}

ConcreteBuilder

public class ConcreteBuilder extends Builder {

    @Override
    public void buildPartA()
    {
        product.setPartA("A产品");
        System.out.println("创建A产品...");
    }

    @Override
    public void buildPartB()
    {
        product.setPartB("B产品");
        System.out.println("创建B产品...");
    }

    @Override
    public void buildPartC()
    {
        product.setPartC("C产品");
        System.out.println("创建C产品...");
    }
}

Director

public class Director {
    private Builder builder;

    //1 构造方法的方式注入builder对象
    public Director(Builder builder)
    {
        this.builder = builder;
    }

    //2 set方法注入builder对象
    public void setBuilder(Builder builder)
    {
        this.builder = builder;
    }

    public Product construct()
    {
        builder.buildPartA();
        builder.buildPartB();
        builder.buildPartC();
        return builder.getResult();
    }
}

BuilderPatternDemo

public class BuilderPatternDemo {
    public static void main(String[] args)
    {
        Builder builder = new ConcreteBuilder();
        Director director = new Director(builder);
        Product product = director.construct();
        System.out.println(product);
    }
}

输出

创建A产品...
创建B产品...
创建C产品...
Product [partA=A产品, partB=B产品, partC=C产品]

优点

  • 使用建造者模式可以使客户端不必知道产品内部组成的细节。
  • 具体的建造者类之间是相互独立的,这有利于系统的扩展。
  • 具体的建造者相互独立,因此可以对建造的过程逐步细化,而不会对其他模块产生任何影响。

缺点

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

应用场景

  1. 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。

  2. 当复杂对象的部件相对稳定,不会发生变化时。

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

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

如果大家对java架构相关感兴趣,可以关注下面公众号,会持续更新java基础面试题, netty, spring boot,spring cloud等系列文章,一系列干货随时送达, 超神之路从此展开, BTAJ不再是梦想!

架构殿堂

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章