生成器模式涉及复杂对象

时间:2017-07-18 15:58:23

标签: java design-patterns

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

这里我有一个Person类和一个静态内部类来构建Person。我有一个我在PersonBuilder静态嵌套类中定义的地址类。理想情况下,Address类应该在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());
     }
}

2 个答案:

答案 0 :(得分:1)

一个类应该有一个主要目的,但似乎你给PersonBuilder两个不同的任务:构建人员和构建地址(在构建Person实例时动态完成)。

如前所述,如果您可以将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();

答案 1 :(得分:0)

我认为最好将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();