观察者模式定义
观察者模式是一种行为设计模式, 允许你定义一种订阅机制, 可在对象事件发生时通知多个 “观察” 该对象的其他对象。也就是我们常说的发布-订阅。
观察者模式结构
观察者模式实现
声明抽象观察者(订阅者),也可以是接口
public abstract class Observer
{
public abstract void Update();
}
创建具体观察者,使其继承自抽象观察者
public class ConcertSubject : Subject
{
private string _state;
/// <summary>
/// 具体被观察者状态
/// </summary>
public string State
{
get { return _state; }
set { _state = value; }
}
}
创建抽象发布者
public abstract class Subject
{
private List<Observer> observers = new List<Observer>();
...
/// <summary>
/// 通知
/// </summary>
public void Notify()
{
foreach (var item in observers)
{
item.Update();
}
}
}
创建具体发布者,继承自抽象发布者
public class ConcertSubject : Subject
{
private string _state;
/// <summary>
/// 具体被观察者状态
/// </summary>
public string State
{
get { return _state; }
set { _state = value; }
}
}
客户端代码
ConcertSubject sub = new ConcertSubject();
sub.Addach(new ConcertObserver(sub, "1"));
sub.Addach(new ConcertObserver(sub, "2"));
sub.Addach(new ConcertObserver(sub, "3"));
sub.State = "online";
sub.Notify();
可以结合委托事件实现,具体代码参考仓库代码示例
观察者模式优缺点
优点
- 开闭原则。 无需修改发布者代码就能引入新的订阅者类 (如果是发布者接口则可轻松引入发布者类)。
- 可以在运行时建立对象之间的联系。
缺点
- 订阅者的通知顺序是随机的
观察者模式使用场景
- 当一个对象状态的改变需要改变其他对象,或实际对象是事先未知的或动态变化的时,可使用观察者模式。
- 当你使用图形用户界面类时通常会遇到一个问题。 比如, 你创建了自定义按钮类并允许客户端在按钮中注入自定义代码, 这样当用户按下按钮时就会触发这些代码。
- 观察者模式允许任何实现了订阅者接口的对象订阅发布者对象的事件通知。 你可在按钮中添加订阅机制, 允许客户端通过自定义订阅类注入自定义代码。
- 当应用中的一些对象必须观察其他对象时, 可使用该模式。但仅能在有限时间内或特定情况下使用。
- 订阅列表是动态的, 因此订阅者可随时加入或离开该列表。