Design Pattern 设计模式【观察者】
2009-11-26 09:33 Virus-BeautyCode 阅读(1732) 评论(2) 编辑 收藏 举报观察者设计模式中存在两种角色: 观察者和被观察者。
最经典的例子就是“猫叫了,老鼠跑了,惊醒了主人。”,这个例子也是我以前去微软面试的时候碰到的一个面试题,当时就是让我设计一下这个过程的实现框架。
在这个例子中,老鼠和主人其实就是观察者,而猫属于被观察者,老鼠和主人观察猫的变化,猫有了动作,老鼠和主人就要做出响应。被观察者,就是这个过程,也可以叫做整个事件的根本原因,亦可以叫直接导火索。
从上面这个例子不难看出,观察者和被观察者的关系通常是n:1,也就是多个多个观察者观察一个被观察者。
这样就给我们一个小小的提示,通过这个提示就可以很容易的找出被观察者。猫,也就是观察的内容,或者观察的被动者,猫所在的角色就是被观察者;老鼠和主人,也就是观察的主体,动作的出发者,他们的角色就是观察者。
当然了,实际的项目中,这个过程肯定没有这么简单,这时候需要我们把大过程,分解成很多的小过程,分层级的找出观察者和被观察者,分层级的使用观察者模式。
下面给出我写的一个完整代码,欢迎大家一起讨论。
完整代码:/Files/virusswb/BeautyCode.DesignPattern.Observer.rar
代码包括两个部分,首先是普通的观察者模式,也就是在被观察者中注册观察者,多个观察者通过一个荣起来管理,然后向观察者发送通知。
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApp
{
/// <summary>
/// 观察者接口
/// </summary>
public interface IObserver
{
void Notify(object obj);
}
/// <summary>
/// 被观察者接口
/// </summary>
public interface IObservable
{
void Register(IObserver observer);
void UnRegister(IObserver observer);
void Notify(object obj);
}
class Mouse:IObserver
{
public void Run()
{
}
#region IObserver 成员
public void Notify(object obj)
{
Console.WriteLine(string.Format("{0},老鼠跑了",obj.ToString()));
}
#endregion
}
class Master:IObserver
{
public void Wake()
{
}
#region IObserver 成员
public void Notify(object obj)
{
Console.WriteLine(string.Format("{0},主人被惊醒",obj.ToString()));
}
#endregion
}
class Dog : IObserver
{
#region IObserver 成员
public void Notify(object obj)
{
Console.WriteLine(string.Format("{0},狗拿耗子,多管闲事", obj.ToString()));
}
#endregion
}
class Cat:IObservable
{
private Dictionary<IObserver, IObserver> _observerContainer = new Dictionary<IObserver, IObserver>();
public void Cry()
{
Console.WriteLine("猫叫了");
}
#region IObservable 成员
public void Register(IObserver observer)
{
if (_observerContainer.ContainsKey(observer))
_observerContainer.Remove(observer);
_observerContainer.Add(observer,observer );
}
public void UnRegister(IObserver observer)
{
if (_observerContainer.ContainsKey(observer))
_observerContainer.Remove(observer);
}
public void Notify(object obj)
{
foreach (IObserver o in _observerContainer.Keys)
{
_observerContainer[o].Notify(obj);
}
}
#endregion
}
}
第二种是在.NET 框架的基础之上的观察者,也就是事件委托类型的观察者,不需要在被观察者中注册观察者,降低了观察者和被观察者的耦合度。
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApp
{
public delegate void ObserverEventHandler(object sender, EventObjectArgs e);
/// <summary>
/// 被观察者
/// </summary>
public interface IEventObserable
{
event ObserverEventHandler ObserverEvent;
void OnObserverEvent(EventObjectArgs e);
void RaiseObserverMethod();
}
/// <summary>
/// 观察者
/// </summary>
public interface IEventObserver
{
}
public class EventObjectArgs : EventArgs
{
private string _message;
public string Message
{
get { return _message; }
}
public EventObjectArgs()
{
}
public EventObjectArgs(string message)
{
this._message = message;
}
}
class EventCat : IEventObserable
{
#region IEventObserable 成员
public event ObserverEventHandler ObserverEvent;
public void OnObserverEvent(EventObjectArgs e)
{
if (null != ObserverEvent)
{
ObserverEvent(this, e);
}
}
public void RaiseObserverMethod()
{
Console.WriteLine("猫叫了");
OnObserverEvent(new EventObjectArgs("猫叫了"));
}
#endregion
}
class EventMouse : IEventObserver
{
public EventMouse() { }
public EventMouse(IEventObserable observable)
{
observable.ObserverEvent += new ObserverEventHandler(observable_ObserverEvent);
}
public void observable_ObserverEvent(object sender, EventObjectArgs e)
{
Console.WriteLine(string.Format("{0},所有老鼠被吓跑了", e.Message));
}
}
class EventDog : IEventObserver
{
public EventDog(IEventObserable observable)
{
observable.ObserverEvent += new ObserverEventHandler(observable_ObserverEvent);
}
public void observable_ObserverEvent(object sender, EventObjectArgs e)
{
Console.WriteLine(string.Format("{0},所有老鼠被吓跑了,但是狗拿耗子多管闲事", e.Message));
}
}
class EventMaster : IEventObserver
{
public EventMaster(IEventObserable observable)
{
observable.ObserverEvent += new ObserverEventHandler(observable_ObserverEvent);
}
public void observable_ObserverEvent(object sender, EventObjectArgs e)
{
Console.WriteLine(string.Format("{0},所有老鼠被吓跑了,但是狗拿耗子多管闲事,主人生气了,要打死这些动物", e.Message));
}
}
}
下面是他们的调用代码,是一个Console应用程序
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApp
{
public class Model
{
public object ModelState { get; set; }
}
public class Command
{
public void DoCommand()
{ }
}
public class Selection : EventArgs
{
public object State { get; set; }
}
public class Interactor
{
public delegate void AddItemEventHandler(object sender, Selection e);
public event AddItemEventHandler ItemAdded;
protected virtual void OnItemAdded(Selection e)
{
if (ItemAdded != null)
ItemAdded(this, e);
}
public void AddItem(object value)
{
Selection selection = new Selection() { State = value };
OnItemAdded(selection);
}
}
public class Presenter
{
private readonly Command command;
private readonly Interactor interactor;
private readonly Model model;
private readonly View view;
public Presenter(Interactor interactor)
{
this.command = new Command();
this.model = new Model();
this.view = new View();
this.interactor = interactor;
this.interactor.ItemAdded += new Interactor.AddItemEventHandler(interactor_ItemAdded);
}
void interactor_ItemAdded(object sender, Selection e)
{
this.command.DoCommand();
this.model.ModelState = e.State;
this.view.Update ("Processed " + e.State);
}
}
public class View
{
private object ViewState;
static void Main(string[] args)
{
#region Model View Presenter Design Pattern
Interactor interactor = new Interactor();
Presenter presenter = new Presenter(interactor);
interactor.AddItem("Message from the UI");
#endregion
#region 普通观察着模式
Mouse mouse = new Mouse();
Master master = new Master();
Dog dog = new Dog();
Cat cat = new Cat();
cat.Register(mouse);
cat.Register(master);
cat.Register(dog);
cat.Cry();
cat.Notify("猫叫了");
cat.UnRegister(mouse);
cat.UnRegister(master);
cat.UnRegister(dog );
#endregion
#region 基于事件和委托的观察者模式
EventCat eventCat = new EventCat();
EventMouse eventMouse = new EventMouse(eventCat);
EventDog eventDog = new EventDog(eventCat);
EventMaster eventMaster = new EventMaster(eventCat);
eventCat.RaiseObserverMethod();
#endregion
Console.ReadLine();
}
public void Update(object state)
{
ViewState = state;
}
}
}