简介
建造者模式是创建型模式的一种,其作用是解决复杂对象的创建问题。对于一个复杂对象,其某些属性是必须的,有些则是非必须的,这种情况就非常适用于创建者模式。创建者模式在各种项目中也大量应用,一般只要方法最后是.build()方法的,都是创建者模式,如Spark中的SparkSession的创建,Java的StringBuilder都是创建者模式的实际应用。下面以创建一台汽车为例来详细说明。
传统实现示例
首先新建一个Car类,设置其4个属性和包含全部参数的构造方法:
public class Car {
private String engine;
private String body;
private String os;
private String electric;
private Car(String engine, String body, String os, String electric) {
this.engine = engine;
this.body = body;
this.os = os;
this.electric = electric;
}
}
在Car类中新增一个CarBuilder的静态内部类,其类的属性与Car一致,并在类中设置其各个属性的方法:
public class Car {
private String engine;
private String body;
private String os;
private String electric;
private Car(String engine, String body, String os, String electric) {
this.engine = engine;
this.body = body;
this.os = os;
this.electric = electric;
}
public static class CarBuilder {
private String engine;
private String body;
private String os;
private String electric;
private CarBuilder(){}
private CarBuilder engine(String engine) {
this.engine = engine;
return this;
}
public CarBuilder body(String body) {
this.body = body;
return this;
}
public CarBuilder os(String os) {
this.os = os;
return this;
}
public CarBuilder electric(String electric) {
this.electric = electric;
return this;
}
public Car build() {
return new Car(engine, body, os, electric);
}
}
public static CarBuilder builder() {
return new CarBuilder();
}
@Override
public String toString() {
return "Car{" +
"engine='" + engine + '\'' +
", body='" + body + '\'' +
", os='" + os + '\'' +
", electric='" + electric + '\'' +
'}';
}
}
客户端调用:
public class Test {
public static void main(String[] args) {
Car car = Car.builder().body("body").electric("ele").engine("engine").build();
System.out.println(car.toString());
}
}
总结
建造者模式的常规写法大致就是如此,其余版本的都是大同小异。
题外话->lombok的建造者模式
对于使用lombok插件,有两种实现方式,分别是传统的建造者模式和链式写法:
lombok建造者
实现方式很简单,只需要在类中加上@Builder注解(我这里加了@Data注解是为了方便我测试时使用toString()方法) lombok的pom为:
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
</dependencies>
import lombok.Builder;
import lombok.Data;
@Builder
@Data
public class Car1 {
private String engine;
private String body;
private String os;
private String electric;
}
客户端调用:
public class LombokTest {
public static void main(String[] args) {
Car1 car = Car1.builder().body("lombok_body").electric("lombok_electric").engine("lombok_engine").build();
System.out.println(car.toString());//Car1(engine=lombok_engine, body=lombok_body, os=null, electric=lombok_electric)
}
}
lombo的链式写法
链式写法也只需要加锁@Accessors(chain = true)和@Data两个注解即可:
import lombok.Data;
import lombok.experimental.Accessors;
@Accessors(chain = true)
@Data
public class Car1 {
private String engine;
private String body;
private String os;
private String electric;
}
客户端调用
public class LombokTest {
public static void main(String[] args) {
Car1 car1 = new Car1().setBody("lombok_chain_body").setElectric("lombok_chain_electric").setEngine("lombok_chain_engine");
System.out.println(car1.toString());//Car1(engine=lombok_chain_engine, body=lombok_chain_body, os=null, electric=lombok_chain_electric)
}
}
再说一句
对于lombok插件,喜欢的人认为其能解决大量的重复代码,并且当新增或者删除了一个字段时,我们不需要更改其setter、getter和toString()方法,让代码更加简洁。但同时,也有人认为其让代码处于亚健康状态,对于某些特定的set和get,还需要重新编写。因此,对于lombok的使用,就是仁者见仁智者见智了。