简介
说明
本文用Java实战来介绍建造者模式的写法,让你彻底掌握建造者模式。
建造者模式的优点
建造者模式可以为构建对象提供如下便利:
- 可以只指定某几个属性。
 - 可以肉眼可见地给某个属性赋值,不需要再点进去看构造方法的定义。
 
实战
需求:构建一个User对象。
原始写法
用户实体类
package com.knife.designPattern.entity;
import lombok.Data;
/**
 * 用户实体类
 */
@Data
public class User {
    private String username;
    private String email;
    private String phone;
    public User(String username, String email, String phone) {
        this.username = username;
        this.email = email;
        this.phone = phone;
    }
}
测试类
package com.knife.designPattern;
import com.knife.designPattern.entity.User;
public class Test {
    public static void main(String[] args) {
        User user = new User("钢铁侠", "aa@gmail.com", "111222333");
        System.out.println(user);
    }
}
可以发现,创建一个User对象时,会遇到如下问题:
- 参数都是String,我都不知道第一个参数是什么含义,第二个是什么,必须点进来看看这个方法定义。参数少还好,参数是十个呢?二十个呢?头都大了
 - 我想只指定其中的2个参数:邮箱和电话号码。我还是要去看看这个方法定义,还得给第1个参数指定为null。同样地,参数很多时会很麻烦。
 
测试结果
User(username=钢铁侠, email=aa@gmail.com, phone=111222333)
手写建造者
用户实体类
package com.knife.designPattern.entity;
import lombok.Data;
/**
 * 用户实体类
 */
@Data
public class User {
    private String username;
    private String email;
    private String phone;
 
    public static UserBuilder builder() {
        return new UserBuilder();
    }
}
可以发现,用户实体类里持有一个用户建造者。
用户建造者
package com.knife.designPattern.entity;
 
public class UserBuilder {
    private final User user;
 
    public UserBuilder() {
        this.user = new User();
    }
 
    public UserBuilder username(String username) {
        user.setUsername(username);
        return this;
    }
 
    public UserBuilder email(String email) {
        user.setEmail(email);
        return this;
    }
 
    public UserBuilder phone(String phone) {
        user.setPhone(phone);
        return this;
    }
 
    public User build() {
        return user;
    }
}
每一个赋值方法都只设置一个属性,然后返回User这个实体类。
测试类
package com.knife.designPattern;
import com.knife.designPattern.entity.User;
public class Test {
    public static void main(String[] args) {
        User user = User.builder()
                .email("aa@gmail.com")
                .phone("111222333")
                .build();
        System.out.println(user);
    }
}
可以发现,建造者模式这种写法有如下优点:
- 可以只指定某几个属性(本处只指定了邮箱和电话)
 - 可以肉眼可见地给某个属性赋值,不需要再点进去看构造方法的定义。
 
测试结果
User(username=null, email=aa@gmail.com, phone=111222333)
用lombok生成建造者
建造者模式这么简单,就是写一个builder,里边给实体类的每个属性赋值,然后返回这个实体类对象本身。那么有没有什么简便方法?一个一个手写也太麻烦了!
答案是:有的!
lombok可以自动生成Builder,方法是:在实体类上加个@Builder即可。
实体类
package com.knife.designPattern.entity;
import lombok.Builder;
import lombok.Data;
/**
 * 用户
 */
@Builder
@Data
public class User {
    private String username;
    private String email;
    private String phone;
 
}
测试类
package com.knife.designPattern;
import com.knife.designPattern.entity.User;
public class Test {
    public static void main(String[] args) {
        User user = User.builder()
                .username("钢铁侠")
                .email("aa@gmail.com")
                .build();
        System.out.println(user);
    }
}
测试结果
User(username=钢铁侠, email=aa@gmail.com, phone=null)
怎么样?@Builder是不是超级好用!

请先 !