2010-07-12 40 views
1

我有需要「年」作爲參數的DataProvider類(DAL)。它使用像這樣:異常可拋出的構造函數和初始化。最佳做法

using (var provider = new DataProvider(year)) 
{ 
    provider.SomeRepostitory.DoSomethingUsefull(); 
} 

DataProvider構造函數代碼處理配置 - 因此它可以拋出異常。不推薦使用異常拋出構造函數。所以我添加初始化方法,並把那裏所有拋出代碼:

var provider = new DataProvider(); 
provider.Init(year); 

但是現在有兩行代碼中的一個,而不是和供應商在整個代碼中創建了很多次,我就把這兩條線織成織物的靜態方法:

using (var provider = DataProvider.Create(year)) 
{ 
    ... 
} 

是好的還是有更好的解決方案?

預先感謝您!

回答

4

DataProvider構造函數代碼使用配置處理 - 因此它可以拋出 異常。建議不要使用異常拋出的 構造函數。

他們爲什麼「不推薦」?看看微軟的基類庫,你會發現每個單獨的構造函數都會檢查傳遞給它的參數,並且如果參數無效則拋出某種類型的參數異常。爲什麼你會讓某人在沒有告訴他們的情況下實例化一個處於無效狀態的對象?提前失敗,努力失敗。

拋出一個異常的構造函數是一個更好的API來編程,而不是必須使用單獨的初始化方法(我個人很討厭兩階段初始化;很容易忘記第二次調用)。除非有一個令人信服的理由來避免它,否則我只是在構造函數中進行檢查。

如果您確實想使用靜態工廠方法(除非需要使其鬆散耦合,否則沒有任何問題),請確保默認構造函數是私有的,以便用戶被迫使用適當的工廠方法。

2

我認爲有一個工廠方法對對象進行一些初始化是完全合理的。如果您不應該在沒有初始化的情況下使用對象,請將構造函數設置爲private(或protected),以便只有類中的靜態方法才能調用構造函數。

0

如果您想將呼叫鏈接在一起,您可以使用Init方法返回this。像:

var provider = new DataProvider().Init(year); 

但如果你打電話.Init(),那麼工廠方法款式可能會更有幫助。

0

你可以逃脫懶惰的實例嗎?在創建它的年份傳遞,但在使用之前不要實際初始化它。這會把例外移到第一個電話而不是建築物,但它似乎符合你的要求。

+0

這意味着每次使用「worker」方法時都必須捕獲潛在的異常,儘管這可能是相當大的開銷。這也意味着對該方法的第一次調用不如其餘,這與良好的API設計相反, – 2010-07-12 21:00:04