2015-04-16 32 views
5

在經典的Facade模式中,單個對象通常爲更復雜的事物提供簡化的界面。與SRP的外觀模式

幫派對四的把它(儘可能接近「官」,因爲它得到...):在一個子系統

門面(185)提供統一的接口,以一組接口。 Facade定義了一個更高級別的界面,使得子系統更易於使用。

...門面只是抽象到子系統對象,使他們更容易使用的界面;它沒有定義任何新的功能,子系統類不知道它。

或者,如Unmesh把它放在https://stackoverflow.com/a/5242476

甲門面從該系統的複雜細節遮蔽用戶併爲他們提供的它的簡化視圖,其是易於使用的。它還將使用該系統的代碼從子系統的細節中分離出來,以便稍後修改系統。

的單一職責原則建議我們,

類或模塊應該有一個,且只有一個理由去改變。

每Bob大叔(http://en.m.wikipedia.org/wiki/Single_responsibility_principle

鑑於一個門面,設計,屏蔽用戶從「的理由來改變」衆多,怎麼能這兩個概念一起工作? Facade是否有與其實施所依賴的子系統數量一樣多的理由來改變?

+0

會是什麼原因衆多是改變一個門面? – PeeHaa

+0

將在帖子中進行說明 – goofballLogic

回答

1

首先,

模式和原則 - 是兩個截然不同的東西。模式是解決問題的經過證明的解決方案,而原則不過是一個準則。

因此,比較它們將是毫無意義的,特別是因爲它們在大多數情況下完成彼此。

至於SRP的定義,「一個理由去改變」,可以很容易解釋:

圖片,如果你造一輛車的對象,這將包括引擎,類型之類的東西的。所以這個物體的構造看起來像:

car = new Car(new Engine(), new Type()); 

那麼如果你想更換該車的發動機呢?那麼你只需更換Engine的實例。這是改變的原因之一,因爲你沒有觸及其他部分。

至於外牆,您提供的定義太籠統。正面只是包裝在某些環境下可能不可用的另一種方式。他們只是確保,你的東西可以在所有環境中工作。例如,有事件監聽器在JavaScript中非常有名的例子:

function click(object, handler){ 
    if (object.addEventListener != undefined){ 
    // For major browsers 
    object.addEventListener(....); 
    } else if (object.attachEvent != undefined){ 
    // For IE < 7 
    object.attachEvent(...) 
    } else { 
    object.click = handler; 
    } 
} 
+0

更新我的問題以反映外觀的「官方」GoF定義 – goofballLogic

+0

您的示例外觀並不真正適合外觀樣式的經典定義,至少在OO圓圈中。 – goofballLogic

+0

我描述的定義來自Ross Harmes和Dustin Diaz的書,被稱爲JavaScript設計模式(頁141)。至於你反映的變化,我只是簡單地爲這些「外牆」實現一個接口,從現在開始,實現將取決於抽象,而不是具體的實現,這將解決你的問題 – Yang

4

基本上,如果你門面類實現依賴倒置原則(這取決於抽象,而不是在具體的實現),你將來不需要修改它。

異常 - 如果有錯誤或者您需要更改Facade的業務邏輯(例如,它封裝的那些子系統之間的交互)。但這不是SRP違規。

順便說一句,好像它在報價順帶提到:在一個子系統

門面(185)提供了統一的接口,一組接口

+0

是的,這樣做是有道理的,只是部分外觀的任務是屏蔽消費者免受底層系統的變化影響。如果值得這樣做,這是不是意味着這些系統足夠複雜,即使它們的接口在版本化時也會改變? – goofballLogic

+0

我明白你的意思。是的,如果您必須更新特定子系統的界面 - 這意味着您違反了該界面的界面隔離原則。不要忘記Open-Closed原則 - 最好擴展現有的接口/類,而不是更新內部內容。 似乎你在構建新課程時必須瞭解所有SOLID原則:) –