观察者模式介绍
观察者模式面向的需求是:A对象(观察者)对B对象(被观察者)的某种变化高度敏感,需要在B变化的一瞬间做出反应。举个例子,新闻里喜闻乐见的警察抓小偷,警察需要在小偷伸手作案的时候实施抓捕。在这个例子里,警察是观察者、小偷是被观察者,警察需要时刻盯着小偷的一举一动,才能保证不会错过任何瞬间。程序里的观察者和这种真正的【观察】略有不同,观察者不需要时刻盯着被观察者(例如A不需要每隔1ms就检查一次B的状态),二是采用注册(_Register_)或者成为订阅(_Subscribe_)的方式告诉被观察者:我需要你的某某状态,你要在它变化时通知我。采取这样被动的观察方式,既省去了反复检索状态的资源消耗,也能够得到最高的反馈速度。
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合。
何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
关键代码:在抽象类里有一个 ArrayList 存放观察者们。
应用实例: 1、拍卖的时候,拍卖师观察最高标价,然后通知给其他竞价者竞价。 2、西游记里面悟空请求菩萨降服红孩儿,菩萨洒了一地水招来一个老乌龟,这个乌龟就是观察者,他观察菩萨洒水这个动作。3.微信发布一个朋友圈,朋友都会收到通知,然后评论(评论就是触发的反应)
简单例子:
当派发方法执行,观察者就会执行各自对应的方法。
当被观察者做出指示时,需要声明指示的类型,然后从字典中取出对应的监听者,来执行对应的方法。
那么我们就来看看如何在SOCKET中根据收到不同协议情况下使用观察者模式,以下给出了核心代码:
using System.Collections;
using System.Collections.Generic;
public delegate void OnActionHander(byte[] buffer);
public class EventDispatcher : SingleTon<EventDispatcher> {
private Dictionary<ushort, List<OnActionHander>> dic = new Dictionary<ushort, List<OnActionHander>>();
/// 添加监听
public void AddEventListener(ushort protoCode,OnActionHander handler)
{
if (dic.ContainsKey(protoCode))
{
dic[protoCode].Add(handler);
}
else
{
List<OnActionHander> lstHandler = new List<OnActionHander>();
lstHandler.Add(handler);
dic[protoCode] = lstHandler;
}
}
/// 移除事件
public void RemoveEventListener(ushort protoCode,OnActionHander handler)
{
List<OnActionHander> lstHandler=dic[protoCode];
lstHandler.Remove(handler);
if (lstHandler.Count == 0)
{
dic.Remove(protoCode);
}
}
/// 派发协议
public void Dispatch(ushort protoCode,byte[] buffer)
{
if (dic.ContainsKey(protoCode))
{
List<OnActionHander> lstHandler=dic[protoCode];
if (lstHandler != null && lstHandler.Count > 0)
{
for (int i = 0; i < lstHandler.Count; i++)
{
if (lstHandler[i] != null)
{
lstHandler[i](buffer);
}
}
}
}
}
}