Есть несколько хороших аргументов против const , вот мой выбор: -
Лично у меня не было бы этих "OnXXXUpdated" как части моих классов менеджера.Я думаю, именно поэтому существует некоторая путаница в отношении наилучшей практики.Вы уведомляете заинтересованные стороны о чем-то и не знаете, изменится ли состояние объекта в процессе уведомления.Это может или не может.Что является очевидным для меня, так это то, что процесс уведомления заинтересованных сторон должен быть константой.
Итак, чтобы решить эту дилемму, это то, что я хотел бы сделать:
Избавьтесь от функций OnXXXXUpdated от классов вашего менеджера.
Напишите менеджер уведомлений, вот прототип, со следующими допущениями:
«Аргументы»произвольный базовый класс для передачи информации, когда происходят уведомления
«Делегат» - это своего рода указатель на функцию (например, FastDelegate).
class Args
{
};
class NotificationManager
{
private:
class NotifyEntry
{
private:
std::list<Delegate> m_Delegates;
public:
NotifyEntry(){};
void raise(const Args& _args) const
{
for(std::list<Delegate>::const_iterator cit(m_Delegates.begin());
cit != m_Delegates.end();
++cit)
(*cit)(_args);
};
NotifyEntry& operator += (Delegate _delegate) {m_Delegates.push_back(_delegate); return(*this); };
}; // eo class NotifyEntry
std::map<std::string, NotifyEntry*> m_Entries;
public:
// ctor, dtor, etc....
// methods
void register(const std::string& _name); // register a notification ...
void unRegister(const std::string& _name); // unregister it ...
// Notify interested parties
void notify(const std::string& _name, const Args& _args) const
{
std::map<std::string, NotifyEntry*>::const_iterator cit = m_Entries.find(_name);
if(cit != m_Entries.end())
cit.second->raise(_args);
}; // eo notify
// Tell the manager we're interested in an event
void listenFor(const std::string& _name, Delegate _delegate)
{
std::map<std::string, NotifyEntry*>::const_iterator cit = m_Entries.find(_name);
if(cit != m_Entries.end())
(*cit.second) += _delegate;
}; // eo listenFor
}; // eo class NotifyManager
Я пропустил некоторый код, как вы, вероятно, можете сказать, но вы поняли идею.Я предполагаю, что этот менеджер уведомлений будет единственным.Теперь, гарантируя, что менеджер уведомлений создан на раннем этапе, остальные ваши менеджеры просто регистрируют свои уведомления в своем конструкторе следующим образом:
MyManager::MyManager()
{
NotificationMananger.getSingleton().register("OnABCUpdated");
NotificationMananger.getSingleton().register("OnXYZUpdated");
};
AnotherManager::AnotherManager()
{
NotificationManager.getSingleton().register("TheFoxIsInTheHenHouse");
};
Теперь, когда вашему менеджеру нужно уведомить заинтересованные стороны, он просто вызываетnotify:
MyManager::someFunction()
{
CustomArgs args; // custom arguments derived from Args
NotificationManager::getSingleton().notify("OnABCUpdated", args);
};
Другие классы могут прослушивать этот материал.
Я понял, что только что набрал шаблон Observer, но я хотел показать, что проблемав том, как эти вещи поднимаются и находятся ли они в постоянном состоянии или нет.Абстрагировав процесс уведомления от класса mananager, получатели уведомления могут свободно изменять этот класс менеджера.Просто не менеджер уведомлений.Я думаю, что это справедливо.
Кроме того, наличие единого места для получения уведомлений - хорошая практика, так как оно дает вам единственное место, где вы можете отслеживать свои уведомления.