Factory改造計画1

LokiにFactoryと言うクラスがありますが、私はこれがめっちゃ好きでよく使ってます。
たとえばシリアライズクラスやリモートプロキシクラスのオブジェクト生成部分とか
果てはゲームなどのシーンの生成やいろんなファイルフォーマットのリードオブジェクトの生成などなど。
で、もちろん若干いじってありまして3番目のテンプレート引数がこんな感じに。。


<
typename TAbstractProduct,
typename TIdentifyType,
typename TProductCreator = boost::function::ReturnType ()>
>
class Factory
とLokiとboostの夢の合体ですw
挙句に直接shared_ptrを返せるように

template
struct Product
{
typedef T* ReturnType;
};
template
struct Product >
{
typedef shared_ptr< U > ReturnType;
};
というTraitsクラスを作っておき
Factory::CreateObjectを

typename Product::ReturnType CreateObject(const IdentifyType& id)
という実装にしてあげます。

こんな風にしておけばboost::functionが関数ポインタでも生成ファンクタでもなんでも受け付けてくれるし
shared_ptrに入った安全な型が手に入ります。
が。。。最近なんかここまでやる必要はなかったなぁ・・とおもてます。
と言うのは私の使い方はほとんど決まりきっていてテンプレート第三引数のTProductCreatorは
ほとんどがoperator()をもってるファンクタです。
わざわざboost::functionを使う必要もないでしょう。

ということでテンプレート関数のオーバーロードに型つっこんじゃう例のアレで
ファンクタ専門のバージョンを実装してみました。


/*==============================================================================*/
/*=
/*= ProductTraits
/*=
/*==============================================================================*/
template
struct ProductTraits
{
typedef T* ReturnType;
};

/*==============================================================================*/
/*=
/*= Factory
/*=
/*==============================================================================*/
template
class Factory
{
typedef TAbstractProduct AbstractProduct;
typedef TIdentifyType IdentifyType;
typedef typename ProductTraits::ReturnType ReturnType;
public:
struct Invoker
{
template
static ReturnType InvokeCreater()
{
return Pred()();
}
};

template
bool Regist(const IdentifyType& id)
{
return mFunctorMap.insert(std::make_pair(id, typename Invoker::InvokeCreater)).second;
}
bool Unregist(const IdentifyType& id)
{
return mFunctorMap.erase(id)==1;
}
ReturnType CreateObject(const IdentifyType& id)
{
std::map::iterator i = mFunctorMap.find(id);
if (i != mFunctorMap.end())
{
return (i->second)();
}
throw std::exception("CreateObject 登録されていないIDでCreateObjectが呼ばれました");
}
private:
std::map mFunctorMap;
};

決まりきった使い方しかしないならこっちのが依存がすくなくていいでしょう。
まぁパフォーマンスの違いはないでしょうけどね。