登录
    Technology changes quickly but people's minds change slowly.

EffectiveJava-创建和销毁对象-多个构造器参数考虑使用构建器

技术宅 破玉 1146次浏览 0个评论

  当我们的类有多个成员变量,我们使用构造器或者静态工厂创建他的实例可能就不是那么方便了,这时候,我们需要考虑其他方式,方便我们开发。
一种方式是方法注入:提供get,set 方法,需要什么参数 set 什么参数。 遗憾的是, javaBeans 模式自身有着很严重的缺点 因为构造过程被分到了几个调用中,在构造过程中 Java Bean 可能处于不一致的状态。
​    类无法仅仅通过检验构造器参数的有效性来保证一致性 试图使用处于不 一致状态的对象将会导致失败,这种失败与包含错误的代码大相径庭,因调试起来十分困难 与此相关的另一点不足在于, Java Beans 模式使得把
类做成不可变的可能性不复存在,这就需要程序员 付出 的努力来确保的线程安全。
​    还有第三种替代方法,它既能保证像重叠构造器模式那样的安全性,也能保证像 JavaBean 模式那么好的可读性。这就是构建器模式, 它不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器(或者静态工厂),得到一个 builder 对象 然后客户端在 builder 对象上调用类 setter的方法,来设置每个相关的可选参数 最后 客户端调 无参 build 方法来生成通常是不可变的对象。
示例如下:

public class MagicUser {
    private String name;
    private String nickName;
    private String userName;
    private String firstName;
    private String lastName;

    public static class Builder{
        private String name;
        private String nickName;
        private String userName;
        private String firstName;
        private String lastName;
        public Builder name(String name){
            this.name=name;
            return this;
        }
        public Builder nickName(String nickName){
            this.nickName=nickName;
            return this;
        }
        public Builder userName(String userName){
            this.userName=userName;
            return this;
        }
        public Builder firstName(String firstName){
            this.firstName=firstName;
            return this;
        }
        public Builder lastName(String lastName){
            this.lastName=lastName;
            return this;
        }
        public MagicUser build(){
            return new MagicUser(this);
        }
    }

    private MagicUser(Builder builder){
        this.name=builder.name;
        this.nickName=builder.nickName;
        this.userName=builder.userName;
        this.firstName=builder.firstName;
        this.lastName=builder.lastName;
    }


}
public class Test {
    public static void main(String[] args) {
        MagicUser user=new MagicUser.Builder().userName("hello").build();
    }
}

构建器模式的代码易写,可读性好,类似于Python和Scala的可选参数。

  Builder 模式十分灵活,可以利用单个 builder 构建 个对象 builder 的参数可以在调用build 方法来创建对象期间进行调整,也可以随着不同的对象而改变 builder 可以自动填充某些域, 例如每次创建对 时自动增加序列号。

  Builder 模式的确 有它自身的不 为了创建对象 ,必 须先 创建它 的构 建器 虽然创建这个构建器的开销在实践中可能不那么明显 但是在某些十分注重性能 的情况下,可能就成问题了 Builder 模式还 比重 叠构造器模式 更加冗 ,因此它只在有很多 参数 的时候才使用,比如 4个或者更多个参数 。

  简而言之 如果类的构造器或者静态工厂中具有多个参数,设计这种类时, Builder模式就是一种不错的选择, 特别是当大多数参数都是可选或者类型相同的时候 与使用重叠构造器模式相比,使用 Builder 模式 的客户端代码将更 易于 阅读和编写,构建器也比JavaBeans 更加安全。


华裳绕指柔, 版权所有丨如未注明 , 均为原创|转载请注明EffectiveJava-创建和销毁对象-多个构造器参数考虑使用构建器
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址