解锁设计模式的神秘面纱:编写无懈可击的代码之建造者设计模式

简介: 解锁设计模式的神秘面纱:编写无懈可击的代码之建造者设计模式

前言


设计模式是一种在软件设计中广泛应用的概念,它们代表了解决特定问题或实现特定功能的经验性最佳实践和通用解决方案。设计模式是经过反复验证和测试的,可以帮助开发人员更有效地解决常见的设计问题,提高代码的可维护性、可扩展性和可重用性。


设计模式可以分为三个主要类别:创建型、结构型和行为型。创建型设计模式关注对象的创建机制,结构型设计模式关注类和对象的组合方式,而行为型设计模式关注对象之间的通信和协作方式。在这些类别中,存在许多常见的设计模式.

🌊 关注我不迷路,如果本篇文章对你有所帮助,或者你有什么疑问,欢迎在评论区留言,我一般看到都会回复的。大家点赞支持一下哟~ 💗



什么是建造者模式?

建造者模式是一种软件设计模式,它用于将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式通常用于创建复杂对象,它包含多个部分,每个部分可以有不同的组成方式。


需求


一个类计算机类Computer包括以下变量


  • cpu
  • ram
  • usbCount
  • keyboard
  • display

而其他3个是可选参数

  • usbCount
  • keyboard
  • display




两种常用的方式


折叠构造器模式


Javabean 直接定义



缺点


第1种

第一种主要是使用及阅读不方便。当调用一个类的构造函数时, 首先要决定使用哪一个,里面参数又很多,参数的类型也不一样,

这样很容易搞混


第2种

在构建过程中对象的状态容易发生变化,造成错误。

因为那个类中的属性是分步设置的,所以就容易出错。


特点

在软件开发过程中有时需要创建一个复杂的对象,这个复杂对象通常由多个子部件按一定的步骤组合而成。 产品都是由多个部件构成的,各个部件可以灵活选择,但其创建步骤都大同小异。

这类产品的创建无法用前面介绍的工厂模式描述,只有建造者模式可以很好地描述该类产品的创建。



建造者模式解决需求(代码实现)


第一步:创建目标类, 也就是我们的产品

/**
 * 产品 计算机
 *
 * @author yang shuai
 * @date 2022/12/4
 */
public class Computer {
    private final String cpu;// 必须
    private final String ram;// 必须
    private int usbCount;// 可选
    private String keyboard;// 可选
    private String display;// 可选
    public Computer(String cpu, String ram) {
        this.cpu = cpu;
        this.ram = ram;
    }
    public void setUsbCount(int usbCount) {
        this.usbCount = usbCount;
    }
    public void setKeyboard(String keyboard) {
        this.keyboard = keyboard;
    }
    public void setDisplay(String display) {
        this.display = display;
    }
    @Override
    public String toString() {
        return "Computer{" + "cpu='" + cpu + '\'' + ", ram='" + ram + '\'' + ", usbCount=" + usbCount + ", keyboard='" + keyboard + '\'' + ", display='" + display + '\'' + '}';
    }
}


第二步:创建抽象构建者类

public abstract class ComputerBuilder {
    public abstract void buildCount(int usbCount);
    public abstract void buildKeyboard(String keyBoard);
    public abstract void buildDisplay(String display);
    public abstract Computer makeComputer();
}


第三步:创建具体建造者类

public class HWComputerBuilder extends ComputerBuilder{
    private Computer computer;
    public HWComputerBuilder(String cpu, String ram) {
        computer=new Computer(cpu,ram);
    }
    @Override
    public void buildCount(int usbCount) {
        computer.setUsbCount(usbCount);
    }
    @Override
    public void buildKeyboard(String keyBoard) {
        computer.setKeyboard(keyBoard);
    }
    @Override
    public void buildDisplay(String display) {
        computer.setDisplay(display);
    }
    @Override
    public Computer makeComputer() {
        return computer;
    }
}


第四步:创建指挥类

