专注IT技术、资源分享!
【设计模式系列】建造者模式
【设计模式系列】建造者模式

【设计模式系列】建造者模式

前言

建造者设计模式和工厂模式,抽象工厂模式一样也是创建型设计模式之一。

如果在需要创建一个对象时,该对象包含大量的参数,使用工厂模式或抽象工厂模式会存在一些问题。为了解决这些问题,可以使用建造者模式。

工厂模式和抽象工厂模式在这种情况下主要存在下列问题:

  • 有太多参数需要从客户端传递给工厂类,这很容易出错,尤其是当有很多数据类型一样的参数时,很难正确维护参数的顺序;
  • 如果有参数是可选的,则需要在参数列表中传递NULL值;
  • 如果对象很重,创建起来很复杂,那么这些复杂性都会侵入到工厂类中;
  • 这种问题虽然可以通过提供一个包含所有必须参数的构造方法,然后其他可选参数使用setter方法来设置,但是这样容易造成对象状态的不一致。

为了解决这一系列问题,在建造者模式中,通过提供一种逐步构建对象的方法,并将最终对象返回,可以解决大量参数和对象状态不一致的问题。

建造者模式结构

如果实现建造者设计模式,主要分以下步骤:

  • 首先创建一个静态内部类,将所有需要构建对象的属性赋值到内部类中;按照约定的命名规范,一般命名为XXXBuilder,比如需要创建一个Computer对象,则静态内部类为ComputerBuilder;
  • 这个Builder类需要提供一个包含所有参数的构造方法;
  • 然后Builder类还需要提供设置可选参数的方法,该设置方法需要将Builder对象返回;
  • 最后需要在Builder类中提供build()方法,该方法将返回客户端最终需要的对象,也就是Computer对象。

代码结构如下:

package com.heiz.design.builder;

/**
* @author 小黑说Java
* @ClassName Computer
* @Description
* @date 2021/11/20
**/

public class Computer {

   //必选参数
   /**
    * 硬盘
    */
   private String HDD;
   /**
    * 内存
    */
   private String RAM;

   // 可选参数
   /**
    * 显卡
    */
   private boolean isGraphicsCardEnabled;
   /**
    * 蓝牙
    */
   private boolean isBluetoothEnabled;


   public String getHDD() {
       return HDD;
  }

   public String getRAM() {
       return RAM;
  }

   public boolean isGraphicsCardEnabled() {
       return isGraphicsCardEnabled;
  }

   public boolean isBluetoothEnabled() {
       return isBluetoothEnabled;
  }

   private Computer(ComputerBuilder builder) {
       this.HDD = builder.HDD;
       this.RAM = builder.RAM;
       this.isGraphicsCardEnabled = builder.isGraphicsCardEnabled;
       this.isBluetoothEnabled = builder.isBluetoothEnabled;
  }

   //Builder Class
   public static class ComputerBuilder {

       //必选参数
       /**
        * 硬盘
        */
       private String HDD;
       /**
        * 内存
        */
       private String RAM;

       // 可选参数
       /**
        * 显卡
        */
       private boolean isGraphicsCardEnabled;
       /**
        * 蓝牙
        */
       private boolean isBluetoothEnabled;

       public ComputerBuilder(String hdd, String ram) {
           this.HDD = hdd;
           this.RAM = ram;
      }

       public ComputerBuilder setGraphicsCardEnabled(boolean isGraphicsCardEnabled) {
           this.isGraphicsCardEnabled = isGraphicsCardEnabled;
           return this;
      }

       public ComputerBuilder setBluetoothEnabled(boolean isBluetoothEnabled) {
           this.isBluetoothEnabled = isBluetoothEnabled;
           return this;
      }

       public Computer build() {
           return new Computer(this);
      }
  }
}

需要注意,Computer类只有getter方法,没有公共构造函数。因此,获得Computer对象的唯一方法是通过ComputerBuilder类。

然后我们使用一个简单的测试,来测一下我们的代码:

package com.heiz.design.builder;

/**
* @author 小黑说Java
* @ClassName BuilderTest
* @Description
* @date 2021/11/20
**/
public class BuilderTest {
   public static void main(String[] args) {
       Computer computer = new Computer.ComputerBuilder("500GB", "2 GB")
              .setBluetoothEnabled(false)
              .setGraphicsCardEnabled(true)
              .build();
  }
}

建造者模式的优点

使用建造者模式将创建对象的可变属性和不可变属性进行分离,对于客户端只能使用建造者创建对象,不用关心创建细节,所以建造者模式更易于扩展,便于控制细节风险。

JDK中的建造者模式

在JDK中最典型的建造者模式就是我们常用的StringBuilder和StringBuffer:

  • java.lang.StringBuilder#append() 线程不安全
  • java.lang.StringBuffer#append() 线程安全

以上就是本期建造者模式的全部内容,如果对你有所帮助,点个赞是对我最大的鼓励。

发表回复

您的电子邮箱地址不会被公开。