每次对象说“调用开始事件”时,我都必须遍历游戏中的每个实体,并确定它们是否在“监听”该事件。
你这样做是错的!遍历每个对象并检查它们是否已注册事件是非常低效的!这是典型的观察者设计模式,有几种方法可以解决这个问题,这里有几个:
- 有一个事件被引发并有一个事件类型的枚举参数(每个订阅者都得到它)。
- 有一个枚举和相应事件的字典。
以下是选项 1的样子:
delegate void OnEventDelegate(kEvents anEvent);
public class MyEventObservable
{
public event OnEventDelegate OnEvent;
}
public class MyEventObserver
{
// Constructors and all
// ...
public void OnEventReceived(kEvents anEvent)
{
switch(anEvent)
{
// switch through all the events and handle the ones that you need
}
}
}
MyEventObserver observer = new MyEventObserver();
MyEventObservable observable = new MyEventObservable();
observable.OnEvent += new OnEventDelegate(observer.OnEventReceived);
这是选项2:
public class MyEventObservable
{
private Dictionary<kEvents, List<IObserver>> _observers;
MyEventObservable()
{
// Initialize the dictionary with all the events
}
public void RegisterObserver(kEvents event, IObserver observer)
{
_observers[event].Add(observer);
}
}
interface class IObserver
{
void Notify(kEvents anEvent);
}
public MyEventObserver: IObserver
{
// Constructors and all
// ...
// Override the IObserver
public void Notify(kEvents anEvent)
{
switch(anEvent)
{
// switch through all the events and handle the ones that you need
}
}
}
MyEventObserver observer = new MyEventObserver();
MyEventObservable observable = new MyEventObservable();
observable.RegisterObserver(kEvents.Start, observer);
选项二将减少每个观察者必须处理的事件数量,但其代价是必须分别注册每个事件(这增加了编码复杂性)。这意味着选项 2 将工作得更快,因为要进行的函数调用更少。根据您想要获得的性能有多“疯狂”,可能还有其他选项可以帮助您加快速度,但这应该会让您走上正确的轨道。
PS 我没有编译任何代码,但它应该让你大致了解事情应该如何工作。