public class ComputerDirector {
    private ComputerBuilder builder;
    public void setBuilder(ComputerBuilder builder) {
        this.builder = builder;
    }
    public Computer makeComputer(int useCount,String display,String keyBoard){
       builder.buildCount(useCount);
       builder.buildDisplay(display);
       builder.buildKeyboard(keyBoard);
       return builder.makeComputer();
    }
}




定义

指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。 它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。即产品的组成部分是不变的,但每一部分是可以灵活选择的。




建造者模式与工厂模式的区别


工厂模式

  • 工厂模式注重于创建产品
  • 工厂模式创建出来的产品都是一个样子
  • 工厂模式的关注点是只要创建出对象就可以了建造者模式
  • 建造者模式注重于方法的调用顺序
  • 建造者模式可以创建出复杂的产品,由各种复杂的部件组成
  • 建造者模式不仅要创建产品,,还要知道该产品是由哪些部件组成的




建造者模式包括四个角色:


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




建造者模式的优点有:

  • 它隔离了具体组建和装配方式,使得构建过程与具体实现分离。
  • 它支持构建复杂对象,并且可以控制复杂对象的构建顺序。
  • 它可以使得用户可以独立地改变一个对象的内部表示。
  • 它可以提供一种灵活的构建方式,在用户不确定最终的产品的具体细节时也可以创建对象。
  • 它可以有效地防止用户在构建过程中破坏产品的结构。大白话:

封装性好,构建和表示分离。 扩展性好,各个具体的建造者相互独立,有利于系统的解耦。

客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险。



建造者模式的缺点有:

  • 产生多余的Builder对象
  • 产品内部发生变化,建造者都要修改,成本较大



建造者模式第二种写法


解决产生多余的Builder对象等

在Computer 中创建一个静态内部类 Builder,然后将Computer 中的参数都复制到Builder类中。

示例:

/**
 * 使用静态内部类构造数据
 *
 * @author yang shuai
 * @date 2022/12/9
 */
public class Computer {
    private final String cpu;//必须
    private final String ram;//必须
    private final int usbCount;//可选
    private final String keyboard;//可选
    private final String display;//可选
    @Override
    public String toString() {
        return "Computer{" + "cpu='" + cpu + '\'' + ", ram='" + ram + '\'' + ", usbCount=" + usbCount + ", keyboard='" + keyboard + '\'' + ", display='" + display + '\'' + '}';
    }
    private Computer(Builder computerBuilder) {
        this.cpu = computerBuilder.cpu;
        this.ram = computerBuilder.ram;
        this.usbCount = computerBuilder.usbCount;
        this.keyboard = computerBuilder.keyboard;
        this.display = computerBuilder.display;
    }
    public static class Builder {
        private final String cpu;//必须
        private final String ram;//必须
        private int usbCount;//可选
        private String keyboard;//可选
        private String display;//可选
        public Builder(String cup, String ram) {
            this.cpu = cup;
            this.ram = ram;
        }
        public Builder buildUsbCount(int usbCount) {
            this.usbCount = usbCount;
            return this;
        }
        public Builder buildKeyboard(String keyboard) {
            this.keyboard = keyboard;
            return this;
        }
        public Builder buildDisplay(String display) {
            this.display = display;
            return this;
        }
        public Computer build() {
            return new Computer(this);
        }
    }
}




使用场景

如果一个对象有非常复杂的内部结构(很多属性) 想把复杂对象的创建和使用分离



总结

用来创建复杂的复合对象



源码分析


StringBuilder

  • JDK 的 StringBuilder 类中提供了 append() 方法,这就是一种链式创建对象的方法,开放构造步骤,最后调用 toString() 方法就可以获得一个完整的对象



