第2条:遇到多个构造器参数时要考虑用构建器

无论是静态工厂还是构造器都有共同的局限性:它们都不能很好地扩展到大量可选参数。

然后重叠构造器模式可以实现这一需求,但是又许多参数的时候,客户端代码会变得很难编写,并且可读性很差

于是我们想到JavaBean模式,在这种模式下,调用一个无参构造器来创建对象,然后使用setter来对每个参数进行设置,例:

        Book book = new Book();
        book.setName("xx");
        book.setPrice(123);

这样就出现了一个问题,由于对Book类的参数设置是多个setter方法,这个类可能会处于不一致状态,会导致难以调试的错误。

因此我们说JavaBeans模式阻止了把类做成不可变的可能(即不能做到线程安全)

那么我们会想,有没有一种模式既能保证像JavaBeans模式那样的可读性,又能保证像重叠构造器模式那样的安全性?

有,那就是Builder模式

Builder模式的做法:
1.这个模式不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器(或者静态工厂),得到一个builder对象。
2.然后客户端在builder对象上调用类似于setter的方法,来设置每个相关的可选参数。最后,客户端调用build()方法来生产不可变对象。

下面是Book的Builder模式的代码

public class Book{
    private String name;
    private float price;
    private String authorName;
    //这里有很多参数没写出来

    //这是Builder,Book类的内部类
    public static class Builder{
        private String name;
        private float price;
        private String authorName;

        //这是Builder的狗构造器
        public Builder(){
        }
        //Builder的setter方法,注意这里返回值是自身,链式编程
        public Builder name(String val){
            name = val;
            return this;
        }
        //这里有很多参数的setter没写出来

        //还有一个重要方法,builder方法,用于生成真正的对象,这里是Book的实例
        public Book builder(){
            return new Book(this);
        }
    }

    //这是Book的构造器,只接受一个参数,那就是已经构建好的builder
    private Book(Builder builder){
        name = builder.name;
        price = builder.price;
        //这里有很多赋值没写出来
    }
}

以下是客户端代码:

Book book = new Book.Builder().name("书名").price(12).省略.builder();

注意:Builder模式的参数校验应该放在setter方法中,而不是在builder()方法中。

当然,Builder模式也有自身的不足,因为每次为了创建对象,都要先创建Builder的狗构造器。
在某些十分注重性能的情况下,可能会发生问题。

并且,最好在类设计时一开始就是用Builder,而不是构造器和Builder共存

简而言之,如果类的构造器或静态工厂中具有多个参数,设计这种类时,Builder模式是不错的选择,特别是当大多数参数是可选的时候。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值