Factroyとは?
オブジェクトの生成処理をカプセル化し、
クライアントコードから具体的なクラス名を隠蔽する設計。
- 具体的なクラス名を直接記述しないため、クラス間の結合度を低くできる
- 新しい種類のオブジェクトを追加する場合、Factoryクラスを修正するだけなので
柔軟性を向上できる
C++
FactoryMethod.cpp
#include <iostream>
#include <string>
#include <map>
#include <vector>
/// <summary>
/// お祭りの屋台の抽象クラス
/// </summary>
class FestivalShop
{
public:
/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="_name">店の名前</param>
FestivalShop(std::string _name)
{
name = _name;
}
/// <summary>
/// 名前を取得する
/// </summary>
inline std::string GetName(void) const { return name; }
private:
std::string name;
};
/// <summary>
/// 作成の抽象クラス
/// </summary>
class Creator
{
public:
inline virtual FestivalShop* Create(void) const = 0;
};
/// <summary>
/// たこ焼き
/// </summary>
class Takoyaki
: public Creator
{
public:
inline FestivalShop* Create(void) const override
{
return new FestivalShop("たこ焼き");
}
};
/// <summary>
/// 焼きそば
/// </summary>
class Yakisoba
: public Creator
{
public:
inline FestivalShop* Create(void) const override
{
return new FestivalShop("焼きそば");
}
};
/// <summary>
/// チョコバナナ
/// </summary>
class ChocolateBanana
: public Creator
{
public:
inline FestivalShop* Create(void) const override
{
return new FestivalShop("チョコバナナ");
}
};
/// <summary>
/// ベビーカステラ
/// </summary>
class BabyCastella
: public Creator
{
public:
inline FestivalShop* Create(void) const override
{
return new FestivalShop("ベビーカステラ");
}
};
/// <summary>
/// シングルトン
///
/// templateで汎用性強化
/// </summary>
template<typename T>
class Singleton
{
public:
/// <summary>
/// デフォルトコンストラクタ
///
/// コンストラクタは絶対に呼ばない!!
/// </summary>
Singleton() {}
/// <summary>
/// インスタンスを取得する
/// </summary>
static T* GetInstance(void)
{
if (instance == nullptr)
{
// 初回のみ動的確保
instance = new T;
}
return instance;
}
/// <summary>
/// インスタンスを破棄する
/// </summary>
static void DeleteInstance(void)
{
// 削除は動的確保している時のみ
if (instance != nullptr)
{
delete instance;
instance = nullptr;
}
}
private:
static T* instance;
};
template<typename T>
T* Singleton<T>::instance = nullptr;
/// <summary>
/// ファクトリー
/// </summary>
class Factory
: public Singleton<Factory>
{
public:
enum class KIND_OF_SHOP
{
TAKOYAKI,
YAKISOBA,
CHOCOLATE_BANANA,
BABY_CASTELLA,
};
/// <summary>
/// コンストラクタ
/// </summary>
Factory()
{
// 生産ラインを登録
creators[KIND_OF_SHOP::TAKOYAKI] = new Takoyaki();
creators[KIND_OF_SHOP::YAKISOBA] = new Yakisoba();
creators[KIND_OF_SHOP::CHOCOLATE_BANANA] = new ChocolateBanana();
creators[KIND_OF_SHOP::BABY_CASTELLA] = new BabyCastella();
}
/// <summary>
/// デストラクタ
/// </summary>
virtual ~Factory()
{
// 動的配列の解放
creators.clear();
}
inline FestivalShop* Create(KIND_OF_SHOP key)
{
return creators[key]->Create();
}
private:
std::map<KIND_OF_SHOP, Creator*> creators;
};
int main(void)
{
// FestivalShopのポインタをアップキャストして実体を作成
std::vector<FestivalShop*> festivalShops =
{
Factory::GetInstance()->Create(Factory::KIND_OF_SHOP::TAKOYAKI),
Factory::GetInstance()->Create(Factory::KIND_OF_SHOP::YAKISOBA),
Factory::GetInstance()->Create(Factory::KIND_OF_SHOP::CHOCOLATE_BANANA),
Factory::GetInstance()->Create(Factory::KIND_OF_SHOP::BABY_CASTELLA),
};
// 出力
for (auto festivalShop : festivalShops)
{
std::cout << festivalShop->GetName() << std::endl;
}
// 破棄
festivalShops.clear();
Factory::DeleteInstance();
return 0;
}
C#
FactoryMethod.cs
using System;
using System.Collections.Generic;
/// <summary>
/// お祭りの屋台の抽象クラス
/// </summary>
public class FestivalShop
{
private string name;
/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="_name">店の名前</param>
public FestivalShop(string _name)
{
name = _name;
}
/// <summary>
/// 名前を取得する
/// </summary>
public string GetName { get { return name; } }
}
/// <summary>
/// 作成の抽象クラス
/// </summary>
public abstract class Creator
{
public abstract FestivalShop Create();
}
/// <summary>
/// たこ焼き
/// </summary>
public class Takoyaki : Creator
{
public override FestivalShop Create()
{
return new FestivalShop("たこ焼き");
}
}
/// <summary>
/// 焼きそば
/// </summary>
public class Yakisoba : Creator
{
public override FestivalShop Create()
{
return new FestivalShop("焼きそば");
}
}
/// <summary>
/// チョコバナナ
/// </summary>
public class ChocolateBanana : Creator
{
public override FestivalShop Create()
{
return new FestivalShop("チョコバナナ");
}
}
/// <summary>
/// ベビーカステラ
/// </summary>
public class BabyCastella : Creator
{
public override FestivalShop Create()
{
return new FestivalShop("ベビーカステラ");
}
}
/// <summary>
/// シングルトン
///
/// ジェネリックで汎用性強化
/// where T : new()はインスタンス化の保証
/// </summary>
public class Singleton<T> where T : new()
{
private static T instance;
/// <summary>
/// デフォルトコンストラクタ
///
/// private化で複製禁止
/// </summary>
public Singleton() { }
/// <summary>
/// インスタンスを取得する
/// </summary>
public static T GetInstance
{
get
{
// 初回のみ動的確保
return instance ??= new T();
}
}
}
/// <summary>
/// ファクトリー
/// </summary>
public class Factory : Singleton<Factory>
{
public enum KIND_OF_SHOP
{
TAKOYAKI,
YAKISOBA,
CHOCOLATE_BANANA,
BABY_CASTELLA,
};
private Dictionary<KIND_OF_SHOP, Creator> creators = new Dictionary<KIND_OF_SHOP, Creator>();
/// <summary>
/// コンストラクタ
/// </summary>
public Factory()
{
// 生産ラインを登録
creators[KIND_OF_SHOP.TAKOYAKI] = new Takoyaki();
creators[KIND_OF_SHOP.YAKISOBA] = new Yakisoba();
creators[KIND_OF_SHOP.CHOCOLATE_BANANA] = new ChocolateBanana();
creators[KIND_OF_SHOP.BABY_CASTELLA] = new BabyCastella();
}
public FestivalShop Create(KIND_OF_SHOP key)
{
return creators[key].Create();
}
};
class Program
{
static void Main()
{
List<FestivalShop> festivalShops = new List<FestivalShop>
{
Factory.GetInstance.Create(Factory.KIND_OF_SHOP.TAKOYAKI),
Factory.GetInstance.Create(Factory.KIND_OF_SHOP.YAKISOBA),
Factory.GetInstance.Create(Factory.KIND_OF_SHOP.CHOCOLATE_BANANA),
Factory.GetInstance.Create(Factory.KIND_OF_SHOP.BABY_CASTELLA),
};
foreach (FestivalShop festivalShop in festivalShops)
{
// 出力
Console.WriteLine(festivalShop.GetName);
}
}
}