目录
一.概述
建造者模式即将对象的创建分成构造(不同属性的设置)和装配(设置不同属性的顺序)两部分,从而可以构造出复杂的对象。
二.结构
抽象建造者类(Builder):定义要实现复杂对象的哪些部分(属性)的创建,并不涉及具体对象部件的创建。
具体建造者类:实现抽象构造者,完成复杂产品的各个部件的具体创建方法,在构造完成后,提供产品的实例。
产品类:创建的复杂对象。
指挥者类:调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建。
三.案例
一个汽车有发动机和轮胎品牌等等。
汽车类
/**
* 汽车类
*/
public class Car {
//发动机
private String engine;
//轮胎
private String tyre;
public String getEngine() {
return engine;
}
public void setEngine(String engine) {
this.engine = engine;
}
public String getTyre() {
return tyre;
}
public void setTyre(String tyre) {
this.tyre = tyre;
}
@Override
public String toString() {
return "Car{" +
"engine='" + engine + '\'' +
", tyre='" + tyre + '\'' +
'}';
}
}
建造者
/**
* 抽象建造者类
*/
public abstract class Builder {
//定义一个Car
protected Car car=new Car();
//建造发动机
public abstract void createEngine();
//建造轮胎
public abstract void createTyre();
//构建汽车
public abstract Car createCar();
}
/**
* 具体构造者类
*/
public class BYD_han_Builder extends Builder{
@Override
public void createEngine() {
car.setEngine("BYD自研发动机");
}
@Override
public void createTyre() {
car.setTyre("固特异");
}
@Override
public Car createCar() {
return car;
}
}
指挥者
public class Director {
//声明builder类型变量
private Builder builder;
public Director(Builder builder){
this.builder=builder;
}
//组装汽车
public Car construct(){
builder.createEngine();
builder.createTyre();
return builder.createCar();
}
}
测试
public class MAIN {
public static void main(String[] args) {
Director director = new Director(new BYD_han_Builder());
Car BYD_han = director.construct();
System.out.println(BYD_han);
}
}
以上是常规用法。在程序设计中,也可以将指挥者与抽象建造者结合,即在建造者中加入指挥者。
例:
/**
* 抽象建造者类
*/
public abstract class Builder {
//定义一个Car
protected Car car=new Car();
//建造发动机
public abstract void createEngine();
//建造轮胎
public abstract void createTyre();
//构建汽车
public abstract Car createCar();
//组装汽车
public Car construct(){
this.createEngine();
this.createTyre();
return this.createCar();
}
}
四.建造者模式优缺点
优点:
封装性好。
将产品本身与产品的创建解耦。
可以更加精细的控制产品的创建过程。将复杂的产品创建步骤分解在不同的方法中,使创建过程更加清晰。
添加新产品时不用修改源代码,只需实现Builder接口,符合开闭原则。
缺点:
只适合复杂的对象创建,且创建的产品一班有较多共同点,即组成部分相似。
五.模式扩展
建造者模式除了上面的用途外,还可以用在创建一个参数很多的对象中,即链式构造。
例:
仍以汽车的创建为例。
/**
* 汽车类
*/
public class Car {
//发动机
private String engine;
//轮胎
private String tyre;
//私有构造方法
private Car(Builder builder){
//外部类可以直接访问内部类中的属性和方法
this.engine=builder.engine;
this.tyre=builder.tyre;
}
//静态内部类
public static final class Builder{
//发动机
private String engine;
//轮胎
private String tyre;
//创建发动机
public Builder createEngine(String engine){
this.engine=engine;
return this;
}
//创建轮胎
public Builder createTyre(String tyre){
this.tyre=tyre;
return this;
}
//组装汽车
public Car build(){
return new Car(this);
}
}
@Override
public String toString() {
return "Car{" +
"engine='" + engine + '\'' +
", tyre='" + tyre + '\'' +
'}';
}
}
测试
public class MAIN {
public static void main(String[] args) {
Car.Builder builder = new Car.Builder();
Car BYD = builder
.createEngine("BYD自研发动机")
.createTyre("固特异")
.build();
System.out.println(BYD);
}
}
即可以在产品类中定义一个Builder内部类,先在内部类中建造好产品各部件(属性),最后再通过Builder类进行赋值(组装),创建产品类。
使用此方式可以让代码使用起来更加的方便,也更能清楚每个参数所代表的意思,可以提升开发效率。
六.常见案例
很多工具类也使用此方式创建对象,常见的比如:lombok工具类中@Builder注解。
代码分析:
import lombok.Builder;
@Builder
public class Car {
private String engine;
private String tyre;
}
创建了一个类,在类上加上了@Builder注解,下面进行编译,看一下其编译后的文件。
.class文件
public class Car {
private String engine;
private String tyre;
Car(final String engine, final String tyre) {
this.engine = engine;
this.tyre = tyre;
}
public static Car.CarBuilder builder() {
return new Car.CarBuilder();
}
public static class CarBuilder {
private String engine;
private String tyre;
CarBuilder() {
}
public Car.CarBuilder engine(final String engine) {
this.engine = engine;
return this;
}
public Car.CarBuilder tyre(final String tyre) {
this.tyre = tyre;
return this;
}
public Car build() {
return new Car(this.engine, this.tyre);
}
public String toString() {
return "Car.CarBuilder(engine=" + this.engine + ", tyre=" + this.tyre + ")";
}
}
}
通过查看其编译后的.class文件,我们发现其使用了建造者模式,只不过其外部类并没有设置成私有,仍可以直接创建外部类对象
总结
建造者模式注重部件建造的过程,而工厂方法模式和抽象工厂模式注重的是整体对象创建的方式。在使用中有时会将抽象工厂模式与建造者模式结合,抽象工厂负责创建部件,建造者负责组装。