一、什么是建造者模式
建造者模式是一种创建型设计模式,它通过将复杂对象的构造过程分解成多个简单的步骤来使其更加灵活、可扩展和可维护。在建造者模式中,将构造过程和具体实现分离,通过调用一个指挥者的方法来创建一个完整的对象。建造者模式遵循“单一职责原则”,每个建造者只负责一部分工作。
二、为什么用建造者模式
在实际开发中,我们经常需要创建一个复杂的对象,并且这个对象的构造过程比较繁琐和复杂,这时候就可以使用建造者模式来简化对象的构造过程。建造者模式可以将对象的创建与表示分离,使得同样的构造过程可以创建不同的表示形式,且易于扩展。同时,建造者模式可以提高代码的复用性和可维护性。
三、工作中用在哪里
建造者模式通常用于创建复杂的对象,例如,Web应用程序中的表单验证、Servlet请求对象、Hibernate的Criteria查询对象等。
在Android中我们可以去构建不同功能的Dialog、网络框架、多功能的自定义View。所以说还是这种设计模式还是很常见和使用的。
个人建议:当一个类的构造函数参数个数超过4个,而且这些参数有些是可选的参数,考虑使用构造者模式。
四、设计思路
建造者模式的核心思想是将一个复杂对象的构建过程分解成多个简单的步骤,然后通过一个指挥者来统一管理这些步骤。建造者模式包含以下几个角色:
- Builder(建造者):定义用于创建对象的抽象接口,包含创建各个部分的方法。
- ConcreteBuilder(具体建造者):具体实现Builder接口中各个方法以创建对象的各个部分,同时定义返回创建结果的方法。
- Director(指挥者):负责控制建造过程,即调用Builder接口定义的各个方法以创建对象。
- Product(产品):具体要创建的复杂对象,由多个部分组成。
五、建造者模式的代码实现
下面是一个简单的建造者模式的示例代码,创建一个包含用户Id、用户名和年龄的User对象。具体建造者实现根据不同的场景来构建不同的User对象。
实现方式一:传统实现方式
Builder接口
public interface UserBuilder {
void setId(int id);
void setUsername(String username);
void setAge(int age);
User build();
}
具体建造者1
public class UserBuilderImpl1 implements UserBuilder {
private int id;
private String username;
private int age;
@Override
public void setId(int id) {
this.id = id;
}
@Override
public void setUsername(String username) {
this.username = username;
}
@Override
public void setAge(int age) {
this.age = age;
}
@Override
public User build() {
return new User(id, username, age, "builder1");
}
}
具体建造者2
public class UserBuilderImpl2 implements UserBuilder {
private int id;
private String username;
private int age;
@Override
public void setId(int id) {
this.id = id;
}
@Override
public void setUsername(String username) {
this.username = username;
}
@Override
public void setAge(int age) {
this.age = age;
}
@Override
public User build() {
return new User(id, username, age, "builder2");
}
}
指挥者
public class UserDirector {
private UserBuilder userBuilder;
public UserDirector(UserBuilder userBuilder) {
this.userBuilder = userBuilder;
}
public User construct() {
userBuilder.setId(1);
userBuilder.setUsername("Tom");
userBuilder.setAge(18);
return userBuilder.build();
}
}
产品
public class User {
private int id;
private String username;
private int age;
private String builder;
public User(int id, String username, int age, String builder) {
this.id = id;
this.username = username;
this.age = age;
this.builder = builder;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", age=" + age +
", builder='" + builder + '\'' +
'}';
}
}
测试代码
public class BuilderPatternDemo {
public static void main(String[] args) {
UserBuilder builder1 = new UserBuilderImpl1();
UserBuilder builder2 = new UserBuilderImpl2();
UserDirector director = new UserDirector(builder1);
User user1 = director.construct();
System.out.println(user1);
director = new UserDirector(builder2);
User user2 = director.construct();
System.out.println(user2);
}
}
运行结果
User{id=1, username='Tom', age=18, builder='builder1'}
User{id=1, username='Tom', age=18, builder='builder2'}
实现方式二:简单模式
简单模式在构建代码中非常常见:例如图片处理框架Glide,网络请求框架Retrofit等都使用了此模式。
步骤如下:
在User 中创建一个静态内部类 Builder,然后将User 中的参数都复制到Builder类中。
在User中创建一个private的构造函数,参数为Builder类型
在Builder中创建一个public的构造函数,参数为User中必填的那些参数,id 和username。
在Builder中创建设置函数,对User中那些可选参数进行赋值,返回值为Builder类型的实例
在Builder中创建一个build()方法,在其中构建User的实例并返回
public class User {
private final int id;//必须
private final String username;//必须
private final int age;//可选
private final String sex;//可选
private User(Builder builder){
this.id = builder.id;
this.username = builder.username;
this.age = builder.age;
this.sex = builder.sex;
}
public static class Builder{
private int id;//必须
private String username;//必须
private int age;//可选
private String sex;//可选
public Builder(String id,String username){
this.id = id;
this.username = username;
}
public Builder setAge(int age) {
this.age = age;
return this;
}
public Builder setSex(String sex) {
this.sex = sex;
return this;
}
public User build(){
return new User(this);
}
}
//省略getter方法
}
如何使用
在客户端使用链式调用,一步一步的把对象构建出来。
User user = new User.Builder("1","小M")
.setAge(24)
.setSex("男")
.build();
看到这个调用大家就知道了吧!! 很多框架构建复杂对象都是使用了这种创建对象方式。OkHttp、Glide等等。
六、总结
建造者模式是一种创建型设计模式,它能够将复杂对象的构造过程分解成多个简单的步骤,从而使其更加灵活、可扩展和可维护。建造者模式遵循"单一职责原则",每个建造者只负责一部分工作。在实际开发中,建造者模式通常用于创建复杂的对象,并且可以提高代码的复用性和可维护性。