观察者模式,有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
优点:
1、通知通信:观察者模式支持广播通信。被观察者会向所有的注册过的观察者发出通知。
2、聚耦合:观察者模式在被观察者和观察者之间建立了一个抽象的耦合,被观察者并不知道任何一个具体的观察者,只是保存着抽象观察者的列表,每个具体观察者都符合一个抽象观察者的接口。
缺点:
1、时间复杂度:如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
2、内联不足:虽然观察者模式可以随时使观察者知道所观察的对象发送了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎样发生变化的。
3、容易出现循环调用:如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃。
eg:小雪有很多追求者,小雪要去旅游,追求者们都要知道小雪的位置变化,追求者们都会时不时的向小雪发消息问小雪的位置,这样导致小雪不能好好的玩,追求者们也不能专心的做自己的事情。如果小雪位置没有变化,还要发送重复的位置,这时候有个观察者模式,只要追求者们订阅小雪的信息,只要位置变化,小雪就回统一发送信息来通知。
public interface IBoy{
void Show(string address);//所有观察者都必须实现
}
//追求者A
{
public void Show(string address)
{
Console.WriteLine("A:"+address);
}
}
//追求者B
{
public void Show(string address)
{
Console.WriteLine("B:" + address);
}
}
//被观察者
public class Gprs
{
//保存观察者列表
private List<IBoy> boys = null;
public Gprs()
{
boys = new List<IBoy>();
}
//添加观察者
public void AddBoy(IBoy b)
{
boys.Add(b);
}
//通知
public void Notify(string address)
{
for (int i = 0; i < boys.Count; i++)
{
boys[i].Show(address);
}
}
//位置发生变化
public void ChangeAddress(string newAddress)
{
Notify(newAddress);
}
}
//调用
Gprs a = new Gprs();
IBoy aaa = new BoyA();
IBoy bbb = new BoyB();
a.AddBoy(aaa);
a.AddBoy(bbb);
a.Notify("我在北京");
a.ChangeAddress("我在上海");