观察者模式

[ Observer ]

观察者模式 又叫 发布-订阅(Publish/Subscribe)模式

定义了一种一对多的依赖关系 , 让多个观察者对象同时监听某一个主题对象 。这个主题对象在状态发生变化时 , 会通知所有观察者对象 , 使它们能够自动更新自己 。


[
通知者 : 在通知者状态发生改变时 , 给观察者发送消息
观察站 : 在收到通知者的消息时 , 更新自己。
]

这种观察者模式 , 有个缺点就是 , 具体的观察者执行的更改方法名必须是 Update , 如果想执行其他方法的更改可以用 委托 。




使用了委托的观察者模式 :

委托观察者模式 , 减少了 通知者 和 观察者 之间的耦合
委托观察者 , 可以调用 不同 观察者 中的 不同方法




源码 :

interface ISubject
{
/*
用于通知 "观察者" 的 "通知者" 接口
* 它把所有对观察者对象的引用保存在一个聚集里 ,
* 每个主题都可以有任何数量的观察者 。
* 抽象主题(通知者)提供一个接口 , 可以增加和删除观察者对象。
*/

  void Attach(IObserver observer); 添加通知者
  void Detach(IObserver observer); 删除通知者
  void Notify();
  string SubjectState
  { get; set;}
}



// <summary>
// 具体主题(通知者) , 将有关状态存入具体观察者对象 ;
// 在具体主题的内部状态改变时 , 给所有登记过的观察者发出通知。
// </summary>
class Boss : ISubject
{
  private IList<IObserver> list = new List<IObserver>();
  private string _SubjectState;

  #region ISubject 成员

  public void Attach(IObserver observer)
  {
    list.Add(observer);
  }

  public void Detach(IObserver observer)
  {
    list.Remove(observer);
  }

  public void Notify()
  {
    foreach (IObserver o in list)
      o.Update();
  }

  public string SubjectState
  {
    set
    {
      _SubjectState = value;
    }

    get
    {
      return _SubjectState;
    }
  }

  #endregion
}



// <summary>
// 具体主题(通知者) , 将有关状态存入具体观察者对象 ;
// 在具体主题的内部状态改变时 , 给所有登记过的观察者发出通知。
// </summary>
class Secretary : ISubject
{

  private IList<IObserver> list = new List<IObserver>();
  private string _SubjectState;


  #region ISubject 成员

  public void Attach(IObserver observer)
  {
    list.Add(observer);
  }

  public void Detach(IObserver observer)
  {
    list.Remove(observer);
  }

  public void Notify()
  {
    foreach (IObserver o in list)
      o.Update();
  }

  public string SubjectState
  {
    get {
      return _SubjectState;
    }
    set
    {
      _SubjectState = value;
    }
  }

  #endregion
}




interface IObserver
{
/*
抽象观察者 , 为所有的具体观察者定义一个接口 ,
* 在得到主题的通知时更新自己
*/

  void Update(); //对具体观察者的通知方法
}



// <summary>
//具体观察者 , 实现了抽象观察者角色所要求的更新接口 ,
// 以便使本身的状态与主题的状态相协调
// </summary>
class NbaObserver : IObserver
{
  private string _name;
  private ISubject _subject;

  public NbaObserver(string name, ISubject subject)
  {
    _name = name;
    _subject = subject;
  }


  #region IObserver 成员

  public void Update()
  {
    Console.WriteLine("{0} {1} 关闭NBA直播 , 继续工作!",_subject.SubjectState,_name);
  }

  #endregion
}



// <summary>
// 具体观察者 , 实现了抽象观察者角色所要求的更新接口 ,
// 以便使本身的状态与主题的状态相协调
// </summary>
class StockObserver : IObserver
{
  private string _name;
  private ISubject _subject;
  public StockObserver(string name,ISubject subject)
  {
    _name = name;
  }

  #region IObserver 成员

  public void Update()
  {
    Console.WriteLine("{0} {1} 关闭股票行情 , 继续工作!",_subject.SubjectState,_name);
  }

  #endregion
}




class Program
{

  static void Main(string[] args)
  {

    ISubject subject = new Boss(); 声明一个用于通知观察者的对象 — 通知者
    subject.SubjectState = "老板来了"; 通知者的状态
    IObserver nba = new NbaObserver("小赵", subject); 声明一个具体的观察者
    subject.Attach(nba); 把观察者加入通知者的通知列表
    subject.Notify(); 通知者开始对观察者进行通知


    Console.Read();
  }
}



//使用委托的观察者模式

interface ISubject
{
  void Notify();
  string SubjectState
  {

    get; set;

  }
}



class Boss : ISubject
{
  private string _SubjectState;

  public event Observers update; //声明一个事件委托变量

  #region ISubject 成员

  public void Notify()
  {
    update();
  }

  public string SubjectState
  {
    set
    {
      _SubjectState = value;
    }

    get
    {
      return _SubjectState;
    }
  }

  #endregion
}



class Secretary : ISubject
{
  private string _SubjectState;

  public event Observers update; //声明一个事件委托变量

  #region ISubject 成员

  public void Notify()
  {
    update();
  }

  public string SubjectState
  {
    get {
      return _SubjectState;
    }
    set
    {
      _SubjectState = value;
    }
  }

  #endregion
}




// <summary>
// 声明一个委托 , 用于通知者通知不同类里的不同方法
// </summary>
delegate void Observers();



class NbaObserver
{
  private string _name;
  private ISubject _subject;

  public NbaObserver(string name, ISubject subject)
  {
    _name = name;
    _subject = subject;
  }

  public void CloseNba()
  {
    Console.WriteLine("{0} {1} 快关闭 NBA 直播...",_subject.SubjectState,_name);
  }
}



class StockObserver
{
  private string _name;
  private ISubject _subject;
  public StockObserver(string name,ISubject subject)
  {
    _name = name;
    _subject = subject;
  }

  public void CloseStock()
  {
    Console.WriteLine("{0} {1} 快关闭股票行情...", _subject.SubjectState, _name);
  }
}



class Program
{

  static void Main(string[] args)
  {
    Boss boss = new Boss();
    boss.SubjectState = "老板来了";

    StockObserver so = new StockObserver("小赵",boss);
    NbaObserver no = new NbaObserver("小杨",boss);

    boss.update += new Observers(so.CloseStock);
    boss.update += new Observers(no.CloseNba);

    boss.Notify();

    Console.Read();
  }
}

posted on 2012-02-21 12:17  多个马甲  阅读(295)  评论(0)    收藏  举报