constに反対するためのいくつかの良い議論があります、ここでここに私の見解があります:-
個人的には、これらの「OnXXXUpdated」をマネージャークラスの一部として持っていません。これが、ベストプラクティスに関して混乱が生じる理由だと思います。利害関係者に何かについて通知していて、通知プロセス中にオブジェクトの状態が変更されるかどうかがわかりません。それはそうかもしれないし、そうでないかもしれない。私にとって明らかなことは、利害関係者に通知するプロセスは一定でなければならないということです。
したがって、このジレンマを解決するために、これは私が行うことです。
マネージャクラスからOnXXXXUpdated関数を削除します。
次の前提条件で、通知マネージャーを作成します。これがプロトタイプです。
「Args」は、通知が発生したときに情報を渡すための任意の基本クラスです。
「デリゲート」は、ある種の関数ポインタ(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
おそらくお分かりのように、いくつかのコードを省略しましたが、あなたはその考えを理解しています。このNotificationManagerはシングルトンになると思います。これで、Notification Managerが早い段階で作成されるようになり、残りのマネージャーは次のようにコンストラクターに通知を登録するだけです。
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);
};
他のクラスはこのようなものを聞くことができます。
オブザーバーパターンを入力したばかりだと気づきましたが、問題はこれらがどのように発生しているのか、そしてそれらがconst-stateにあるかどうかにあることを示すことでした。マネージャークラスから通知のプロセスを抽象化することにより、通知の受信者はそのマネージャークラスを自由に変更できます。通知マネージャーではありません。これは公平だと思います。
その上、通知を上げるための単一の場所を持つことは、通知を追跡できる単一の場所を提供するので、良い習慣です。