SqlSessionFactoryBuilder

  • MyBatis 中 SqlSessionFactoryBuiler 类用到了建造者模式。且在 MyBatis 中 SqlSessionFactory是由 SqlSessionFactoryBuilder 产生的


  • XMLConfigBuilder 负责 Configuration 各个组件的创建和装配,整个装配的流程化过程如下:

  • XMLConfigBuilder 负责创建复杂对象 Configuration,其实就是一个具体建造者角色。
  • SqlSessionFactoryBuilder 只不过是做了一层封装去构建 SqlSessionFactory 实例,这就是建造者模式简化构建的过程。



最后


本期结束咱们下次再见👋~

🌊 关注我不迷路,如果本篇文章对你有所帮助,或者你有什么疑问,欢迎在评论区留言,我一般看到都会回复的。大家点赞支持一下哟~ 💗

相关文章
|
24天前
|
设计模式 存储 Java
23种设计模式,享元模式的概念优缺点以及JAVA代码举例
【4月更文挑战第6天】享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享技术有效地支持大量细粒度对象的重用。这个模式在处理大量对象时非常有用,特别是当这些对象中的许多实例实际上可以共享相同的状态时,从而可以减少内存占用,提高程序效率
35 4
|
24天前
|
设计模式 Java 中间件
23种设计模式,适配器模式的概念优缺点以及JAVA代码举例
【4月更文挑战第6天】适配器模式(Adapter Pattern)是一种结构型设计模式,它的主要目标是让原本由于接口不匹配而不能一起工作的类可以一起工作。适配器模式主要有两种形式:类适配器和对象适配器。类适配器模式通过继承来实现适配,而对象适配器模式则通过组合来实现
33 4
|
28天前
|
设计模式 Java 数据库
Java设计模式精讲:让代码更优雅、更可维护
【4月更文挑战第2天】**设计模式是解决软件设计问题的成熟方案,分为创建型、结构型和行为型。Java中的单例模式确保类仅有一个实例,工厂方法模式让子类决定实例化哪个类。适配器模式则协调不兼容接口间的合作。观察者模式实现了一对多依赖,状态变化时自动通知相关对象。学习和适当应用设计模式能提升代码质量和可维护性,但需避免过度使用。设计模式的掌握源于实践与不断学习。**
Java设计模式精讲:让代码更优雅、更可维护
|
6月前
|
设计模式 算法 Java
设计模式第十五讲:重构 - 改善既有代码的设计(下)
设计模式第十五讲:重构 - 改善既有代码的设计
239 0
|
6天前
|
设计模式 存储 Java
C++从入门到精通:3.5设计模式——提升代码可维护性与可扩展性的关键
C++从入门到精通:3.5设计模式——提升代码可维护性与可扩展性的关键
|
20天前
|
设计模式 算法 Java
23种设计模式,模板方法模式的概念优缺点以及JAVA代码举例
【4月更文挑战第10天】模板方法模式是一种行为设计模式,它定义了一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些特定步骤。
17 0
|
21天前
|
设计模式 Java
23种设计模式,状态模式的概念优缺点以及JAVA代码举例
【4月更文挑战第9天】状态模式是一种行为设计模式,允许一个对象在其内部状态改变时改变它的行为,这个对象看起来似乎修改了它的类。
29 4
|
22天前
|
设计模式 Java
23种设计模式,命令模式的概念优缺点以及JAVA代码举例
【4月更文挑战第7天】命令模式是一种行为设计模式,它将请求或简单操作封装为一个对象。这种模式允许用户通过调用对象来参数化其他对象的方法,并能保存、排队和执行方法调用。
22 1
|
26天前
|
设计模式 Java Windows
23种设计模式,抽象工厂模式的概念优缺点以及JAVA代码举例
【4月更文挑战第10天】抽象工厂模式是一种创建型设计模式,它提供了一个接口用于创建相关或依赖对象的家族,而不需要指定具体类。该模式允许客户端在不知道具体类的情况下,通过其共同的接口来创建一组产品。
30 7
|
1月前
|
设计模式 数据采集 缓存
设计模式取舍之道:代码复杂度权衡
设计模式取舍之道:代码复杂度权衡
39 1