2017-07-18 22 views
1

對於基本類型,生成器模式似乎非常簡單。我想了解它是如何工作的,當你想建立一個複雜的成員類型的對象。涉及複雜對象的生成器模式

這裏我有一個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()); 
    } 
} 

回答

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