观察者模式(Observer):又叫发布/订阅模式(Publish/Subscribe)
它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对者,使它能够自动更新自己。
使用场合:
当一个对象的改变需要改变其它对象的时候,而且需要同时改变其它对象的时候,应该考虑使用观察者模式。
从这种模式衍生出来的一种技术,叫做事件委托。
委托就是一种引用方法的类型。一旦为委托分配了方法,委托将与方法有相同的行为,委托必须有相同的方法签名(参数和返回值相同)。一个委托可以搭载多个方法,所有方法被依次唤起。可以使委托搭载对象方法并不需要同一个类。
- using System;
- using System.Collections.Generic;
- namespace StuDesignMode.Observer
- {
- /// <summary>
- /// 抽象通知者
- /// </summary>
- interface ISubject
- {
- string SubjectStatus { get; set; }
- /// <summary>
- /// 添加观察者
- /// </summary>
- /// <param name="observer"></param>
- void Attach(AbsObserver observer);
- /// <summary>
- /// 删除观察者
- /// </summary>
- /// <param name="observer"></param>
- void Detach(AbsObserver observer);
- /// <summary>
- /// 通知观察者
- /// </summary>
- void Noticy();
- }
- /// <summary>
- /// 抽象观察者
- /// </summary>
- abstract class AbsObserver
- {
- public string Name { get; set; }
- public ISubject Subject { get; set; }
- public AbsObserver(string name, ISubject subject)
- {
- this.Name = name;
- this.Subject = subject;
- }
- public abstract void Update();
- }
- /// <summary>
- /// 通知者,老板
- /// </summary>
- class Boss : ISubject
- {
- //员工列表
- private IList<AbsObserver> observers = new List<AbsObserver>();
- //老板状态
- public string SubjectStatus { get;set; }
- public void Attach(AbsObserver observer)
- {
- this.observers.Add(observer);
- }
- public void Detach(AbsObserver observer)
- {
- this.observers.Remove(observer);
- }
- public void Noticy()
- {
- foreach (AbsObserver o in observers)
- {
- o.Update();
- }
- }
- }
- delegate void EventHandler();
- /// <summary>
- /// 秘书,将采用事件来通知各员工
- /// </summary>
- class Secretary :ISubject
- {
- public string SubjectStatus { get;set; }
- public event EventHandler Update;
- public void Attach(AbsObserver observer)
- {
- Console.WriteLine("此方法不实现,要使用事件来发布给观察者(订阅者)!");
- }
- public void Detach(AbsObserver observer)
- {
- Console.WriteLine("此方法不实现,要使用事件来发布给观察者(订阅者)!");
- }
- public void Noticy()
- {
- this.Update();
- }
- }
- /// <summary>
- /// 玩游戏的同事
- /// </summary>
- class GamePlayer : AbsObserver
- {
- public GamePlayer(string name, ISubject subject)
- : base(name, subject) { }
- public override void Update()
- {
- Console.WriteLine("{0} {1}游戏存盘,继续工作!",this.Subject.SubjectStatus,this.Name);
- }
- }
- class ChatQQ:AbsObserver
- {
- public ChatQQ(string name, ISubject subject)
- : base(name, subject) { }
- public override void Update()
- {
- Console.WriteLine("{0} {1}关掉QQ,继续工作!",this.Subject.SubjectStatus,this.Name);
- }
- }
- public class ClientTest
- {
- static void Main(string[] args)
- {
- Boss huhansan = new Boss();
- GamePlayer xiaoli = new GamePlayer("小李", huhansan);
- ChatQQ xiaowang = new ChatQQ("小王", huhansan);
- huhansan.Attach(xiaoli);
- huhansan.Attach(xiaowang);
- huhansan.SubjectStatus = "我胡汉三又回来了!";
- huhansan.Noticy();
- Console.WriteLine();
- }
- /// <summary>
- /// 测试使用事件[观察者模式]
- /// </summary>
- public static void TestEventHandler()
- {
- Secretary qiantai = new Secretary();
- GamePlayer xiaoli = new GamePlayer("小李", qiantai);
- ChatQQ xiaowang = new ChatQQ("小王", qiantai);
- qiantai.Update += new StuDesignMode.Observer.EventHandler(xiaoli.Update);
- qiantai.Update += new StuDesignMode.Observer.EventHandler(xiaowang.Update);
- //取消订阅
- qiantai.Update -= new StuDesignMode.Observer.EventHandler(xiaowang.Update);
- qiantai.SubjectStatus = "老板回来了";
- qiantai.Noticy();
- }
- }
- }