【问题标题】:Builder Pattern involving complex objects涉及复杂对象的建造者模式
【发布时间】:2017-08-31 16:41:07
【问题描述】:

对于基本类型,构建器模式似乎非常简单。我想了解当您想要构建具有复杂成员类型的对象时它是如何工作的。

这里我有一个 Person 类和一个静态内部类来构建 Person。我有一个在 PersonBuilder 静态嵌套类中定义的地址类。理想情况下,地址类应该在 Person 类本身中定义。该代码有效,但我不确定我是否在这里正确地做事。谁能告诉我是否有更好的方法来构造这些对象。

class Person{

private String firstName;
private String lastName;
private Integer age;
private Person.PersonBuilder.Address address;

private Person(PersonBuilder builder){
    this.firstName =  builder.firstName;
    this.lastName = builder.lastName;
    this.age = builder.age; 
    this.address = builder.address;
}

@Override
 public String toString(){
    return "Person: " + 
           this.firstName + "|" + 
           this.lastName + "|" + 
           this.age.toString() + "|" + 
           this.address.aptNum + "|" +
           this.address.street + "|" +
           this.address.city + "|" +
           this.address.state + "|" +
           this.address.zipCode;
}

public static class PersonBuilder{

    private String firstName;
    private String lastName;
    private Integer age;
    private Address address;

    private class Address{

        private String aptNum;
        private String street;
        private String city;
        private String state;
        private Long zipCode;

        public Address(String aptNum, String street, String city, String state, Long zipCode) {
            this.aptNum = aptNum;
            this.street = street;
            this.city = city;
            this.state = state;
            this.zipCode = zipCode;
        }
    }       

    public PersonBuilder(String firstName, String lastName){
        this.firstName = firstName;
        this.lastName = lastName;
        this.address = this.new Address("", "", "", "", 0L);
    }

    public PersonBuilder age(Integer age){
        this.age = age;
        return this;            
    }

    public PersonBuilder buildAddress(String aptNum, String street, String city, String state, Long zipCode){
        this.address = new Address(aptNum, street, city, state, zipCode);
        return this;
    }

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

}

class Demo {
    public static void main(String[] args){
        Person p1 = new Person.PersonBuilder("XYZ", "XYZ")
                              .age(24)
                              .buildAddress("AB", "XYZ Lane", "ABCtown", 
                              "XY", 1234L)
                              .build();

                 System.out.println(p1.toString());
     }
}

【问题讨论】:

    标签: java design-patterns


    【解决方案1】:

    一个类应该有一个主要目的,但您似乎给PersonBuilder 分配了两个不同的任务:构建人员和构建地址(这是在构建人员实例时即时完成的)。

    如前所述,如果您可以将Address 设为一个独立的类并在其中添加一个AddressBuilder 会更好。

    这将使您更容易独立修改PersonAddress 类。

    PersonBuilder 中的地址字段设置器也会看起来更简洁,因为它可以简单地接收已构建的 Address 实例:

    public PersonBuilder address(Address address){
        this.address = address;
        return this;
    }
    

    用法类似于上一个答案中提到的示例:

    Address address = new Adress.AdressBuilder()
                                .aptNum("xyz")
                                .street("xyz")
                                .city("xyz")
                                .state("xyz")
                                .zipCode("xyz")
                                .build();
    
    Person person = new Person.PersonBuilder("ABCD", "EFG")
                              .address(address)
                              .build();
    

    【讨论】:

      【解决方案2】:

      我认为将Address单独定义为公共类会更好,这样它就不会与Person紧密耦合,您可以重复使用它。

      您还可以为Address 创建一个构建器。即使所有字段都是必需的,它也会使地址初始化更易于阅读。

      看起来像这样:

      Address a1 = new Address.AddressBuilder()
                          .aptNum("AB")
                          .street("XYZ Lane")
                          .city("ABCtown")
                          .state("XY")
                          .zipCode("1234L")
                          .build();
      Person p1 = new Person.PersonBuilder("XYZ", "XYZ")
                            .age(24)
                            .address(a1)
                            .build();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-25
        • 2018-05-23
        • 2018-07-20
        • 2016-02-02
        相关资源
        最近更新 更多