2016-07-23 79 views
1

我已經看到了實現生成器模式的兩種常用方法:實現生成器模式

// 1. The build() approach 
Product p = builder.part1() 
        .part2() 
        .build(); 

// 2.The constructor approach 
builder.part1() 
     .part2(); 
Product p = new Product(builder); 

哪一個是最好?

回答

6

1日一個是要走的路...

如果使用第二選擇

那麼這樣做:

Product p = new Product(builder); 

將依賴關係添加到產品類..

是手段產品類現在至少需要一個構造函數,參數爲構建器

+0

我也剛剛意識到,如果'Product'是一個接口,那麼方法將不起作用。你將不得不引入一個'construct()'方法,這意味着你可以使用'Builder.build()'路由。 –

1

我傾向於使用這兩個示例的組合LES。

我將在產品類中定義一個構建器類,併爲該產品類提供一個採用ProductBuilder的私有構造器。

+0

如果你讓構建者成爲內部類,那麼不會訪問'Product'的內部就夠了嗎? –

+1

我想你可以,但我喜歡將構建器的狀態與您正在創建的對象分開,所以一旦構建對象,構建器就不能再修改它。 – simonv

2

這個問題有點含糊,但是如果你有一個靜態構建器類,joshua bloch的有效java書提示了一個更像構建方法的結構。這是一種更清潔和更安全的方式。

Product p= new Product.ProductBuilder("hw", "sw") 
    .version(30) 
    .mac("1234567") 
    .address("Fake address 1234") 
    .build(); 
+0

我剛剛搜索了Josh Blochs實現,我非常喜歡這個! –

1

這些是兩種不同的方法。交替是不同的。 您必須使用,並根據您的需求和背景,而不是根據一個硬性的規則...

使用建設者喜歡它適應的模式:

Product p = new Product(builder); 

允許創建您的建設者和重用。 如果您需要重用構建器或在另一個類中創建構建器,這是一個很好的實現。你打開你的API,因爲你需要它。
該解決方案的缺點是不能直接創建對象。
關於設計質量和依賴性,我認爲這是一個錯誤的問題。 是的,對於Product的公共構造函數,您可以在Product和builder之間創建公共依賴項,並公開產品構造函數。 但是,如果在產品構造函數中,您向構建器實例派發構造產品的任務,耦合是否會使代碼更加靈活?決不。
此外,由於構建器使用鏡像屬性構建產品對象,因此真正的耦合位於產品構造中。所以,真正的和強大的耦合將保持不變:這兩個類必須一起工作,並且必須看起來像。

使用像是一個建設者:

Product p = builder.part1() 
       .part2() 
       .build(); 

不允許重用建設者,但更直接使用您的類的客戶端,並在最小Builder之間打開的依賴產品。 如果您不需要重用構建器或在另一個類中創建構建器,這是最好的,因爲您沒有以無用的方式打開您的API。

因此,事實上,兩種解決方案都近在咫尺。 如果我必須重用構建器,或者我需要在另一個類中創建構建器,並且如果不需要,我將使用不帶構造器的解決方案,那麼我會使用該構造器的解決方案。