2011-09-24 31 views
4

我有以下類:設計最佳實踐 - 對象應該擁有傳遞給它的構造函數的東西嗎?

public class SqlCeEventStore: EventStore 
{ 
    private EventStoreDB db; 

    public SqlCeEventStore(EventStoreDB db) 
    { 
    this.db = db; 
    } 

    public void Dispose() 
    { 
    db.Dispose(); 
    } 
} 

我的問題是這樣的:我在我班上的Dispose方法處置有關EventStoreDB糾正,因爲它傳遞給它的構造函數(因此,可能可以想像,在我的課程被處理後重用)?

也就是說,如果我處理它,我授權,我班的正確用法是:

using (var store = new SqlCeEventStore(new EventStoreDB)){ 
{ 
    //... 
} 

但我可以看到使用這種替代電話:

using (var db = new EventStoreDB()) 
using (var store = new SqlCeEventStore(db)) 
{ 
    //... 
} 

在這種情況下,我應該不是SqlCeEventStore類處置EventStoreDB

對於一種風格或其他風格是否有任何爭論?我想選擇一個並堅持下去,我寧願不要翻轉一個硬幣:)

回答

2

一般是沒有規則這一點,但肯定我會同意,因爲對象是你的範圍之內創建並獲得通過對你來說,你不擁有它。

如果你創造了它,那麼你應該有完全的權利做任何你喜歡(有記錄的來電者的預期行爲)

這是典型的composition vs aggregation東西。

+0

啊......謝謝,我必須承認,「構圖vs聚合」的區別對我來說從來不清楚 –

+0

@ Marcel:是的,這是一個難以理解的棘手的定義,你的情況就是看到它的方式,順便說一句,現在很清楚了;) – Nrj

+0

是的,它是:)我將這個標記爲公認的答案。 –

1

如果EventStoreDB由SqlEventStore(即它的組成部分)所有,它應該被構造或合併SqlEventStore類。

如果它在SqlEventStore生命週期的範圍之外使用,那麼它應該由外部代碼創建和處置。

+0

好點。我更喜歡在構造函數中注入一個類所依賴的對象,所以我不能這樣做,但如果沒有這個規則,你會是正確的。 –

1

這裏沒有一般規則,恕我直言,不應該有一個。不同的物體具有不同的壽命,最一般的指導方針是確保物體的壽命是一致的,壽命儘可能短。

您可以嘗試使用以下內容作爲指導(但在需要時不要害怕偏離):在分配同一範圍內處理對象。本指南適​​用於許多場景,並且它正是簡化了using聲明的內容。

如果你有沒有明顯處置點的長壽命對象,不要擔心。這很正常。但是,問問自己:我真的需要這個對象來生活嗎?有沒有其他的方式可以模擬這個使壽命更短?如果您可以找到另一種縮短壽命的方法,那麼通常會使對象更易於管理,因此應該是首選。

但是,在這裏沒有任何「一個真正的規則」。

0

不能挑一個,堅持下去。用戶可以隨時選擇他想要的。

但是,請記住,作爲通過構造函數傳遞的對象處置類不負責任。


的未來是非常愚蠢的討論,因爲if you want to impose initiation of the class using *new SqlCeEventStore(new EventStoreDB))*那麼你爲什麼不刪除此EventStoreDB參數和實例構造函數裏面的變量分貝。

解決方法

有一個解決方法 - 檢查這一點:

public myClass { 
    //do not make the constructor public //hide it 
    private myClass(EventStoreDB db){ 
     this.db = db; 
    } 
    //make a public constructor that will call the private one in the way you want 
    public myClass(){ 
     this(myClass(new EventStoreDB())); 
    } 
} 
+0

我不喜歡類中的new對象,而是在構造函數中傳遞依賴關係。你寫它的方式是有效的,但它使'myClass'難以重用。 –

+0

其實......如果一個班級擴展你的班級,他將不得不使用超級班,這就是全部(: –

0

我會建議,如果可以合理地想象構造對象將成爲宇宙中對傳入對象感興趣的最後一件事情,以及其他事物想要繼續使用傳入的對象在構造函數完成之後,可能需要有一個構造函數參數,該參數指定新對象是否應接受傳入的對象的所有權。

請注意,如果構造對象將獲取傳入對象的所有權後,即使構造函數拋出異常,確定該對象將被丟棄也很重要。一種方法是將構造函數調用包裝在例程中,該例程將在「finally」塊中處理傳入的對象,除非構造函數已成功完成。