观察者模式
观察者模式是对象行为型模式,使用订阅制模式,当发送者状态发生改变时,它可以向订阅者发出通知并使得订阅者进行更新。
观察者模式非常常见,如微信公众号,平台消息等,都算是观察者模式的行为,C# 中 event 事件就是一种观察者模式。观察者模式非常常用,主要是针对一对多的单向连接,这种动态的订阅和取消订阅的方式,来轻松建立连接。
结构
说明
- 抽象主题(Subject,可选)- 管理和保存观察者对象,提供一些通知观察者方法。
- 具体主题(Concrete Subject)- 实现抽象方法,当状态发生改变时,通知所有注册的观察者。
- 抽象观察者(Obverser)- 接口声明通知方法,该接口包含一个更新方法, 该方法可以拥有多个参数, 使发布者能在更新时传递事件的详细信息。
- 具体观察者(Concrete Obverser)- 实现抽象方法,即通知时的更新方法。
实现
观察者接口
public interface IObserver
{
void Reponse();
}
观察者对象(通知时,变为青色)
public class Observer : MonoBehaviour, IObserver
{
public void Reponse()
{
GetComponent<MeshRenderer>().material.color = new Color(0.33f, 1f, 0.14f);
}
}
抽象按钮(抽象主题)
public abstract class Buttom
{
protected IList<IObserver> _observers = new List<IObserver>();
public void Add(IObserver observer) => _observers.Add(observer);
public void Remove(IObserver observer) => _observers.Remove(observer);
public abstract void Notify();
}
发送者(具体主题)
public class PublisherButtom : Buttom
{
public override void Notify()
{
foreach (IObserver observer in _observers)
{
observer.Reponse();
}
}
}
客户端
public class ObverserExample : MonoBehaviour
{
[SerializeField] private List<Observer> _observers;
private PublisherButtom _buttom;
private void Awake()
{
_buttom = new PublisherButtom();
}
private void Start()
{
foreach (var observer in _observers)
_buttom.Add(observer);
}
private void OnGUI()
{
GUILayout.BeginArea(new Rect(10, 10, 200, 200));
if (GUILayout.Button("发送"))
_buttom.Notify();
GUILayout.EndArea();
}
}
添加对象
应用场景
- 当对象结构出现一对多关系,即一个对象的改变会影响其他对象
- 需要实现广播机制和订阅机制时,无需关注接收者,只需发送即可
- 当应用中其他对象必须观察某些对象从而进行改变时。 但仅能在有限时间内或特定情况下使用。
优缺点
优点
- 无需修改发布者代码,当有新的观察者加入时。
- 降低发送者和接收者的耦合
- 在运行时动态的订阅和取消订阅
缺点
- 无法控制通知顺序