14总结
使用场景:
具体的通知者,将有关状态存入具体的观察者对象,在具体通知者内部状态改变时,给所有登记过的观察者发出通知,就是通知者发现老板来了,要赶紧通知正在摸鱼的同事们。
//具体通知者
class ConcreteSubject : Subject
{
private string subjectState;
//具体通知者状态
public string SubjectState
{
get { return subjectState; }
set { subjectState = value; }
}
}
13客户端
class Program
{
static void Main(string[] args)
{
ConcreteSubject s = new ConcreteSubject();
s.Attach(new ConcreteObserver(s, "X"));
s.Attach(new ConcreteObserver(s, "Y"));
s.Attach(new ConcreteObserver(s, "Z"));
s.SubjectState = "ABC";
s.Notify();
Console.Read();
}
}
独立的观察者类都需要实现一个Observer的接口,而有些独立的类之间并没有观察者接口,如果没有,通知就没法下发了。
12观察者
观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。:::
一个委托可以搭载多个方法,所有方法被依次唤起。方法的入参和返回值要与委托的定义相同。:::看具体代码:
using System;
using System.Collections.Generic;
using System.Text;
namespace 观察者模式
{
class Program
{
static void Main(string[] args)
{
//老板Randy
Boss huhansan = new Boss();
//看股票的同事
StockObserver tongshi1 = new StockObserver("阿三", huhansan);
//看NBA的同事
NBAObserver tongshi2 = new NBAObserver("大头", huhansan);
/// 将不同的方法搭载到老板的更新上,从而通知观察者做各自的更新,
// 观察者不需要统一的Observer接口
huhansan.Update += new EventHandler(tongshi1.CloseStockMarket);
huhansan.Update += new EventHandler(tongshi2.CloseNBADirectSeeding);
//老板回来
huhansan.SubjectState = "我Randy回来了!";
//发出通知
huhansan.Notify();
Console.Read();
}
}
//通知者接口
interface Subject
{
void Notify();
string SubjectState
{
get;
set;
}
}
//事件处理程序的委托
delegate void EventHandler();
class Secretary : Subject
{
//声明一事件Update,类型为委托EventHandler
public event EventHandler Update;
private string action;
public void Notify()
{
Update();
}
public string SubjectState
{
get { return action; }
set { action = value; }
}
}
class Boss : Subject
{
//声明一事件Update,类型为委托EventHandler
public event EventHandler Update;
private string action;
public void Notify()
{
Update();
}
public string SubjectState
{
get { return action; }
set { action = value; }
}
}
//看股票的同事
class StockObserver
{
private string name;
private Subject sub;
public StockObserver(string name, Subject sub)
{
this.name = name;
this.sub = sub;
}
//关闭股票行情
public void CloseStockMarket()
{
Console.WriteLine("{0} {1} 关闭股票行情,继续工作!", sub.SubjectState, name);
}
}
//看NBA的同事
class NBAObserver
{
private string name;
private Subject sub;
public NBAObserver(string name, Subject sub)
{
this.name = name;
this.sub = sub;
}
//关闭NBA直播
public void CloseNBADirectSeeding()
{
Console.WriteLine("{0} {1} 关闭NBA直播,继续工作!", sub.SubjectState, name);
}
}
}
结果:
运行结果:
14观察者模式
12定义
当一个对象的改变需要同时改变其他对象的时候,并且不知道具体有多少对象需要改变;一个抽象模型有2个方面,一方面依赖于另一方面,可以将两者封装在独立的对象中,使他们各自独立地改变和复用;观察者模式就是解除耦合,耦合的双方都依赖于抽象而非具体。
最近加班越来越多,阿三感到非常疲惫,于是上班的时候想摸摸鱼。于是趁老板出去的时候,打开手机,看看股票是否跌破3000点了,看看基金有没有扳回来一点。但是万一老板回来了怎么办?还好他人脉广,认识前台的大头,跟大头打个招呼,老板一回来,就发个信息给他。
观察者与通知者均使用抽象类,方便通知者和观察者的扩展与个例的实现,观察不同对象,通知者也有不同的通知形式。
11通知者
抽象观察者,在得到通知者的通知时,更新自己,这个接口叫更新接口,通常包含一个Update方法,这个方法叫更新方法
abstract class Observer
{
public abstract void Update();
}
应该由客户端决定,谁改变了通知谁。
具体观察者。具体观察者角色可以保存一个指向具体通知者对象的引用。
class ConcreteObserver : Observer
{
private string name;
private string observerState;
private ConcreteSubject subject;
public ConcreteObserver(ConcreteSubject subject, string name)
{
this.subject = subject;
this.name = name;
}
//更新
public override void Update()
{
observerState = subject.SubjectState;
Console.WriteLine("观察者{0}的新状态是{1}",
name, observerState);
}
public ConcreteSubject Subject
{
get { return subject; }
set { subject = value; }
}
}
这就是典型的观察者模式,又叫发布-订阅模式。观其其他事务的状态,根据其状态改变做出对应的策略。
可翻译为主题或抽象通知者,一般用一个抽象类或者一个接口实现,可以添加或者移除观察者,并通知。
abstract class Subject
{
private IList<Observer> observers = new List<Observer>();
//增加观察者
public void Attach(Observer observer)
{
observers.Add(observer);
}
//移除观察者
public void Detach(Observer observer)
{
observers.Remove(observer);
}
//通知
public void Notify()
{
foreach (Observer o in observers)
{
o.Update();
}
}
}
不足:
事件委托
委托就是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托可以有参数和返回值,可以看成是对函数的抽象,是函数的“类”,委托的实例代表一个具体的函数。
文章为作者独立观点,不代表股票交易接口观点