一、举例
自从上了大学手机流量与老师讲课的吸引力呈负相关。同学A在玩手机就提前让旁边的同学B看着老师,如果当老师走过来时B通知A,那A立即停下玩手机的动作进入听课,但是B没有及时通知A,那么A就被老师抓住。同学A,B,老师就是观察者模式在现实生活中的例子。
二、定义与结构图
观察者模式又叫发布-订阅模式,定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象发生变化时,会通知所有的观察者对象,使他们能自动更新
a、Subject类,它把所有对观察者对象的引用保存在一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象
b、ConcreteSubject类,具体主题,将有关状态存入具体观察者对象;在具体主题的内部状态改变时;给所有登记过得观察者发出通知
c、Observer类,抽象观察者,为所有的观察者定义一个接口,在得到主题里通知时更新自己
d、ConcreteObserver,具体观察者实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调
三、代码
以上边说的上课的例子写了一段代码
1、代码结构图:
2、代码
//通知者接口 interface Subject { void Attach(Observer observer); void Detch(Observer observer); void Notify(); string SubjectState { get; set; } } //具体通知者 class Teacher:Subject { private IList<Observer> observers = new List<Observer>(); private string action; public void Attach(Observer observer) //增加 { observers.Add(observer ); } public void Detch(Observer observer) //减少 { observers.Remove(observer ); } public void Notify() //通知 { foreach (Observer o in observers) o.Update(); } public string SubjectState //老师状态 { get { return action; } set { action = value; } } } class ClassMates:Subject //同学 { private IList<Observer> observers = new List<Observer>(); private string action; public void Attach(Observer observer) //增加 { observers.Add(observer); } public void Detch(Observer observer) //减少 { observers.Remove(observer); } public void Notify() //通知 { foreach (Observer o in observers) o.Update(); } public string SubjectState //同学状态 { get { return action; } set { action = value; } } } //抽象观察者 abstract class Observer { protected string name; protected Subject sub; public Observer (string name,Subject sub) { this.name=name; this.sub=sub; } public abstract void Update(); } class OnlineObserver : Observer //上网同学 { public OnlineObserver(string name, Subject sub) : base(name, sub) { } public override void Update() { Console.WriteLine("{0}{1}停止上网,听课!",sub .SubjectState ,name ); } } class SleepingObserver : Observer //睡觉的同学 { public SleepingObserver(string name, Subject sub) : base(name, sub) { } public override void Update() { Console.WriteLine("{0}{1}停止睡觉,听课!",sub .SubjectState ,name ); } }客户端代码
static void Main(string[] args) { //王老师 Teacher wang = new Teacher(); //上网的同学 OnlineObserver tongxue1 = new OnlineObserver("朱火云",wang ); //睡觉的同学 SleepingObserver tongxue2 = new SleepingObserver("刘佳翰",wang ); wang.Attach(tongxue1 ); wang.Attach(tongxue2); wang.Detch(tongxue1); wang.SubjectState = "王老师过来了"; wang.Notify(); //发出通知 Console.Read(); }运行结果:
总的来说观察者所做的工作就是在解除耦合,让耦合的双方都依赖于抽象,而不依赖于具体,从而使各自的变化都不影响另一边