1.遇到多个构造器参数时要考虑用构建器 注意是构建器不是构造器 说白了就是Builder设计模式。
- 无论是构造器(构造函数)还是静态工厂方法都有一个共同的局限性 那就是他们都很难扩展到大量的可选参数。
- 面对好多参数的时候我们可以用重叠构造器 (就是从第一个参数到最后一个参数的一次递增的创建构造器)。这样是可以解决问题但是很麻烦。
- 为了解决重叠构造器的麻烦冗长 我们引进了javabean模式就是创建一个无参的构造器 然后set get 属性。但是这种模式劣势就是构造的过程被分到几个调用中,在构造中可能处于不一致状态,无法保证一致性。多个线程 同时使用一个实例并且都在set的时候就可能乱了。出现不一致状态那个时候我们要额外的去确保他线程安全。
- javabeans 模式阻止了把类变成不可变的可能 什么是不可变的类(其实例不能被修改的类,每个实例包含的信息都必须在创建实例的时候提供,并在对象的整个生命周期内固定不变)
- build模式 既能保证像重叠构造器那样的安全,也能实现JavaBean模式那样的可读性。Builder模式可以将一个类的构建和表示进行分离。
- Builder模式:优点是可以将构造器的setter方法名取成类似注释的方式,这样我们可以很清晰的知道刚才究竟设置的什么值,可读性较高,缺点是比较冗长。
2.Builder模式的步骤:
- 不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器(或者静态工厂),得到一个build对象。
- 让客户端在build对象上调用类似的setter方法来设置每个相关的可选参数, 类似javaBeans模式。
最后,客户端调用无参的build方法来生成不可变的对象。这个builder是它构建的静态成员类。
package com.orbis.squery; /** * @author squery * @date 2018/6/14 * @version v1.0.0 * @description * @modified by */ public class Student { private int id; private String name; private String passwd; private String sex; private String address; // 构造器尽量缩小范围 private Student() { } // 构造器尽量缩小范围 private Student(Student origin) { // 拷贝一份 this.id = origin.id; this.name = origin.name; this.passwd = origin.passwd; this.sex = origin.sex; this.address = origin.address; } public int getId() { return id; } public String getName() { return name; } public String getPasswd() { return passwd; } public String getSex() { return sex; } public String getAddress() { return address; } /** * Student的创建完全依靠Student.Builder,使用一种方法链的方式来创建 * */ public static class Builder { private Student target; public Builder() { target = new Student(); } public Builder address(int id) { target.id = id; return this; } public Builder name(String name) { target.name = name; return this; } public Builder password(String passwd) { target.passwd = passwd; return this; } public Builder sex(String sex) { target.sex = sex; return this; } public Builder address(String address) { target.address = address; return this; } public Student build() { return new Student(target); } } }
Student并不是直接new出来的,对其构造器进行了处理使其可访问范围尽可能的小,只让它通过Student.Builder来构建自己,在Student.Builder中提供了一种类set的方法链的方式来设置值,然后在最后的build()方法的时候会返回一个Student对象,现在要创建一个Student对象,
Student s=new Student.Builder().name("CC").password("qwerty").sex("男") .address("银河系第二旋臂").build();