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

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