设计模式之建造者模式

本文详细介绍了建造者模式,一种创建型设计模式,用于将复杂对象的构建与其表示分离,使同样的构建过程能创建不同的表示。通过举例说明了建造者模式的角色分工,如指挥者、抽象建造者和具体建造者,并展示了两种不同的实现方式,包括带有指挥者的构建和通过静态内部类简化构建过程。此外,还讨论了建造者模式的优缺点和适用场景,并与抽象工厂模式进行了对比。
摘要由CSDN通过智能技术生成
4.建造者模式
4.1 介绍
  • 建造者模式属于创建型模式,提供了一种创建对象的最佳方式
  • 定义:将一个复杂对象的构建和它的表示分离,使得**同样的构建过程**可以创建不同的表示。
  • 主要作用:在用户不知道对象的建造过程和细节的情况下直接创建复杂的对象(把内部的建造过程和细节隐藏起来)
  • 例子:

工厂:(建造者模式)负责建造汽车(组装过程和细节在工厂内)

客户:只需要说出需要的型号(对象得类型和内容),然后就直接购买可以使用(不需知道汽车的组装过程,零件等等)

  • 角色分析

Driector—指挥—>抽象的Builder<—实现—具体的builder—生产—>具体的产品

4.2 举例步骤:
  • 抽象的建造者:规定协议或步骤
//抽象的建造者:规定协议或步骤
public abstract class Builder {
    abstract void step1();
    abstract void step2();
    abstract void step3();
    abstract void step4();
    abstract Protuct getProtuct();
}
  • 产品
public class Protuct {
    private String step1;
    private String step2;
    private String step3;
    private String step4;

    public String getStep1() {
        return step1;
    }

    public void setStep1(String step1) {
        this.step1 = step1;
    }

    public String getStep2() {
        return step2;
    }

    public void setStep2(String step2) {
        this.step2 = step2;
    }

    public String getStep3() {
        return step3;
    }

    public void setStep3(String step3) {
        this.step3 = step3;
    }

    public String getStep4() {
        return step4;
    }

    public void setStep4(String step4) {
        this.step4 = step4;
    }

    @Override
    public String toString() {
        return "Protuct{" +
                "step1='" + step1 + '\'' +
                ", step2='" + step2 + '\'' +
                ", step3='" + step3 + '\'' +
                ", step4='" + step4 + '\'' +
                '}';
    }
}
  • 具体建造师实现协议
//具体建造师
public class Worker extends Builder{
    private Protuct protuct;


    public Worker() {           //实际建造者创建产品,产品非传入,而是由其创建而来
        protuct = new Protuct();
    }

    @Override
    void step1() {
        protuct.setStep1("步骤1");
    }

    @Override
    void step2() {
        protuct.setStep2("步骤2");
    }

    @Override
    void step3() {
        protuct.setStep3("步骤3");
    }

    @Override
    void step4() {
        protuct.setStep4("步骤4");
    }

    @Override
    Protuct getProtuct() {
        return protuct;
    }
}
  • 指挥者创建对象
//核心:通过指挥者来创建对象;负责构建一个工程
public class Driector {

    public Protuct build(Worker worker){ //指挥者指挥建造者建造产品,指挥不同的建造者建造不同的产品
        //构建顺序可变
        worker.step1();
        worker.step2();
        worker.step3();
        worker.step4();
        return worker.getProtuct();
    }
}
  • 测试
@Test
public void testBuilder(){
    Driector driector = new Driector();
    Protuct build = driector.build(new Worker());
    System.out.println(build.toString());
}

Protuct{step1='步骤1', step2='步骤2', step3='步骤3', step4='步骤4'}
4.3 建造者模式构成简化
  • 上述举例是建造者模式常规用法,Driector在此模式中具有重要作用,用于指导如何构建产品,控制调用先后次序,向调用者返回实际产品,有些情况需要简化系统结构,可以把Director和抽象者进行结合

  • 通过静态内部类的方式实现零件无序装配构造,此方式灵活,更符合定义。内部有复杂对象的默认实现,使用时可以根据用户需要自由定义更改内容,并且无需改变具体的构造方式。就可以生产出不同复杂产品。

  • 举例:

  • 抽象的建造者:规定协议或步骤

