观察者模式
[ 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();
}
}