观察者模式
一、概述
观察者模式(Observer Parttern)又称发布-订阅模式(Publish/Subscribe Parttern)是软件设计模式的一种,属于行为型模式。在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用做实时事件处理系统。
二、分析
观察者模式定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。
优点
- 观察者模式可以实现表现层和数据逻辑层的分离,并定义了稳定的消息更新传递机制,抽象了更新接口,使得可以有各种各样不同的表示层作为具体观察者角色。
- 观察者模式在观察目标和观察者之间建立一个抽象的耦合。
- 观察者模式支持广播通信。
- 观察者模式符合“开闭原则”的要求。
缺点
- 如果一个观察目标对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
- 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
- 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
三、代码实现
源码:https://github.com/WarZhan/DesignPatterns/tree/master/ObserverPattern
注:一个 Observer 可以同时关注多个 Subject,比如一个班级的学生,可以同时接受语文老师和数学老师的通知。
- 观察者
核心部分:提供一个 Update 接口,方便 主题/通知者(Subject) 在状态改变时调用
/// <summary>
/// 观察者基类
/// </summary>
public abstract class Observer
{
public abstract void Update();
}
- 主题/通知者
核心部分:提供一个列表保存所有注册的 观察者(Observer),在自身状态改变时调用 Notifiy 方法通知观察者
/// <summary>
/// 主题/抽象通知者
/// </summary>
public abstract class Subject
{
private List<Observer> _listObserver = new List<Observer>();
// 通知者(主题)的状态
protected string _subjectState;
public string SubjectState
{
get { return _subjectState; }
set { _subjectState = value; }
}
/// <summary>
/// 增加 观察者
/// </summary>
/// <param name="observer"></param>
public void Attach(Observer observer)
{
_listObserver.Add(observer);
}
/// <summary>
/// 移除观察者
/// </summary>
/// <param name="observer"></param>
public void Detach(Observer observer)
{
_listObserver.Remove(observer);
}
/// <summary>
/// 通知
/// </summary>
public void Notify()
{
_listObserver.ForEach(it => it.Update());
}
}
- 测试代码
static void Main(string[] args)
{
// 主题/被观察者
ConcreteSubject subject = new ConcreteSubject();
// 创建观察者
Observer observerA = new ConcreteObserver("A", subject);
Observer observerB = new ConcreteObserver("B", subject);
Observer observerC = new ConcreteObserver("C", subject);
// 添加观察者 A B C
subject.Attach(observerA);
subject.Attach(observerB);
subject.Attach(observerC);
subject.SubjectState = "Run";
subject.Notify();
Console.WriteLine("-------------------------------------");
subject.Detach(observerB);
subject.SubjectState = "Eat";
subject.Notify();
Console.ReadKey();
}
四、UML 图
参考资料
[1] 观察者模式:https://zh.wikipedia.org/wiki/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F
[2] 观察者模式:https://design-patterns.readthedocs.io/zh_CN/latest/behavioral_patterns/observer.html
[3] 观察者模式:https://www.runoob.com/design-pattern/observer-pattern.html
[4]《大话设计模式》第 14 章 观察者模式
欢迎关注个人公众号,实时推送最新博文!