什么是建造者模式?
建造者模式是一种创建型模式,
建造者模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创造不同的表示。建造对象的时候只需要指定需要建造的类型,而不必了解具体的建造过程。
主要特点是通过逐步添加单体对象形成一个复杂的对象。
可以参考https://blog.csdn.net/u010102390/article/details/80179754
解释得非常好
建造者模式中有原型写法和链式写法
原型写法
经典Buider模式分为四块:
Product
:被构造的复杂对象
Builder
:抽象接口
BuilderImpl
:抽象接口的具体实现
Director
:接口的构造者和使用者
经典图示
实体User类(Product)
public class User {
String id;
String name;
String password;
String phone;
//set/get方法
@Override
public String toString() {
return "User{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", password='" + password + '\'' +
", phone='" + phone + '\'' +
'}';
}
}
抽象建造者/建造者接口(Builder)
public interface Build {
void makeId(String val);
void makeName(String val);
void makePassword(String val);
void makePhone(String val);
User makeUser();
}
具体建造者(BuilderImpl)
public class AdminBuilder implements Build{
User user=new User();
@Override
public User makeUser(){
return user;
}
@Override
public void makeId(String val) {
user.setId(val);
}
@Override
public void makeName(String val) {
user.setName(val);
}
@Override
public void makePassword(String val) {
user.setPassword(val);
}
@Override
public void makePhone(String val) {
user.setPhone(val);
}
}
Admin指导建造者创建User(Director)
public class Admin {
private AdminBuilder adminBuilder;
public void setAdminBuilder(AdminBuilder adminBuilder) {
this.adminBuilder = adminBuilder;
}
public User makeUser(String id,String name,String password,String phone){
adminBuilder.makeId(id);
adminBuilder.makeName(name);
adminBuilder.makePassword(password);
adminBuilder.makePhone(phone);
return this.adminBuilder.makeUser();
}
}
具体main类
public static void main(String[] args){
AdminBuilder adminBuilder=new AdminBuilder();
Admin admin=new Admin();
admin.setAdminBuilder(adminBuilder);
User user=admin.makeUser("1","张三","123456","88888888");
System.out.println(user.toString());
}
AdminBuilder adminBuilder=new AdminBuilder();
new
具体建造者
Admin admin=new Admin();
new
出Admin
指导建造者
admin.setAdminBuilder(adminBuilder);
准备开始建造(不写会报空指针)
User user=admin.makeUser()
根据Admin
的建造方法创建User
运行输出
UML类图
链式写法(非常推荐)
链式写法是在原型写法的基础上做优化,有些时候Builder
的创建部分有默认值,或者不需要的情况下,而产生不同的Product
,通过以上方式,就需要修改Director
类和Builder
类,再或者根据不同的创建顺序,生成不同的结果,也需要修改Director
类。Director
似乎显得很不稳定和多余。可以通过Builder
自身的调用逻辑来生成Product
,即链式调用
使用IDEA的插件生成代码
首先先在IDEA
中安装InnerBuilder
插件,可以在实体类中自动生成建造者模式的链式写法
InnerBuilder
插件的官方介绍:http://plugins.jetbrains.com/plugin/7354-innerbuilder
用法:安装好插件后在实体类中按下alt+insert
,然后选择Builder
实体User类
public class User {
String id;
String name;
String password;
String phone;
private User(Builder builder) {
id = builder.id;
name = builder.name;
password = builder.password;
phone = builder.phone;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getPassword() {
return password;
}
public String getPhone() {
return phone;
}
@Override
public String toString() {
return "User{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", password='" + password + '\'' +
", phone='" + phone + '\'' +
'}';
}
public static final class Builder {
private String id;
private String name;
private String password;
private String phone;
public Builder() {
}
public Builder id(String val) {
id = val;
return this;
}
public Builder name(String val) {
name = val;
return this;
}
public Builder password(String val) {
password = val;
return this;
}
public Builder phone(String val) {
phone = val;
return this;
}
public User build() {
return new User(this);
}
}
}
重点(相比于普通JavaBean的好处):
在建造者模式中,提供一个辅助的静态建造器Builder
(静态内部类),可以在里面set
实体类的属性,与JavaBean
不同的是,建造者是先set
,在通过build
实例化实体类,这样既可以提高代码的阅读性,也可以防止对象没有实例化,就被调用;不会造成不一致性,同时解决了Javabean
模式的线程安全问题
具体main类
public static void main(String[] args){
User user=new User.Builder().id("1").name("张三").password("123456")
.phone("15820638007").build();
System.out.println(user.toString());
}
运行输出
UML类图
总结:
Director
角色并非多余,能把复杂的Product
创建过程对外隐藏,使Builder
部件和创建过程分离,各方易于扩展,降低了耦合度。当需要对一个对象设置很多属性,此时就能方便的使用链式调用来提高编码速度和代码可读性。