3.8.1 模式意图:
在系统中会有一些订阅发布性质的子系统,例如消息系统,用户订阅自己关注的消息,当关注的消息发出时,订阅者也会随之收到相应的推送通知。这也和生活中关注的频道相似,当频道更新时,总会收到对应的推送更新。通过利用订阅发布机制来达到解耦的手段,在设计模式中叫做观察者模式。
3.8.2 模式概念:
它属于行为型模式,定义了一种一对多的依赖关系,让多个观察者监听某一对象。当被监听对象状态发生改变时,会通知所有观察者,使他们能够自动更新自己。
3.8.3 模式元素:
- 订阅目标抽象(ISubject)
- 订阅目标细节(ConcreteSubject)
- 观察者抽象(IObserver)
- 观察者细节(ConcreteObserver1、ConcreteObserver1)
3.8.4 代码示例:
A.订阅目标抽象
public interface ISubject
{
void NotifyObservers();
void RegisterObserver(IObserver observer);
void RemoveObserver(IObserver observer);
}
B. 订阅目标细节
public class ConcreteSubject : ISubject
{
private IList observerList = new List();
private string subjectState;
public void SetState(string State)
{
subjectState = State;
NotifyObservers();
}
public void NotifyObservers()
{
for (int i = 0; i < observerList.Count; i++)
{
observerList[i].Update(subjectState);
}
}
public void RegisterObserver(IObserver observer)
{
observerList.Add(observer);
}
public void RemoveObserver(IObserver observer)
{
observerList.Remove(observer);
}
}
C.观察者抽象
public interface IObserver
{
void Update(string state);
}
D.观察者细节
public class ConcreteObserver1 : IObserver
{
ISubject subject = null;
public ConcreteObserver1(ISubject subject)
{
this.subject = subject;
}
public void Update(string state)
{
Debug.Log($"{nameof(ConcreteObserver1)}+Update:{state}");
}
}
public class ConcreteObserver2 : IObserver
{
ISubject subject = null;
public ConcreteObserver2(ISubject subject)
{
this.subject = subject;
}
public void Update(string state)
{
Debug.Log($"{nameof(ConcreteObserver2)}+Update:{state}");
}
}
示例代码调用
void Start()
{
ConcreteSubject subject = new ConcreteSubject();
ConcreteObserver1 theObserver1 = new ConcreteObserver1(subject);
subject.RegisterObserver(theObserver1);
subject.RegisterObserver(new ConcreteObserver2(subject));
subject.SetState("发布订阅");
}
打印日志
3.8.5 写法对比:
略
3.8.6 模式分析:
观察者模式利用订阅发布机制,当目标自身状态发生改变时,推送信息,而无需知道观察者的数量和执行消息的具体细节。这在系统中是一个非常普遍的解耦手段,例如C#中的委托。
C# 中的委托可以算作观察者模式的简化版,因为只含有对应的行为(函数),而示例中的ConcreteObserver1
,既包含行为(Update
)也可包含数据,在实际操作中会更灵活一些。
3.8.7 应用场景:
当一个对象发生改变,需要通知一个或多个对象且不需要知道具体接收对象的操作细节。
3.8.8 小结:
观察者模式应用最出名的地方就是MVC模式,通过这种订阅发布机制,使操作以消息的方式发出,而无需关注使用者,降低系统中各子系统或子模块间的耦合度。