C++ デザインパターン作成 ファクトリパターン仕上げ

1. ファクトリーモデルの分類

        ファクトリ パターンは作成パターンに属し、一般に単純なファクトリ パターン、ファクトリ パターン、および抽象ファクトリ パターンに細分できます。それぞれに異なる特性とアプリケーションシナリオがあります。

2.ファクトリーモデルの詳細

1. 簡易ファクトリーモード

1。概要

        比較的、簡易ファクトリーパターンはカルテット著『デザインパターン---再利用可能なオブジェクト指向ソフトウェアの基礎』には記載されていないため、標準的なデザインパターンではないと考えられます。シナリオがあるので、ここで簡単に紹介します。プログラミングの送受信やプログラミングスキルの一種と捉える人もいます。

2) 簡単な工場出荷時のパターンコード

class Monster
{ public:     Monster(int life, int magic, int Attack):m_life(life),m_magic(magic),m_ Attack(攻撃){}     virtual ~Monster(){} protected:     int m_life;     int m_magic;     int m_攻撃; };







class M_Undead: public Monster
{ public:     M_Undead(int life, int magic, int Attack):Monster(life, magic, Attack)     {         cout << "アンデッドモンスターがこの世に誕生した" << endl;     } ; };





class M_Element: public Monster
{ public:     M_Element(int life, int magic, int Attack):Monster(life, magic, Attack)     {         cout << 「この世界にエレメンタルモンスターが誕生した」<< endl; } ;     } ;





class M_Mechanic: public Monster
{ public:     M_Mechanic(int life, int magic, int Attack):Monster(life, magic, Attack)     {         cout << "機械の怪物がこの世に誕生した" << endl;     } ; }; class CSimpleFactory { public:     Monster* createMonster(eMonsterType eType)     {         Monster* pCreateObj = nullptr;         if (eType == Undead_Type)         {             pCreateObj = new M_Undead(300, 50, 80);         }          else if (eType == Element_Type )         {             pCreateObj = 新しい M_Element(200, 80, 100);         }




















        else if (eType == Mechanic_Type)
        {             pCreateObj = new M_Mechanic(400, 0, 110);         pCreateObjを返し         ます。     } };




int main()
{

    CSimpleFactory simobj;
    モンスター* pM1 = simobj.createMonster(Undead_Type);

    モンスター* pM2 = simobj.createMonster(Element_Type);

    Monster* pM3 = simobj.createMonster(Mechanic_Type);

    pM1を削除します。
    pM2を削除します。
    pM3を削除します。
    
    0を返します。
}

概要: ファクトリークラスを通じてモンスターを作成するということは、モンスターを作成するときに新しいキーワードが使用されなくなり、ファクトリークラスを通じて使用されることを意味します。このように、将来ディストーションの種類が増えても、メインのモンスター作成コードは機能は可能な限り安定します。同時に、main 関数内で new を直接使用してオブジェクトを作成する際に、特定のクラス名を知る必要がなくなり、モンスターを作成するコードと、それぞれが実装するビジネス ロジック コードの分離を実現します。特定のモンスタークラスのオブジェクト。もちろん、このモードには明らかな欠点もあります。新しい種類のモンスターが導入されると、createMonster メンバー関数のソース コードを変更して、新しい種類のモンスターの作成をサポートする if 判定分岐を追加する必要があります。そして閉鎖原則。if ブランチの数がそれほど多くなく、数十または数百ではなく数個のみの場合は、適切に開閉するという原則に違反することが許容されます。

2. ファクトリーモード

1。概要

        ファクトリ パターンは、通常、ファクトリ メソッド パターンも指します。言い換えれば、ファクトリ メソッド パターンは、ファクトリ パターンまたはポリモーフィック ファクトリ パターンと呼ばれます。このパターンは、単純なファクトリ パターンよりも実装が若干難しくなります。モンスターのタイプごとに対応するファクトリ クラスを作成する必要があります。これは、新しいファクトリ クラスを追加することでオブジェクト指向プログラミングの開始と終了の原則に準拠しますが、その代償として、複数の新しいファクトリ クラスを追加する必要があります。

2) コード例

class M_ParFactory
{ public:     virtual Monster* createMonster() = 0;     仮想 ~M_ParFactory(){} };



class M_UndeadFactory : public M_ParFactory
{ public:     virtual Monster* createMonster()     {         return new M_Undead(300, 50, 80);     } };





class M_ElementFactory : public M_ParFactory
{ public:     virtual Monster* createMonster()     {         return new M_Element(200, 80, 100);     } };





class M_MechanicFactory : public M_ParFactory
{ public:     virtual Monster* createMonster()     {         return new M_Mechanic(400, 0, 110);     } };





Monster* Gbl_CreateMonster(M_ParFactory *factoryObj)
{     return FactoryObj->createMonster(); }

int main()
{     M_ParFactory* p_ud_fy = new M_UndeadFactory();     Monster* pM1 = Gbl_CreateMonster(p_ud_fy); //アンデッドモンスターを構築する

    M_ParFactory* p_ele_fy = new M_ElementFactory();
    Monster* pM2 = Gbl_CreateMonster(p_ele_fy); //エレメントモンスターを構築

    M_ParFactory* p_mec_fy = new M_MechanicFactory();
    Monster* pM3 = Gbl_CreateMonster(p_mec_fy); //機械式モンスターを構築する

    //リソースを解放
    delete p_ud_fy;
    delete p_ele_fy;
    delete p_mec_fy;

    pM1を削除します。
    pM2を削除します。
    pM3を削除します。
}

概要: 上記のコードからわかるように、モンスター オブジェクトを作成するとき、特定のモンスター クラスの名前を覚える必要はありませんが、モンスターを作成したファクトリの名前を知っている必要があります。ファクトリ パターンの実装目的は、オブジェクトを作成するためのインターフェイスを定義することですが、どのクラスをインスタンス化するかはサブクラスが決定するため、特定のクラスのサブクラスへのインスタンス化が遅れます。新しいモンスター タイプが出現したときに Gbl_CreateMonster 関数を変更する必要はありません。また、シンプル ファクトリ モードのように新しい if 分岐を追加するために MonsterFactory クラスの createMonster メンバー関数を変更する必要もありません。

3. 抽象的なファクトリーパターン

1。概要

         ビジネスの変更に伴い、ゲーム内の戦闘シーンの数と種類は増え続けており、本来の街での戦闘から、沼地での戦闘、山岳地帯での戦闘など、シーンは多岐にわたります。モンスターは3種類、戦闘シーンは3種類に分かれており、合計9種類のモンスターが出現します。ファクトリ サブクラスが同じルールで複数のモンスター オブジェクトを生成できる場合、作成されるファクトリ サブクラスの数を効果的に減らすことができます。これが抽象ファクトリ パターンの中心的なアイデアです。抽象的な工場パターンは、製品ファミリーに従って製品を生産するというもので、1 つの場所に工場があり、すべての地元製品の生産を担当します。

2) コード例

//沼地のモンスター
class M_Undead_Swamp : public Monster
{ public:     M_Undead_Swamp(int life, int magic, int Attack):Monster(life, magic, Attack)     {         cout << "沼地のアンデッドモンスターがこの世に誕生した" << endl ;     }; };





class M_Element_Swamp : public Monster
{ public:     M_Element_Swamp(int life, int magic, int Attack):Monster(life, magic, Attack)     {         cout << "沼地のエレメンタルモンスターがこの世に誕生した" << endl ;     }; } ;





class M_Mechanic_Swamp : public Monster
{ public:     M_Mechanic_Swamp(int life, int magic, int Attack):Monster(life, magic, Attack)     {         cout << "沼地の機械の怪物がこの世に誕生した" << endl ;     }; } ;





//------------------------------------------------ ----------------------------
//山のモンスター
クラス M_Undead_Mountain : public Monster
{ public:     M_Undead_Mountain(int life, int magic, int Attack):Monster(ライフ、魔法、攻撃)     {         cout << 「この世界に山のアンデッドの怪物が生まれました」 << endl; };     } ;





class M_Element_Mountain : public Monster
{ public:     M_Element_Mountain(int life, int magic, int Attack):Monster(life, magic, Attack)     {         cout << "山属性のモンスターがこの世に誕生した" << endl ;     }; } ;





class M_Mechanic_Mountain : public Monster
{ public:     M_Mechanic_Mountain(int life, int magic, int Attack):Monster(life, magic, Attack)     {         cout << 「山の機械の怪物がこの世に誕生した」<< endl ;     } ; };





//------------------------------------------------ ----------------------------
//タウンモンスター
クラス M_Undead_Town : public Monster
{ public:     M_Undead_Town(int life, int magic , int Attack):Monster(ライフ、魔法、攻撃)     {         cout << 「この世界にアンデッドモンスターの街が誕生しました」<< endl; };     } ;





class M_Element_Town : public Monster
{ public:     M_Element_Town(int life, int magic, int Attack):Monster(life, magic, Attack)     {         cout << "街のエレメンタルモンスターがこの世界に誕生した" << endl ;     }; } ;





class M_Mechanic_Town : public Monster
{ public:     M_Mechanic_Town(int life, int magic, int Attack):Monster(life, magic, Attack)     {         cout << 「町の機械の怪物がこの世界に生まれた」<< endl ;     } ; };





class M_ParFactory
{ public:     virtual Monster* createMonster_Undead() = 0;     仮想モンスター* createMonster_Element() = 0;     仮想モンスター* createMonster_Mechanic() = 0;     仮想 ~M_ParFactory(){} };





//ファクトリのサブクラス:
//------------------------------------------ - ----------------------------------------
//スワンプファクトリー
クラス M_Factory_Swamp : public M_ParFactory
{ public:     virtual Monster* createMonster_Undead()     {         return new M_Undead_Swamp(300, 50, 120);     }




    virtual Monster* createMonster_Element()
    {         return new M_Element_Swamp(200, 80, 110);     }

    virtual Monster* createMonster_Mechanic()
    {         return new M_Mechanic_Swamp(400, 0, 90);     } };


//------------------------------------------------ -------------------------------------
//山地ファクトリー
クラス M_Factory_Mountain : public M_ParFactory
{ public:     virtual Monster* createMonster_Undead()     {         return new M_Undead_Mountain(300, 50, 80);     }




    virtual Monster* createMonster_Element()
    {         return new M_Element_Mountain(200, 80, 100);     }

    virtual Monster* createMonster_Mechanic()
    {         return new M_Mechanic_Mountain(600, 0, 110);     } };


//------------------------------------------------ -------------------------------------
//タウンエリアファクトリー
クラス M_Factory_Town : public M_ParFactory
{ public:     virtual Monster* createMonster_Undead()     {         return new M_Undead_Town(300, 50, 80);     }




    virtual Monster* createMonster_Element()
    {         return new M_Element_Town(200, 80, 100);     }

    virtual Monster* createMonster_Mechanic()
    {         return new M_Mechanic_Town(400, 0, 110);     } };


概要: 抽象ファクトリー パターンは、元のコードを変更するのではなく、新しいコードを追加することによって、ゲームに新しい機能を追加します。製品ファミリーが必要な場合は、ファクトリの親クラスを変更して新しいタイプをサポートする新しい仮想関数を追加する必要があり、各ファクトリは新しいタイプのサポートを追加する必要があります。この場合、オープンとクローズの原則が崩れます。抽象化は適用されません。ファクトリー パターン。抽象ファクトリ パターンにはファクトリ パターンの利点があります。新しい製品ファミリを追加するだけの場合は、オープンとクローズの原則に準拠する新しいサブファクトリ クラスを追加するだけで済みます。これが抽象ファクトリ パターンの利点です。抽象ファクトリーパターンはファクトリーパターンと同様ですが、新たにプロダクト階層構造を追加する場合、抽象化レイヤーのコードを修正する必要があるという欠点があるため、プロダクト階層構造が不安定な場合には避けるべきです。抽象ファクトリ パターンを導入する目的は、特定のクラスを指定せずに、一連の関連オブジェクトまたは相互依存オブジェクトを作成する役割を担うインターフェイスを提供することです。

4. 3つのモードの比較

1) コード実装の複雑さの点では、単純なファクトリ パターンが最も単純で、次にファクトリ メソッド パターン、そして抽象ファクトリ パターンが最も複雑です。単純なファクトリ パターンのコードを開閉の原理に準拠するように変更すると、ファクトリ メソッド パターンになります ファクトリ メソッド パターンのコードを変更すると、工場は複数の特定の製品の生産をサポートし、抽象的な工場のパターン。

2) 必要な工場の数は、単純なファクトリ パターンが最も少なく、ファクトリ メソッド パターンが最も多く、ファクトリ メソッドで必要なファクトリの数を効果的に削減できるのは、抽象ファクトリ パターンです。パターン。

3) 実用的な観点から、プロジェクト内の製品数が少ない場合は、単純なファクトリ モデルの使用を検討しますが、プロジェクトが少し大きい場合、または開閉の原則を満たす場合は、ファクトリ メソッド モデルを使用できます。大規模なプロジェクトの場合、多くのメーカーがあり、各メーカーが一連の製品を生産するときに抽象的な工場パターンを考慮する必要があります。

おすすめ

転載: blog.csdn.net/leiyang2014/article/details/132072318
おすすめ