2011-06-02 253 views
2

我第一次使用構造函數注入並希望防禦地編寫我的代碼。c#構造函數注入和構造函數重載

因此,如果我有一類具有一個構造函數和一個保存如下方法:

public SomeConstructor(string name, Object someObject) 
{ 
    _name= name; 
    _someObject= someObject; 
} 

public void Save() 
{ 
    // Does a database save 
} 

但隨後需要建立在這個類另一個相關的方法,該方法不需要_someObject所以我創建一個重載鏈構造函數:

public SomeConstructor(string name) : this(name, null) 
{ 
} 

我怎樣才能成功地阻止別人用這個第二個構造帶1個參數初始化類,並利用具有someObject爲空保存()?

我沒有使用注射工具。

上面是一個簡單的例子,在這個例子中,你是正確的,我可以只爲null引發異常,就像我沒有設置屬性一樣。

我想避免的是每個方法開始時的一系列驗證檢查。

回答

4

使用您所遇到的摩擦作爲警告系統。這實際上告訴你,你可能會走向低點cohesion並違反Single Responsibility Principle

如果是這樣,請將該類重構爲兩個單獨的類。

+0

但在上面的例子中,你基本上有1個類來保存/刪除一個對象,它在構造函數中傳遞。即1類僅用於持久性?所有其他方法(如Get()最近的SomeObject都需要一個獨立的類?這有點聽起來像矯枉過正? – asn1981 2011-06-02 12:06:39

+0

有時它是過度的,但是你可以只接受傳遞給構造函數的參數中的一個參數不被使用。 – 2011-06-02 12:22:30

+0

嗯......我猜並不總是最好的辦法。防守編程意味着做出可能違反其他「原則」的決定。我想我只是希望在所有情況下都有一個壓倒一切的規則。 – asn1981 2011-06-02 12:42:59

1

您可以通過運行時異常(如InvalidOperationException)來防止這種情況。

如果某些實例化的類與雙參數構造函數並試圖調用保存,只是檢查是否「someObject」是空的,如果是這樣:

throw new InvalidOperationException("This method cannot be invoked in current object state");

在另一方面,如果第二個構造函數將被庫使用,並且第三方庫開發人員將不被允許使用它,則此構造函數應該具有內部修飾符。

0
public void Save() 
{ 
    if (_someObject == null) 
     throw new InvalidOperationException(); 
} 

我想這很明顯。但是,除非您還將SomeConstructor類型更改爲像decorator pattern那樣工作,否則您確實無法創建類型構造不同的合同。裝飾模式的功能是讓它在運行時而不是編譯時建立繼承層次結構。

然後,您可以根據內部允許的操作來創建不同的對象。這是一些可以通過Save方法的前提條件輕鬆處理的工作。但也許這是你需要的。如果你這樣做了,你可以在SomeConstructor的構造函數中規定你的合同。

下面是一個例子:

interface ISomeConstructor 
{ 
    void Save(); 
} 

class SomeConstructor 
{ 
    ISomeConstructor impl; 

    public SomeConstructor(string name, object someObject) 
    { 
     impl = new StringAndObject(name, someObject); 
    } 

    public SomeConstructor(string name) 
    { 
     impl = new JustString(name); 
    } 

    public void Save() 
    { 
     impl.Save(); 
    } 
} 

類型StringAndObjectJustString工具ISomeConstructor並在他們認爲合適,他們可以處理Save方法。

這是裝飾者模式的細微變化,因爲通常你期望ISomeConstructor作爲參數傳遞給構造函數。

0

IoC它只是一種解決依賴問題的方法,但並不能解決任何OO問題。 我會專注於一個好的面向對象的設計,而不是試圖找到一種方法來欺騙框架,迫使使用承包商而不是另一個。問題是如果你不使用IoC框架,你會怎麼做? 可能性檢查SomeObject是否爲空?