//抽象的建造者:规定协议或步骤
public abstract class Builder {
    abstract Builder step1(String args);
    abstract Builder step2(String args);
    abstract Builder step3(String args);
    abstract Builder step4(String args);
    abstract Protuct getProtuct();
}
  • 产品
public class Protuct {
    private String step1 = "默认步骤1";
    private String step2 = "默认步骤2";
    private String step3 = "默认步骤3";
    private String step4 = "默认步骤4";

    public String getStep1() {
        return step1;
    }

    public void setStep1(String step1) {
        this.step1 = step1;
    }

    public String getStep2() {
        return step2;
    }

    public void setStep2(String step2) {
        this.step2 = step2;
    }

    public String getStep3() {
        return step3;
    }

    public void setStep3(String step3) {
        this.step3 = step3;
    }

    public String getStep4() {
        return step4;
    }

    public void setStep4(String step4) {
        this.step4 = step4;
    }

    @Override
    public String toString() {
        return "Protuct{" +
                "step1='" + step1 + '\'' +
                ", step2='" + step2 + '\'' +
                ", step3='" + step3 + '\'' +
                ", step4='" + step4 + '\'' +
                '}';
    }
}
  • 具体建造师
//具体建造师
public class Worker extends Builder {
    private Protuct protuct;


    public Worker() {           //实际建造者创建产品,产品非传入,而是由其创建而来
        protuct = new Protuct();
    }

    @Override
    public Worker step1(String msg) {
        protuct.setStep1(msg);
        return this;
    }

    @Override
    public Worker step2(String msg) {
        protuct.setStep2(msg);
        return this;
    }

    @Override
    public Worker step3(String msg) {
        protuct.setStep3(msg);
        return this;
    }

    @Override
    public Worker step4(String msg) {
        protuct.setStep4(msg);
        return this;
    }

    @Override
    public Protuct getProtuct() {
        return protuct;
    }
}
  • 客户调用:链式编程
@Test
public void testNoDriectorBuilder(){
    //实际建造者
    nodriectorbuilder.Worker worker = new nodriectorbuilder.Worker();
    //链式编程和springBoot中调用对应
    //客户自己即为指挥者
    nodriectorbuilder.Protuct build = worker.step1("A实现").getProtuct();
    System.out.println(build.toString());
}
4.4 优缺点
  • 优点:

产品建造和表示分离,实现解耦,使用建造者模式可以是客户端屏蔽产品内部实现细节

将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰

具体建造者类之间是相互独立的,有利于系统扩展。增加新的具体建造者无需修改之前的类库。符合开闭原则

  • 缺点

建造者模式所创建的产品一般具有较多的共同点,组成部分相似;若产品之间差异较大,就不适合使用建造者模式,所以使用范围受到一定限制

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

4.5 应用场景
  • 需要生成的产品对象有复杂的内部结构,这些产品对象具备共性
  • 隔离复杂对象的创建和使用,并是的相同的创建过程可以创建不同的产品
  • 适合一个具有较多属性的对象的创建过程
4.6 和抽象工厂模式比较
  • 建造者模式返回一个组装好的完整产品,抽象工厂模式返回一系列相关的产品,这些产品位于不同的产品等级结构,构成一个产品簇
  • 抽象工厂模式客户端实例化工厂类,然后调用工厂方法获得所需的对象。建造者模式客户端可以不直接调用建造者的相关方法,而是直接通过指挥者类来知道如何生成对象,包括对象的组装过程和建造步骤,侧重于一步步构造复杂对象,返回一个完整的对象
  • 将抽象工厂模式看成汽车配件生产工厂,生产一个产品簇产品。建造者模式就是一个汽车组装工厂,通过对部件的组装返回一辆完整汽车
本专栏下一篇:设计模式之原型模式
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值