Builder建造者模式+链式调用

(本文仅适用于初学者,大牛请绕道,如有错误,欢迎指正)

正常情况下,声明一个User类,然后列出几条属性,这个时候IDE会提示说缺少初始化方法。然后就直接构建构造方法,像这样

public class User {
    private final String eyes;
    private final String name;
    private final int age;
    private final String mouth;

    //构造方法
    public User(String eyes, String name, int age, String mouth) {
        this.eyes = eyes;
        this.name = name;
        this.age = age;
        this.mouth = mouth;
    }
}

从上面代码可以看出,虽然只有4个属性,但是构造方法的参数已经显得很累赘了,这个时候就需要用到Builder模式先来简化参数的个数。

  1. 在User类中建一个静态Builder类。注意,只需设置一两个属性为final类型(通常是作为唯一识别的标志)
  2. 具有final类型的属性添加构造方法,其他的属性为返回值为Builder类型的普通方法。
public static class UserBuilder1{
        private final String name;

        //其他都没有final
        private  String eyes;
        private  int age;
        private  String mouth;
    
        //构造方法
        public UserBuilder1(String name) {
            this.name = name;
        }

        //返回值类型为UserBuilder1的,方法名为age的方法
        public UserBuilder1 age(int age){
            this.age = age;
            return this;
        }
        public UserBuilder1 mouth(String mouth){
            this.mouth = mouth;
            return this;
        }
        public UserBuilder1 eyes(String eyes){
            this.eyes = eyes;
            return this;
        }  
}
  1. 此时代码1中的构造方法可以被替换为Builder类型。 再加上get方法获取属性的值
    //参数这里不再是很多个单独的属性,而是对象,这也符合面向对象的逻辑
    public User(UserBuilder1 userBuilder1) {
        this.eyes = userBuilder1.eyes;
        this.age = userBuilder1.age;
        this.mouth = userBuilder1.mouth;
        this.name = userBuilder1.name;
    }
    
    //加上get方法为了以后获得当前对象某个属性的值
    public int getAge() {
        return age;
    }
    public String getEyes() {
        return eyes;
    }
    public String getMouth() {
        return mouth;
    }
    public String getName() {
        return name;
    }
  1. 以上的步骤仅是在构造方法的参数上进行了封装,简化参数的个数。但是UserBuilder1类的最本质目的是————构建User类,并且自由地访问它的属性,如果是声明属性不创建build(),对象就无法正确创建和被访问。 所以我们在UserBuilder中声明build方法
public User build(){
    User user = new User(this);
    return user;
}

这里的this是UserBuilder1本身,对应的是 public User(UserBuilder1 userBuilder1)

另外如果有什么线性安全的要求,就加一些判断条件

public User build() {
    //由于Builder是非线程安全的,所以如果要在Builder内部类中检查一个参数的合法性,
    // 必需要在对象创建完成之后再检查
    
    User user = new User(this);
    if (user.getAge() < 0 || user.getAge() > 255) {
        throw new IllegalStateException("Age out of range:" + user.getAge());//线程安全
            }
            return user;
}
  1. 建一个Main方法,体验链式调用的便利
public static void main(String[] args) {
    User user = new User.UserBuilder1("LL").age(18).eyes("BLACK").mouth("red").build();

}

以下是全部代码,自行体会两者的效果

效果一(链式+Builder)
public class UserDemo {
    private final String eyes;
    private final String name;
    private final int age;
    private final String mouth;

    public UserDemo(UserBuilder1 userBuilder1) {
        this.eyes = userBuilder1.eyes;
        this.age = userBuilder1.age;
        this.mouth = userBuilder1.mouth;
        this.name = userBuilder1.name;
    }

    public int getAge() {
        return age;
    }
    public String getEyes() {
        return eyes;
    }
    public String getMouth() {
        return mouth;
    }
    public String getName() {
        return name;
    }

    public static class UserBuilder1{
        private final String name;

        //其他都没有final
        private  String eyes;
        private  int age;
        private  String mouth;
        //构造方法
        public UserBuilder1(String name) {
            this.name = name;
        }

        //返回值类型为UserBuilder1的,名称的age的方法
        public UserBuilder1 age(int age){
            this.age = age;
            return this;
        }
        public UserBuilder1 mouth(String mouth){
            this.mouth = mouth;
            return this;
        }
        public UserBuilder1 eyes(String eyes){
            this.eyes = eyes;
            return this;
        }

        public UserDemo build(){
            UserDemo userDemo = new UserDemo(this);
            return userDemo;
        }
    }

    public static void main(String[] args) {
        UserDemo user = new UserDemo.UserBuilder1("LL").age(18).eyes("BLACK").mouth("red").build();
    }
}
效果二(没有链式)
public class UserDemo2 {
    private final String eyes;
    private final String name;
    private final int age;
    private final String mouth;

    public UserDemo2(String eyes, String name, int age, String mouth) {
        this.eyes = eyes;
        this.name = name;
        this.age = age;
        this.mouth = mouth;
    }

    public int getAge() {
        return age;
    }
    public String getEyes() {
        return eyes;
    }
    public String getMouth() {
        return mouth;
    }
    public String getName() {
        return name;
    }


    public static void main(String[] args) {
        //UserDemo2 user = new UserBuilder1("LL").age(18).eyes("BLACK").mouth("red").build();
        UserDemo2 userDemo2 = new UserDemo2("BLACK","LL",18,"red");
        System.out.println(userDemo2.getAge());
    }
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值