簡體   English   中英

觀察者模式是否違反單一責任原則?

[英]Does the Observer pattern violate single responsibiliy principle?

如果使用“觀察者”設計模式的應用程序的subject類具有以下職責:

1)管理和通知觀察者(即提供注冊和注銷功能並調用所有觀察者通知功能);

2)它的原始責任(即班級在成為subject之前所做的一切)。

此類是否違反“單一責任原則”? 它顯然有多個職責,但請仔細閱讀SRP,我很困惑“更改的原因”是在設計時還是在運行時更改?

是的,它確實。 但....

讓我們再回顧一下設計模式背后的宏偉構想,它基本上是在幫助開發人員更輕松地應對將來的未決更改。

設計的粒度級別由您決定,通向黃金中間的路徑應由您的常識,經驗和應用程序規模來指導。

如果可以預見到存儲庫分發的更改,則可以創建一個中介器(pub-sub),負責將更改分發給觀察者。

回答我自己的問題,因為盡管bav的答案鏈接到大量資源,但卻無法回答問題。 (盡管觀看視頻可以使我理解,但我可以回答問題!)

不,這是對單一責任原則(SRP)的誤解。

SRP中的職責是指可以發起變更請求的客戶角色 例如,如果某個類Employee具有calculatePay()displayEmployee()方法,則可以合理地認為它違反了SRP,因為calculatePay將“屬於”公司會計,而displayEmployee將屬於報告書記員。 這意味着兩個角色不同的人可以請求更改班級。

觀察者模式不會添加新的責任(至少不是SRP責任),因為沒有客戶角色會關心此類是否將更改發布給其觀察者。

不, Observer設計模式不違反Single Responsibility Principle (SRP)

什么是責任?

“責任表示對象提供某種行為的義務。”
[面向對象的分析和設計,Grady Booch [等],第600頁]

但是,SRP對責任的定義不同,這是變更的原因。 SRP指出,班級應該只負責一項責任(改變理由)。

這與GoF封裝變化的事物的原理相對應-這是許多GoF設計模式的主題。 例如,策略模式將算法(可以更改)封裝在單獨的策略類中。

觀察者模式與封裝變化的內容無關。 它描述了一種在不使對象緊密耦合的情況下定義交互對象之間一對多依賴性的方法。

有關進一步的討論,請訪問http://w3sdesign.com上的GoF設計模式內存,以學習面向對象的設計和編程。

我認為:是的,觀察者模式確實違反了SRP(有時)。

想象一下以下類,它是MVC應用程序(Java偽語法)的一部分:

class Model {
    void setDateOfBirth(Date);
    Date getDateOfBirth();
    int getAge(); // calculated from date of birth
    void registerObserver(Observer);
    void unregisterObserver(Observer);
    void notifyObservers();
}

前三種方法顯然與管理應用程序數據相關,而后三種方法則無關。

SRP指出,一個類應該只有一個改變的理由[1]。 我可以想到多種原因來更改觀察者方法,在這些方法中不應影響應用程序數據的管理。 一些例子:

  • 由於性能原因,我想同時通知所有觀察者。
  • 我想通過某種消息總線通知觀察者,因為新的視圖在其他過程中運行。
  • 我想並行注冊和注銷觀察者,因此需要其他一些列表實現(一個線程安全的列表實現)。

(一個人可能會爭辯說,所有這些東西都可以隱藏在Observer本身中。但是,注冊允許同時注冊其他觀察員的觀察員,IMO也不正確。)

順便說一句,觀察者模式也違反了DRY(不要重復自己)的原則 ,因為您需要一遍又一遍地實現注冊,注銷和通知機制(即遍歷所有觀察者的循環)。

但:

這兩個職責應該分開嗎? 這取決於應用程序的變化方式。 […]如果[…]應用程序沒有以導致兩個職責在不同時間更改的方式進行更改,則無需將它們分開。 確實,將它們分開會散發出不必要的復雜性的氣味。 — [1]

因此,您必須自己決定,並以不必要的復雜性平衡SRP和DRY。


[1] Robert C. Martin(又名Bob叔叔)和他的書“敏捷軟件開發,原理,模式和實踐”中的OOD原則,第8章。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM