1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【C++】Factory(デザインパターン)

Last updated at Posted at 2025-01-29

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);
        }
    }
}
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?