场景
大家有没有碰到过类对象非常的复杂,有些参数是必须有的,但是有些参数又是可选的.例如下面这个类:有很多很多的成员变量,如何构造这个类?
public class Sekiro{
// 姓名(必须)
private String name;
// 年龄(必须)
private String sex;
// 武器(必须)
private String weapon;
// 手里剑(可选)
private String swordInHand;
// 机关斧(可选)
private String mechanizedAxe;
// 吹火筒(可选)
private String blowpipe;
...
折叠构造函数模式
先来看第一种方式:折叠构造函数模式
public Sekiro(String name, String sex, String weapon) {
this.name = name;
this.sex = sex;
this.weapon = weapon;
}
public Hero(String name, String sex, String weapon, String swordInHand) {
this.name = name;
this.sex = sex;
this.weapon = weapon;
this.swordInHand = swordInHand;
}
public Hero(String name, String sex, String weapon, String mechanizedAxe,String blowpipe) {
this.name = name;
this.sex = sex;
this.mechanizedAxe = mechanizedAxe;
this.blowpipe = blowpipe;
}
...
代码阅读以及使用不方便,每次使用需要知道调用哪种构造方法,当参数很多时还需要注意参数顺序,易出错。
JavaBean模式
第二种方式:JavaBean模式,创建一个对象,对其中的成员属性依次set(),get()
public Sekiro() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
...
在构建的过程中对象的状态容易发生变化,造成错误。
构建者模式
针对以上问题,所以才有了Builder模式。当一个类对象非常复杂,构造的参数很多,并且这些参数是可选的,可以考虑使用构建者。
- Builder
构建者接口,定义创建一个Product对象所需的各个部件的操作- ConcreteBuilder
具体的构建器实现,实现各个部件的创建,并负责组装Product对象的各个部件,同时还提供一个让用户获取组装完成后的产品对象的方法- Director
指导者,主要用来使用Builder接口,以一个统一的过程来构建所需要的Product对象。- Product
产品,表示被构建器构建的复杂对象。
针对上述问题使用构建者模式:
1.创建类Sekiro,包含所有成员变量字段(只实现所有成员的get方法)(final修饰必有的成员)
2.创建Sekiro的内部类Builder,拥有Sekiro所有成员变量
3.Builder实现所有的变量的set方法
4.私有化Sekiro构造方法,只能从Builder中赋值获取
5.提供一个返回Sekiro的方法
// 1.创建类Sekiro,包含所有成员变量字段(只实现所有成员的get方法)
public class Sekiro {
// 姓名(必须)
private String name;
// 年龄(必须)
private String sex;
// 武器(必须)
private String weapon;
// 手里剑(可选)
private String swordInHand;
// 机关斧(可选)
private String mechanizedAxe;
// 吹火筒(可选)
private String blowpipe;
// 4.私有化Sekiro构造方法,外部只能通过Builder获取
private Sekiro(Builder builder) {
this.name = builder.name;
this.sex = builder.sex;
this.weapon = builder.weapon;
this.swordInHand = builder.swordInHand;
this.mechanizedAxe = builder.mechanizedAxe;
this.blowpipe = builder.blowpipe;
}
@Override
public String toString() {
return "Sekiro{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", weapon='" + weapon + '\'' +
", swordInHand='" + swordInHand + '\'' +
", mechanizedAxe='" + mechanizedAxe + '\'' +
", blowpipe='" + blowpipe + '\'' +
'}';
}
// 2.创建Sekiro的内部类Builder,拥有Sekiro所有成员变量(final修饰必有的成员)
static class Builder {
// 姓名(必须)
private final String name;
// 年龄(必须)
private final String sex;
// 武器(必须)
private final String weapon;
// 手里剑(可选)
private String swordInHand;
// 机关斧(可选)
private String mechanizedAxe;
// 吹火筒(可选)
private String blowpipe;
// final修饰的参数为必传
public Builder(String name, String sex,String weapon) {
this.name = name;
this.sex = sex;
this.weapon = weapon;
}
// 3.Builder类设置成员参数,实现所有的变量的set方法
// 返回builder对象,链式编程
public Builder setSwordInHand(String swordInHand) {
this.swordInHand = swordInHand;
return this;
}
public Builder setMechanizedAxe(String mechanizedAxe) {
this.mechanizedAxe = mechanizedAxe;
return this;
}
public Builder setBlowpipe(String blowpipe) {
this.blowpipe = blowpipe;
return this;
}
// 5.提供一个返回Sekiro的方法
public Sekiro builder() {
return new Sekiro(this);
}
}
}
// 测试
public static void main(String[] args) {
Sekiro sekiro1 = new Sekiro.Builder("只狼", "男", "楔丸")
.setMechanizedAxe("机关斧")
.builder();
Sekiro sekiro2 = new Sekiro.Builder("只狼2", "男", "不死斩拜泪")
.setMechanizedAxe("机关斧")
.setSwordInHand("手里剑")
.builder();
Sekiro sekiro3 = new Sekiro.Builder("只狼3", "男", "不死斩开门")
.setMechanizedAxe("机关斧")
.setMechanizedAxe("手里剑")
.setSwordInHand("吹火筒")
.builder();
System.out.println("第一只狼:"+sekiro1);
System.out.println("第二只狼:"+sekiro2);
System.out.println("第三只狼:"+sekiro3);
}
// 输出
第一只狼:Sekiro{name='只狼', sex='男', weapon='楔丸', swordInHand='null', mechanizedAxe='机关斧', blowpipe='null'}
第二只狼:Sekiro{name='只狼2', sex='男', weapon='不死斩拜泪', swordInHand='手里剑', mechanizedAxe='机关斧', blowpipe='null'}
第三只狼:Sekiro{name='只狼3', sex='男', weapon='不死斩开门', swordInHand='吹火筒', mechanizedAxe='手里剑', blowpipe='null'}
总结
构建者模式是一种强大且灵活的设计模式,可用于构建复杂对象。通过使用构建者模式,我们可以避免在构造函数中传入大量参数,并且能够创建不同表示的对象。