【观察者模式】
观察者模式定义了一种一对多的依赖关系,让多个观察对象同时监听一个主题对象。这个主题对象再状态发生变换时候,会通知所有观察者对象,使他们能够自动更新自己。
【介绍】
-
主要解决:一个对象改变状态给其他对象通知的问题
-
何时使用:一个对象(目标对象)的状态发生变化,所有的依赖对象(观察者对象)都将得通知,进行广播通知
-
如何解决:使用面向对象技术,可以将这种依赖关系弱化
-
关键代码:在抽象类里有一个ArraList存放着观察者
-
优点:观察者和被观察者是抽象耦合的;建议一套触发机制
-
缺点:1、如果一个被观察者对象有很多的直接和间接的观察者,将所有的观察者都通知到会花费很多时间。2、如果观察者和被观察者之间有循环依赖,被观察者会触发他们之间进行循环调用,可能导致系统崩溃。3、观察者模式没有相应的机制让观察者知道所观察的目对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化
-
注意事项:避免循环引用;如果顺序执行,某一观察者错误会导致系统卡死,一部采用异步方式
【实现】
步骤一:subject类,为抽象主题提供一个接口
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();
}
}
}
步骤二:observer类,抽象观察者
abstract class Observer
{
public abstract void Update();
}
步骤三:ConcreteSubject类,具体主题或者具体通知者
class ConcreteSubject:Subject
{
private string subjectState;
//具体被观察者状态
public string SubjectState
{
get { return subjectState; }
set { subjectState = value; }
}
}
步骤四:ConcreteObserver类,具体观察者
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; }
}
}
步骤五:客户端代码
static void Main(string[] args)
{
ConcreteSubject s = new ConcreteSubject();
s.Attach(new ConcreteObserver(s, "张三"));
s.Attach(new ConcreteObserver(s,"李四"));
s.SubjectState = "斗地主";
s.Notify();
Console.Read();
}
【总结】