Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 涉及复杂对象的生成器模式_Java_Design Patterns - Fatal编程技术网

Java 涉及复杂对象的生成器模式

Java 涉及复杂对象的生成器模式,java,design-patterns,Java,Design Patterns,对于基本类型,构建器模式似乎非常简单。我想了解当您想要构建具有复杂成员类型的对象时,它是如何工作的 这里我有一个Person类和一个静态内部类来构建Person。我在PersonBuilder静态嵌套类中定义了一个Address类。理想情况下,Address类应该在Person类本身中定义。代码可以工作,但我不确定我在这里是否做得正确。谁能告诉我,是否有更好的方法来构建这类对象 class Person{ private String firstName; private String las

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

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


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

您还可以为
地址
创建生成器。即使所有字段都是必需的,也会使地址初始化更容易读取

它将如下所示:

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();

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

正如前面所建议的,如果您可以将
Address
作为一个独立的类,并在其中添加一个
AddressBuilder
,那就更好了

这将使您更容易单独修改
人员
地址

PersonBuilder
中的地址字段设置器看起来也更干净,因为它可以简单地接收一个已构建的
address
实例:

publicpersonbuilder地址(address){
this.address=地址;
归还这个;
}
用法类似于前面回答中提到的示例:

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();
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();