一,观察者模式
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。
别名
- 发布-订阅(Publish/Subscribe)模式
- 模型-视图(Model/View)模式
- 源-监听器(Source/Listener)模式
- 从属者(Dependents)模式
二,介绍
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
如何解决:使用面向对象技术,可以将这种依赖关系弱化。
关键代码:在抽象类里有一个 ArrayList 存放观察者们。
应用实例:
1、拍卖的时候,拍卖师观察最高标价,然后通知给其他竞价者竞价。 2、西游记里面悟空请求菩萨降服红孩儿,菩萨洒了一地水招来一个老乌龟,这个乌龟就是观察者,他观察菩萨洒水这个动作。
优点:
1、观察者和被观察者是抽象耦合的。
2、建立一套触发机制。
缺点:
1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
使用场景:
1、有多个子类共有的方法,且逻辑相同。
2、重要的、复杂的方法,可以考虑作为模板方法。
注意事项:
1、JAVA 中已经有了对观察者模式的支持类。
2、避免循环引用。
3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。
三,实现(C#)
观察者模式包含以下4个角色:
- Subject(目标)
- ConcreteSubject(具体目标)
- Observer(观察者)
- ConcreteObserver(具体观察者)
class Program
{
static void Main(string[] args)
{
Subject subject = new ConcreteSubject();
Observer observer = new ConcreteObserver();
subject.Attach(observer);
subject.Notify();
}
}
//典型的抽象目标类代码
abstract class Subject
{
//定义一个观察者集合用于存储所有观察者对象
protected ArrayList observers = new ArrayList();
//声明抽象注册方法,用于向观察者集合中增加一个观察者
public abstract void Attach(Observer observer);
//声明抽象注销方法,用于在观察者集合中删除一个观察者
public abstract void Detach(Observer observer);
//声明抽象通知方法
public abstract void Notify();
}
//典型的具体目标类代码
class ConcreteSubject : Subject
{
public override void Attach(Observer observer)
{
observers.Add(observer);
}
public override void Detach(Observer observer)
{
observers.Remove(observer);
}
//实现通知方法
public override void Notify()
{
//遍历观察者集合,调用每一个观察者的响应方法
foreach (object obs in observers)
{
((Observer)obs).Update();
}
}
}
//典型的抽象观察者代码
interface Observer
{
void Update();
}
//典型的具体观察者代码
class ConcreteObserver : Observer
{
//实现响应方法
public void Update()
{
//具体更新代码
}
}
四,参考资料
http://www.runoob.com/design-pattern/observer-pattern.html
http://wenku.baidu.com/view/35d085731ed9ad51f01df2f9.html