3

爲了解耦代碼,你可以使用服務定位器,但是這不同於全局變量/狀態?服務定位符不僅僅是全局變量/狀態嗎?

我知道這些經常跑掉接口,所以你傳入一個接口並得到一個具體的類,但仍然是我的問題。

例如:

class Something { 

    void DoSomething() { 
     IMyType myType = ServiceLocator.GetSerivceTypeOf(IMyType); 
    } 
} 

這裏的類需要被創建在其他地方,但不是合格的MyType向下穿過鏈(通過構造函數等)它以這種方式獲得的MyType。

在我作爲開發人員的職業生涯早期,我問過這個問題 - 在此之前我不會遇到這種模式。安東尼已經確定了我對服務定位器的看法(因此現在是選定的答案) - 事實上,我將它們視爲與其他模式相反的反模式。所提供的鏈接是一個很好的起點 - 但是爲了在某種程度上回答我自己的問題,他們充當了全球化的角色,應該避免。優先考慮標準依賴注入;)

+0

一個例子或兩個可能會討論開除了一下。 – 2009-06-10 21:41:54

回答

3

通常備份服務定位器模式的名稱服務確實使用全局名稱空間。

但是,必須考慮「全局變量」被認爲是不好的原因。其中許多都圍繞着修改程序中任何地方的全局變量的能力。但是,大多數命名服務可以限制對綁定對象的修改。對象本身可能是不可變的。

服務定位器不是一個簡單的全局變量,它是一種專業化。而這種專業化傾向於緩解全球變量可能帶來的許多問題。

+2

服務定位器的主要問題是它隱藏了依賴關係(http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars/)。服務定位器不會緩解該問題。並且很難用一個模擬服務替代測試,除非你再次修改它,在這種情況下修改問題又回來了。 – Anthony 2010-02-12 09:35:37

+0

當然,但這不是這個問題所要求的。這裏的對比是全局變量和名稱服務之間的對比,而不是名稱服務與世界的對比。 – erickson 2013-07-10 23:39:51

1

在某些時候,你需要一個具體的實現來完成一些工作。從某種意義上來說,該服務是「全球」的,它對您的應用程序「可用」。但是,您不必在代碼中將其變爲全局變量。

您可以反轉該參數。如果您需要訪問應用程序中的服務,您將使用什麼樣的模式訪問它,並且不將其綁定到具體的實現。沒有太多的選擇。

一些資源本質上是「全球」,以您的應用程序,以操作系統,文件系統,窗口系統,...

的討論更是一個哲學比解決問題之一。無論如何,希望它有幫助。