文章出處

索引

別名

  • Dependency
  • Publish-Subscribe

意圖

定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都得到通知并被自動更新。

Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

結構

參與者

Subject

  • Subject 知道它的 Observer。可以有任意多個 Observer 觀察同一個 Subject。
  • 提供注冊和刪除 Observer 的接口。

Observer

  • 為那些在 Subject 發生改變時需要獲得通知的對象定義一個 Update 接口。

ConcreteSubject

  • 將有關狀態存儲各個 ConcreteObserver 對象。
  • 當它的狀態發生改變時,想它的各個 Observer 發出通知。

ConcreteObserver

  • 維護一個指向 ConcreteSubject 對象的引用。
  • 存儲有關狀態,這些狀態應該與 ConcreteSubject 的狀態保持一致。
  • 實現 Observer 的更新接口以使自身狀態與 ConcreteSubject 狀態保持一致。

適用性

在以下情況下可以使用 Observer 模式:

  • 當一個抽象模型有兩個方面,其中一個方面依賴于另一個方面。將這二者封裝在獨立的對象中以使它們可以各自獨立地改變和復用。
  • 當對一個對象的改變需要同時改變其他對象,而不知道具體有多少對象有待改變。
  • 當一個對象必須通知其他對象,而它又不能假定其他對象時誰。

效果

  • 目標與觀察者間的抽象耦合。
  • 支持廣播通信。
  • 意外的更新。因為 Observer 并不知道其他 Observer 的存在,所以對改變 Subject 的最終代價一無所知。

相關模式

  • 可以使用 Mediator 模式封裝復雜的更新語義,充當 Subject 與 Observer 之間的中介者。

實現

下面的交互圖描述 Subject 與 Observer 之間的協作:

實現方式(一):Observer 模式結構樣式代碼。

推模式(Push Model):Subject 向 Observer 發送關于改變的詳細信息,而不管它們是否需要。

拉模式(Pull Model):Subject 除最小通知外什么也不推送,由 Observer 顯式地向 Subject 詢問細節。

 1 namespace ObserverPattern.Implementation1
 2 {
 3   public abstract class Observer
 4   {
 5     public abstract void Update();
 6   }
 7 
 8   public abstract class Subject
 9   {
10     private List<Observer> _observers = new List<Observer>();
11 
12     public void Attach(Observer observer)
13     {
14       _observers.Add(observer);
15     }
16 
17     public void Detach(Observer observer)
18     {
19       _observers.Remove(observer);
20     }
21 
22     public void Notify()
23     {
24       foreach (var observer in _observers)
25       {
26         observer.Update();
27       }
28     }
29   }
30 
31   public class ConcreteSubject : Subject
32   {
33     private string _state;
34 
35     public string State
36     {
37       get
38       {
39         return _state;
40       }
41       set
42       {
43         _state = value;
44         Notify();
45       }
46     }
47   }
48 
49   public class ConcreteObserver : Observer
50   {
51     private ConcreteSubject _subject;
52 
53     public ConcreteObserver(string name, ConcreteSubject subject)
54     {
55       Name = name;
56       _subject = subject;
57     }
58 
59     public string Name { get; private set; }
60 
61     public override void Update()
62     {
63       string subjectState = _subject.State;
64       Console.WriteLine(Name + ": " + subjectState);
65     }
66   }
67 
68   public class Client
69   {
70     public void TestCase1()
71     {
72       var subject = new ConcreteSubject();
73       subject.Attach(new ConcreteObserver("Observer 1", subject));
74       subject.Attach(new ConcreteObserver("Observer 2", subject));
75       subject.Attach(new ConcreteObserver("Observer 3", subject));
76 
77       subject.State = "Hello World";
78     }
79   }
80 }

設計模式之美》為 Dennis Gao 發布于博客園的系列文章,任何未經作者本人同意的人為或爬蟲轉載均為耍流氓。


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()