先说明一下观察者模式:观察者模式|菜鸟教程
我用最简单的方式将原理实现了一下:
//被观察者父类,主要有Attach、Detach、Notify函数
//被观察者父类
public class Subject : MonoBehaviour
{
//记录注册的观察者
private List<Observer> observerList = new List<Observer>();
//注册观察者
public void Attach(Observer observer)
{
if (!observerList.Contains(observer))
observerList.Add(observer);
}
//注销观察者
public void Detach(Observer observer)
{
if (observerList.Contains(observer))
observerList.Remove(observer);
}
//通知所有注册的观察者
public void Notify(params object[] args)
{
for (int i = 0; i < observerList.Count; i++)
{
observerList[i].OnNotify(args);
}
}
}
//观察者父类,有OnNotify抽象函数,具体逻辑在每个子类中实现
//观察者父类
public abstract class Observer : MonoBehaviour
{
//接受通知接口
public abstract void OnNotify(params object[] args);
}
//测试类,被观察者子类
//被观察者测试类
public class TestSubject : Subject
{
//单例
private static TestSubject instance;
public static TestSubject Instance { get { return instance; } }
private void Awake()
{
instance = this;
}
private void Update()
{
//按键发送通知
if(Input.anyKeyDown)
{
Notify("Input Key");
}
}
}
//测试类,观察者子类
//观察者测试类
public class TestObserver : Observer
{
private void OnEnable()
{
//在被观察者中注册监听
TestSubject.Instance.Attach(this);
}
private void OnDisable()
{
//在被观察者中注销监听
TestSubject.Instance.Detach(this);
}
//接受通知函数
public override void OnNotify(params object[] args)
{
if (args.Length > 0)
Debug.Log(args[0]);
}
}
优缺点都有,合理使用的话,还是非常方便有效的:
优点:
1、观察者和被观察者是抽象耦合的。
2、建立一套触发机制,跨模块更新数据非常方便
缺点:
1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
-----------------------------------------------------------------------------------------
利用委托可以简化以上观察者模式,不过仅适用于代码结构相对简单,功能模块较少的小游戏,慎用~
//被观察者
//被观察者测试类
public class TestSubject : MonoBehaviour
{
//单例
private static TestSubject instance;
public static TestSubject Instance { get { return instance; } }
public System.Action<string> NotifyAction;
private void Awake()
{
instance = this;
}
private void Update()
{
//按键发送通知
if(Input.anyKeyDown)
{
if(NotifyAction != null)
NotifyAction("Input Key");
}
}
}
//观察者
//观察者测试类
public class TestObserver : MonoBehaviour
{
private void OnEnable()
{
//在被观察者中注册监听
TestSubject.Instance.NotifyAction += OnNotify;
}
private void OnDisable()
{
//在被观察者中注销监听
TestSubject.Instance.NotifyAction -= OnNotify;
}
//接受通知函数
void OnNotify(string arg)
{
Debug.Log(arg);
}
}