2016-05-14 33 views
-1

的鏈接想象一下,一類Person。它的構造函數需要很多參數,而類不受你控制。如果你想簡化對象的創建,你可以創建一個構建器,讓你將指令鏈接在一起。是創建一個包裝,使制定者接受

但是,如果您想在創建後更改Person的實例,則必須單獨訪問其所有設置器。

如果你將不得不像這樣經常做大的改變,是否可以接受爲Person創建一個允許鏈接setter的包裝?我以前大部分都只看到了建造者的鏈接,讓制定者返回他們改變的對象是不是一個好主意?

示例代碼,以顯示我的想法:

public class Person { 
    String name; 
    int age; 

    public void setName(String name){ this.name = name; } 

    public void setAge(int age){ this.age = age; } 

} 

public class PersonWrapper { 
    Person person = new Person(); 

    public PersonWrapper setName(String name){ 
     this.person.setName(name); 
     return this; 
    } 

    public PersonWrapper setAge(int age){ 
     this.person.setAge(age); 
     return this; 
    } 
} 

public class Example { 
    public void example() { 
      Person p = new Person(); 
      PersonWrapper pw = new PersonWrapper(); 

      //some time later, we want to change these objects 
      p.setName("John"); 
      p.setAge(20);     //this becomes 

      pw.setName("John").setAge(20); //this instead 
    } 
} 

顯然,如果是一個有點大量的屬性來設置這隻會是有用的。我只提供了兩個屬性來保持簡短。

注意:這是問題Can I do multiple actions to one component in a more elegant way?,讓我想知道這一點。起初,我只是想問這是對接受答案的評論,但顯然我的代表太低評論。如果我錯誤地發佈這個作爲一個新問題,請讓我知道,所以下次我不會犯同樣的錯誤。

+1

我寧願'Builder'或'Factory'模式。爲複雜對象創建包裝類會使整個數據模型更加複雜,並減少對隱藏在包裝類中的複雜對象的控制。例如,如果您想更改複雜對象的屬性,但您的包裝器沒有適合此目的的委託方法。 – 2016-05-14 12:56:06

+0

@Rafael無論是''Builder''和''Factory''是,雖然創建對象,我想知道在創建之後改變對象的狀態。無論如何,如果我正確地理解了你,對複雜對象進行大的修改,只需使用它的setter?或儘可能避免大型,易變,複雜的對象? – SecularisticSloth

+0

一般而言,複雜的對象本身並不是一個好主意。如果對象是太複雜了,它看起來像這個對象「知道」到多,負責[太多** **不同的行動](https://en.wikipedia.org/wiki/God_object)。重新考慮複雜類的設計,將這些類拆分爲更簡單的類,以使它**方便**與它們一起工作。在開發過程中,_convenience_和簡單表明您正處於正確的道路上。反之亦然。 – 2016-05-14 17:39:10

回答

1

如果你真的想花費額外的努力只是爲了鏈接屬性(我認爲不值得),你的解決方案是從設計方面確定。沒有DRY violiation,通過使用Person而不是接口,耦合已經很高,所以額外的PersonWrapper類不會受到傷害。但如前所述,我懷疑這種好處是值得的。

如果只有建設過程中,你不用擔心,我建議你考慮一下工廠模式。

另一種解決方案是使用一個實用工具類,它提供對人對象最常見的操作。例如:

PersonUtility.SetNameAge(personObject, „John「, „Doe「, 31); 
PersonUtility.SetLook(personObject, weight, height, waistSize, hairColor, eyeColor); 

但如果你真的想要去一個包裝類我建議以下的方法,使包裝只做了鏈接,而所有其他操作可能會與原來的Person類來完成。

public class Person { 
    private String mName; 
    private int mAge; 

    void setName(String name){ mName = name; } 
    void setAge(int age){ mAge = age; } 

    void printPerson() { 
     System.out.println(mName + " " + mAge); 
    } 
} 

public class PersonWrapper { 
    private final Person mPerson; 

    public PersonWrapper(Person person) { 
     mPerson = person; 
    } 

    PersonWrapper setName(String name) { 
     mPerson.setName(name); 
     return this; 
    } 

    PersonWrapper setAge(int age) { 
     mPerson.setAge(age); 
     return this; 
    } 

    public Person getPerson() { 
     return mPerson; 
    } 
} 

public class Main { 

    public static void main(String[] args) { 
    // write your code here 
     PersonWrapper wrapper = new PersonWrapper(new Person()).setName("John Doe").setAge(31); 

     wrapper.getPerson().printPerson(); 
    } 
} 
+0

提供的答案中,我覺得最好的答案是我的問題。但是,我發現閱讀Rafael Osipov對原始問題的評論很有幫助。 – SecularisticSloth

+0

爲什麼不簡單地讓Person從它的setters中返回呢? – denniskb

0

我不知道這個程序的,但首先它不建議以創建新類裏的人的對象,這將增加的依賴,而不是你可以在外面創建該對象,並在構造函數發送「PersonWrapper」。

我的建議是讓PersonWrapper繼承的人是這樣的。

public class PersonWrapper extends Person { 


    public PersonWrapper setCustomName(String name){ 
    this.setName(name); 
    return this; 
    } 

    public PersonWrapper setCustomAge(int age){ 
    this.setAge(age); 
    return this; 
    } 
} 
+0

當然最好是你工廠設計模式在開始時 –

+0

來創建對象將這種不會造成編譯在試圖重寫的setName和setAge具有相同簽名和不同返回類型的時間錯誤? – SecularisticSloth

+0

對不起我的壞,我的意思是使用不同的制定者像setCustomName,setCustomAge,將編輯 –