有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

标准Java Builder模式

我最近写了一个builder类,注意到标准如下

public class PersonBuilder {
    private String firstName;
    private String lastName;

    public PersonBuilder withFirstName(String firstName) {
        this.firstName = firstName;
        return this;
    }

    public PersonBuilder withLastName(String lastName) {
        this.lastName = lastName;
        return this;
    }

    public Person build() {
        return new Person(this);
    }
}

相反,这样做有什么不利之处吗

public class PersonBuilder {
    private Person person;

    public PersonBuilder withFirstName(String firstName) {
        person.setFirstName(firstName);
        return this;
    }

    public PersonBuilder withLastName(String lastName) {
        person.setLastName(lastName);
        return this;
    }

    public Person build() {
        return person;
    }
}

我知道这可能是一个基于观点的问题,我只是想知道为什么这可能是一个糟糕或更好的设计模式


共 (3) 个答案

  1. # 1 楼答案

    • 当正在生成的类中没有setter时,可以使用Builder
    • 接受builder作为构造函数参数会引入紧密耦合

    以下方法解决了这些问题:

    public class PersonBuilder {
        private String firstName;
        private String lastName;
    
        public PersonBuilder withFirstName(String firstName) {
            this.firstName = firstName;
            return this;
        }
    
        public PersonBuilder withLastName(String lastName) {
            this.lastName = lastName;
            return this;
        }
    
        public Person build() {
            return new Person(firstName, lastName);
        }
    }
    
  2. # 2 楼答案

    你的方法有几个问题。前面的回答中描述了其中的一些问题,所以我只提其他问题

    设计中最大的问题是,在构建器中使用了Person的单个实例。这意味着,如果您多次使用同一个构建器,您将“构建”同一个实例,而使用它的客户机需要两个不同的实例。无需提及,这可能会对应用程序造成严重破坏

    您从@Basilevs获得的答案提到,“构建”类将需要setter。这是绝对正确的,但我想强调的是,这是一个巨大的问题,因为这意味着你“构建”的类永远不会是不变的!换句话说,如果需要的话,您将限制此类类的实现者使用同步来实现线程安全,以及使用通用方法可以避免的其他问题解决机制

  3. # 3 楼答案

    Is there any disadvantage to, instead, doing the following
    

    是的,当用户调用withFirstName方法时,它将导致NPE,因为您甚至没有实例化person