1. Introduction:
观察者设计模式描述了一个可依赖(observable)对象和其它一些对象(observers)的关系。它也叫做Model/View模式,依赖模式或者是传播/监听模式。
下面给出的例子是父母和医生这两个观察者在孩子的状态每次更新时都能够收到讯息。
2. Observer Design Pattern Structure:
3. Class Diagram:
我比较喜欢用Delegates/Events,所以我决定创建一个事件对象通过委托来通知每个观察者,事件所在的类为ObservableObject; ObservableObject应该允许添加或者移除观察者,每个观察者也是能够收到多个状态更新。
4. 实现代码:
ObservableObject是个抽象类,它里面的方法是用来和观察者交换。它允许客户端添加/移除观察者。而Notify()方法用来处理子类中的事件触发。
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace www.askbargains.com.ObserverDesignPatternLib
- {
- public delegate void NotifyObserver(string key);
- public abstract class ObservableObject
- {
- public event NotifyObserver NotifyObserverEvent;
- public void AddObserver(NotifyObserver ob)
- {
- NotifyObserverEvent += ob;
- }
- public void RemoveObserver(NotifyObserver ob)
- {
- NotifyObserverEvent -= ob;
- }
- public void Notify(string kidName)
- {
- if (NotifyObserverEvent != null)
- {
- NotifyObserverEvent(kidName);
- }
- }
- }
- }
Kit类:
是ObservableObject类的子类,它也有自己的信息,比如status。每次DailyStatus属性被更新时,我们都会触发Notify事件。
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace www.askbargains.com.ObserverDesignPatternLib
- {
- public class Kid : ObservableObject
- {
- public string Name { get; set; }
- private Status _dailyStatus;
- public Status DailyStatus
- {
- get { return _dailyStatus; }
- set
- {
- _dailyStatus = value;
- Notify(this.Name);
- }
- }
- }
- }
Parent类和FamilyDoctor类:
我们创建parent类和familydoctor类作为我们的观察者。Parent类的DailyStatusUpdate()方法和FamilyDoctor类的ReceiveNotes()方法是两个update方法,它们是NotifyObserver委托的方法。
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace www.askbargains.com.ObserverDesignPatternLib
- {
- public class Parent
- {
- private Dictionary<string, Kid> _kids = new Dictionary<string,>();
- public Dictionary<string, Kid> Kids
- {
- get { return _kids; }
- set { _kids = value; }
- }
- public void DailyStatusUpdate(string key)
- {
- Console.WriteLine("Parents received {0}'s daily status. " +
- "updated on {1}, Notes: {2} ",
- Kids[key].Name, Kids[key].DailyStatus.UpdatedOn,
- Kids[key].DailyStatus.Description);
- }
- }
- }
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace www.askbargains.com.ObserverDesignPatternLib
- {
- public class FamilyDoctor
- {
- private Dictionary<string, Kid> _kids = new Dictionary<string,>();
- public Dictionary<string, Kid> Patients
- {
- get { return _kids; }
- set { _kids = value; }
- }
- public void ReciveNotes(string patientName)
- {
- Console.WriteLine("Family Doctor received {0}'s new daily status. " +
- "updates on: {1} . Notes:{2}",
- Paitients[patientName].Name,
- Paitients[patientName].DailyStatus.UpdatedOn,
- Paitients[patientName].DailyStatus.Description);
- }
- }
- }
最后是客户端的实现代码,这里使用控制台程序实现观察者模式,你可以通过任何其它方式来实现。
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using www.askbargains.com.ObserverDesignPatternLib;
- namespace www.askbargains.com.ObserverDesignPatternClient
- {
- class Program
- {
- static void Main(string[] args)
- {
- //Two kids been created
- Kid kid1 = new Kid();
- Kid kid2 = new Kid();
- kid1.Name = "Aimee";
- kid2.Name = "Elizabeth";
- //one parent object created.
- //this parent has two kids in this case.
- Parent parent1 = new Parent();
- parent1.Kids.Add(kid1.Name, kid1);
- parent1.Kids.Add(kid2.Name, kid2);
- //one family doctor object created
- //this doctor is kid2's family doctor,
- //and I am going to send the note when kid2 isn't well
- FamilyDoctor doc1 = new FamilyDoctor();
- doc1.Patients.Add(kid2.Name, kid2);
- //I want to send notes to the parents.
- kid1.AddObserver(new NotifyObserver(parent1.DailyStatusUpdate));
- kid2.AddObserver(new NotifyObserver(parent1.DailyStatusUpdate));
- //Update status for both Kids.
- //Parents will receive the notes at the same time
- kid1.DailyStatus = new Status(String.Format("{0} is happy", kid1.Name));
- kid2.DailyStatus = new Status(String.Format("{0} is fuzzy", kid2.Name));
- //Updates the status after 5 secs
- Thread.Sleep(5000);
- //after 5 secs, kid2 doesn't feel well. need to get doctor involved
- kid2.AddObserver(new NotifyObserver(doc1.ReciveNotes));
- //update two kids' status.
- //Parent will recive two kids status
- //Doc1 start reciving kid2 's status
- kid1.DailyStatus = new Status(String.Format("{0} is happy", kid1.Name));
- kid2.DailyStatus = new Status(String.Format("{0} is sick. " +
- "Tempture : 39.7", kid2.Name));
- //Updates the status after 5 secs
- Thread.Sleep(5000);
- //update two kids' status
- kid1.DailyStatus = new Status(String.Format("{0} is happy", kid1.Name));
- kid2.DailyStatus = new Status(String.Format("{0} is back to normal. " +
- "she is happy now", kid2.Name));
- //Updates the status after 5 secs
- Thread.Sleep(5000);
- //since kid2 is fine. I am going to deattach the doc1's observation
- kid2.RemoveObserver(new NotifyObserver(doc1.ReciveNotes));
- //update two kids' status
- kid1.DailyStatus = new Status(String.Format("{0} is happy. " +
- "Just had a big lunch", kid1.Name));
- kid2.DailyStatus = new Status(String.Format("{0} is happy. " +
- "Playing with her best friend Kevin", kid2.Name));
- Console.WriteLine("Daily Report End!");
- Console.Read();
- }
- }
- }
结果展现:
转载自:http://blog.youkuaiyun.com/dujingjing1230/archive/2009/08/12/4438348.aspx
作者:dujingjing1230