观察者模式?
又叫发布-订阅(Publish/Subscribe)模式,当一个对象的改变需要同时改变其它对象的时候,考虑用观察者模式。
观察者模式的不足?
(1)‘抽象通知者’依赖于‘抽象观察者’(2)观察者的方法相同
事件委托?
委托的实例是一个具体的函数。
事件委托VS观察者模式?
(1)‘抽象通知者’不依赖‘抽象观察者’(2)观察者可以有不同的多个方法。利用委托搭载便可以调用
观察者模式实例:
类
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();
}
//z增加两个具体观察者
//看股票的同事
class StockObserve : Observer
{
public StockObserve(string name, Subject sub)
: base(name, sub)
{
}
public override void Update()
{
Console.WriteLine("{0}{1}关闭股票行情,继续工作!", sub.SubjectState, name);
}
}
//看NBA的同事
class NBAObserver : Observer
{
public NBAObserver(string name, Subject sub)
: base(name, sub)
{ }
public override void Update()
{
Console.WriteLine("{0}{1}关闭NBA直播,继续工作!", sub.SubjectState, name);
}
}
interface Subject //接口通知者
{
void Attach(Observer observer);
void Detach(Observer observer);
void Notify();
string SubjectState
{
get;
set;
}
}
class Boss : Subject
{
//同事列表
private IList<Observer> observers = new List<Observer>();
private string action;
//增加
public void Attach(Observer observer)
{
observers.Add(observer);//同事增加
}
//减少
public void Detach(Observer observer)
{
observers.Remove(observer);
}
//通知
public void Notify()
{
foreach (StockObserve o in observers)
o.Update();//老板来了,所有登记的同事们发通知,“老板来了”
}
//前台状态
public string SubjectState
{
get { return action; }
set { action = value; }//前台通过电话
}
}
客户端:
//老板
Boss boss = new Boss();
//看股票的同事
StockObserve tongshi1 = new StockObserve("gusshen", boss);
//NBA
StockObserve tongshi2 = new StockObserve("NBA", boss);
boss.Attach(tongshi1);
boss.Attach(tongshi2);
boss.Detach(tongshi2);
//老板回来
boss.SubjectState = "boss来了";
boss.Notify();
Console.Read();
改进:事件委托实现(去掉抽象观察类。)
interface Subject//通知者接口
{
void Notify();
string SubjectState
{
get;
set;
}
}
class StockObserve
{
private string name;
private Subject sub;
public StockObserve (string name,Subject sub)
{
this.name =name ;
this.sub =sub;
}
public void ClosefStockMarket()
{
Console.WriteLine("{0}{1}关闭股票行情,继续工作!",sub.SubjectState ,name );
}
}
class NBAObserver
{
private string name;
private Subject sub;
public NBAObserver (string name,Subject sub)
{
this.name =name ;
this.sub =sub;
}
public void ClosefNBADirectSeeding()
{
Console.WriteLine("{0}{1}关闭股票行情,继续工作!",sub.SubjectState ,name );
}
}
delegate void EventHandler();
//前台秘书类
class Secretary:Subject
{
//声明事件Update,类型委托
public event EventHandler Update;
//通知
public void Notify()
{
Update();//老板来了,所有登记的同事们发通知,“老板来了”
}
//前台状态
private string action;
public string SubjectState
{
get { return action; }
set { action = value; }//前台通过电话
}
}
class Boss : Subject
{
//声明事件Update,类型委托
public event EventHandler Update;
//通知
public void Notify()
{
Update();//老板来了,所有登记的同事们发通知,“老板来了”
}
//前台状态
private string action;
public string SubjectState
{
get { return action; }
set { action = value; }//前台通过电话
}
}
客户端
//老板
Boss boss = new Boss();
StockObserve tongshi1 = new StockObserve("天天", boss);
NBAObserver tongshi2 = new NBAObserver ("明明", boss);
boss .Update +=new EventHandler (tongshi1.ClosefStockMarket );
boss.Update += new EventHandler(tongshi2.ClosefNBADirectSeeding );
boss.SubjectState = "老板来了";
boss.Notify();
Console.Read ();