ServiceLocator是反模式嗎?最近我讀過Mark Seemann關(guān)于Service Locator反模式的文章。作者指出ServiceLocator為反模式的兩個主要原因:API使用問題(我完全可以使用)當類使用服務(wù)定位器時,很難看到它的依賴關(guān)系,因為在大多數(shù)情況下,類只有一個PARAMETERLESS構(gòu)造函數(shù)。與ServiceLocator相比,DI方法通過構(gòu)造函數(shù)的參數(shù)顯式地暴露依賴關(guān)系,因此在IntelliSense中很容易看到依賴關(guān)系。維護問題(讓我感到困惑)請考慮以下示例我們有一個使用服務(wù)定位器方法的類'MyType':public class MyType{
public void MyMethod()
{
var dep1 = Locator.Resolve<IDep1>();
dep1.DoSomething();
}}現(xiàn)在我們要為類'MyType'添加另一個依賴項public class MyType{
public void MyMethod()
{
var dep1 = Locator.Resolve<IDep1>();
dep1.DoSomething();
// new dependency
var dep2 = Locator.Resolve<IDep2>();
dep2.DoSomething();
}}這就是我的誤解開始的地方。作者說:要判斷你是否引入了一個重大改變,要變得更加困難。您需要了解使用Service Locator的整個應(yīng)用程序,編譯器不會幫助您。但是等一下,如果我們使用DI方法,我們將在構(gòu)造函數(shù)中引入與另一個參數(shù)的依賴關(guān)系(在構(gòu)造函數(shù)注入的情況下)。問題仍然存在。如果我們忘記設(shè)置ServiceLocator,那么我們可能忘記在IoC容器中添加新的映射,并且DI方法將具有相同的運行時問題。此外,作者還提到了單元測試的難點。但是,我們不會有DI方法的問題嗎?我們不需要更新所有實例化該類的測試嗎?我們將更新它們以傳遞一個新的模擬依賴項,以使我們的測試可編譯。我沒有看到更新和時間花費帶來任何好處。我不是想捍衛(wèi)Service Locator方法。但這種誤解讓我覺得我失去了一些非常重要的東西。有人可以消除我的懷疑嗎?更新(摘要):我的問題“服務(wù)定位器是反模式”的答案實際上取決于具體情況。我絕對不會建議你從工具列表中刪除它。當您開始處理遺留代碼時,它可能會變得非常方便。如果你很幸運能夠處于項目的最初階段,那么DI方法可能是更好的選擇,因為它比Service Locator有一些優(yōu)勢。以下是主要的不同之處,這些差異使我不相信我的新項目使用Service Locator:最明顯和最重要的是:Service Locator隱藏了類依賴項如果您正在使用某個IoC容器,它可能會在啟動時掃描所有構(gòu)造函數(shù)以驗證所有依賴項,并為您提供有關(guān)丟失映射(或錯誤配置)的即時反饋; 如果您將IoC容器用作服務(wù)定位器,則無法實現(xiàn)此目的有關(guān)詳細信息,請閱讀下面給出的優(yōu)秀答案。
3 回答

瀟湘沐
TA貢獻1816條經(jīng)驗 獲得超6個贊
我還想指出,如果你重構(gòu)遺留代碼,服務(wù)定位器模式不僅不是反模式,而且它也是一種實際需要。沒有人會在數(shù)百萬行代碼上揮動魔杖,突然所有的代碼都準備就緒了。因此,如果您想開始將DI引入現(xiàn)有代碼庫,通常情況下您會將內(nèi)容更改為DI服務(wù),并且引用這些服務(wù)的代碼通常不會是DI服務(wù)。因此,這些服務(wù)將需要使用服務(wù)定位器,以獲取已轉(zhuǎn)換為使用DI的那些服務(wù)的實例。
因此,當重構(gòu)大型遺留應(yīng)用程序以開始使用DI概念時,我會說服務(wù)定位器不僅不是反模式,而且它是將DI概念逐漸應(yīng)用于代碼庫的唯一方法。
- 3 回答
- 0 關(guān)注
- 863 瀏覽
添加回答
舉報
0/150
提交
取消