观察者模式
观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发送变化的时候会通知所有的观察者对象,是他们能够自动更新自己。
观察者模式的特点和应用场景:
当一个对象的改变需要同时改变其他对象的时候,而且他不知道具体有多少对象有待改变,应该考虑使用观察者模式
一个抽象模型有两个方面,其中一个方面依赖于另一方面,这是用观察者模式可以将两者封装在独立的对象中是他们各自独立的改变和复用
观察者模式的工作其实就是接触耦合,让耦合的双方都依赖于抽象而不是依赖具体。从而使得各自的变化都不会影响另一边的变化
代码图示
插图
Subject:抽象类,将所有对观察者的引用都保存在一个集合中,提供一个接口添加和删除观察者对象
abstract class Subject
{
private IList<Observer> obervers = new List<Observer>();
public void Attach(Observer oberver)
{
obervers.add(obrver);
}
publiv void Detach(Observer observer)
{
obervers.Remove(ovserver);
}
public void Notify()
{
foreach(Observer o in obervers)
{
o.Update();
}
}
}
//具体通知类
class ConcreteSubject : Subject
{
private string subjectState;
public string SubjectState
{
get {return subjectstate ;}
set { subjectstate = value;}
}
}
//抽象观察者
abstract class Observer
{
public abstract void Update();
}
具体观察者
class ConcreteObserrver : Observer
{
private string name;
private string observerState;
private ConcereteSubject subject;
public ConcreteObserver(ConcreteSubject subject)
{
this.subject = subject;
this.name = name;
}
public override void Update()
{
observerState = subject.SubjectState;;
Console.WriteLine("观察者{0}的新状态{1}",name,observerstate);
}
public COncereteSubject Subject
{
get{return subject ;}
set{subject = value ;}
}
}
//客户端代码:
static void Main(string[] args)
{
ConcreteSubject s = new COncreteSubject();
s.Attach(new ConcreteObserver(s,"X"));
s.attach(ne ConcreteObserver{s,"Y"});
s.SubjectState ="abc";
s.Notity();
}
观察者模式的不足和改进
不足表现在抽象通知者还是依赖抽象观察者,如果没有抽象观察者的接口,通知功能就不能完成,
另外美国具体的观察者响应通知的方法不一定是UPdate方法。
理想的方式是观察者和通知者相互不知道,又客户端来决定通知谁
改进:事件委托实现
抽象通知者不希望依赖抽象观察者,可以去掉抽象观察者,直接写具体观察者,比如观察者A和B
calss AObserver
{
private string name;
privte Subject sub;
public AObserver(string name,Subject sub)
{
this.name = name;
this.sub = sub;
}
//观察者A的响应方法
public void ActionA()
{
Console.Writeline("{0},{1}",sub.subjectState,name);
}
}
calss BObserver
{
private string name;
privte Subject sub;
public BObserver(string name,Subject sub)
{
this.name = name;
this.sub = sub;
}
//观察者B的响应方法
public void ActionB()
{
Console.Writeline("{0},{1}",sub.subjectState,name);
}
}
因为抽象通知者不依赖抽象观察者,所以原来“添加”和“减少”观察者的方法也要去掉。简单的使用一个接口就可以
interface Subject
{
void Notify();
string SubjectState
{get;set;}
}
声明委托
delegate void EventHandler();
//具体的通知者
class NotifyAA : Subject
{
pubilc event EventHandler Update;//声明一个事件,类型是委托EventHandler;
private string action;
public void Notify()//实现接口
{
if(Update != null)
{
Update();
}
}
public string SubjectState
{
get {return action;}
set {action = value;}
}
}
//客户端
NotifyAA no = new NotifyAA();
AObserver a = new AObserver("aa",no);
BObserver b = new BObserver("bb",no);
no.Update += new EventHandler(a.ActionA);
no.Update += new EventHandler(B.ActionB);
no.subjectState="变化通知";
no.Notify();
本文使用Blog_Backup未注册版本导出,请到soft.pt42.com注册。