デザインモデルの美しさ--シンプルな工場モデル


文書ディレクトリ
  • 1. 問題解決
  • 2. 適用シーン
  • 3. 実装
  • C++実装:
  • C言語実装
  • 4. 欠点
  • 1.問題解決
    例を次に示します.
    私达は1つの服を売る机能を実现して、服の种类はたくさんあります:帽子、ズボン、Tシャツ..1つの服を売るたびに、私たちはインスタンス化を行い、new/malloc申請空間を通じて、次の2つの問題があります.
  • new/mallocの後、異常処理コードの山に従う必要があります.服の種類が多くなると、私たちのコードは異常に肥大化します.
  • 新しいウェイターが店に来たとき、彼は服を売ろうとしたが、服を買う流れが分からなかった(どの倉庫から取り出すのか?どんな加工をするのか...)

  • この時、簡単な工場でこのような問題を解決することができます.
  • 単純ファクトリモードはnew/mallocおよびいくつかの衣類の加工操作をカプセル化し、外部に露出することなく、オブジェクトの作成と使用を完全に分離する.
  • 新しく来た同僚は服を売る具体的な流れを知る必要はなく、生産関数を直接呼び出して服の対象を手に入れ、直接売ることができます.

  • 要するに、オブジェクトを構築するクラスは一つの製品を加工するようなもので、製品を使用する人は私の製品がどのように加工されているかを知る必要はありません.工場を使用して製品を生成し、直接使用すればいいだけです.ソフトウェア開発の観点から,ファクトリモードはモジュール間の結合度を低減した.
    2.シーンの適用
  • 大量のインスタンス化オブジェクトを必要とするクラスに対する設計
  • 論理処理は単純な単一シーン
  • である.
    3.実現
    異なる製品の作成を担当する工場クラスを維持し、製品の作成内容は工場が自分で決定します.
    C++実装:
    実現機能:単純な工場モデルは異なる種類の服を作成し、直接販売し、服の作成破壊論理に関心を持つ必要はありません.
    #include 
    
    using namespace std;
    
    /*            */
    enum ClothType{hat,paths};
    
    class Cloth{
        public:
        virtual void createCloth(void) = 0;
        virtual ~Cloth(){} //      ,                   
    };
    
    /*   */
    class Hat: public Cloth{
        public:
        Hat(){
            cout << "Hat::hat()" << endl;
        }
        
        virtual void createCloth(void) {
            cout << "Hat::createHat()" << endl;
        }
        
        ~Hat(){
            cout << "Hat::delete()" << endl;
        }
    };
    
    /*   */
    class Paths: public Cloth{
        public:
        Paths(){
            cout << "Paths::paths()" << endl;
        }
        
        virtual void createCloth(void) {
            cout << "Paths::createPaths()" << endl;
        }
        
        ~Paths(){
            cout << "Paths::delete()" << endl;
        }
    };
    
    /*   ,          */
    class clothFactory { 
        public:
        Cloth * createSpecificCloth(ClothType type) {
            switch(type){
                case hat:
                    return (new Hat());
                case paths:
                    return (new Paths());
                default:
                    return NULL;
            }
        }
    };
    
    int main()
    {
        clothFactory cloFac;
        Cloth *clothA = cloFac.createSpecificCloth(hat);//    
        Cloth *clothB = cloFac.createSpecificCloth(paths);//    
        
        clothA -> createCloth();
        clothB -> createCloth();
        
        delete clothA;
        delete clothB;
        return 0;
    }
    

    コンパイル実行出力は次のとおりです.
    Hat::hat()
    Hat::createHat()
    Paths::paths()
    Paths::createPaths()
    Hat::delete()
    Paths::delete()
    

    C言語実現
    実装機能:C++実装の機能と同様に,単純な工場パッケージによる衣類の作成ロジックにより,工場により指定された衣類オブジェクトを作成し,直接使用する.
    インプリメンテーションロジックインプリメンテーションロジック:関数ポインタretval.h仕様戻り値、およびfreeロジック
    #include 
    #include 
    
    #define return_if_fail(p)\
    	if(!(p)){\
    	printf("%s:%d Warning:"#p"Failed
    ",__func__,__LINE__);\ return;}
    #define return_val_if_fail(p, ret)\ if(!(p)){\ printf("%s:%d Warning:"#p"Failed
    ",__func__,__LINE__);\ return (ret);}
    #define SAFE_FREE(p) if(p != NULL){free(p); p = NULL;}
    cloth.h衣類メーカー
    #ifndef __CLOTH_H__
    #define __CLOTH_H__
    
    #include 
    #include 
    #include "retval.h"
    
    struct _Cloth;
    typedef struct _Cloth Cloth;
    
    typedef Cloth* (*createClothFunc)();
    typedef void (*deleteClothFunc)(Cloth* thiz);
    
    struct _Cloth 
    {
    	createClothFunc createCloth;
    	deleteClothFunc deleteCloth;
    };
    
    static inline Cloth* oper_createCloth(Cloth *thiz) {
    	return_val_if_fail(thiz != NULL,NULL);
    	
    	return thiz -> createCloth();
    } 
    
    static inline void oper_deleteCloth(Cloth *thiz) {
    	if (NULL != thiz && NULL != thiz -> deleteCloth ) {
    		thiz -> deleteCloth(thiz);
    	}
    	
    	return;
    }
    
    #endif
    
    hat.h
    #include 
    #include "cloth.h"
    
    typedef struct _Hat Hat;
    
    typedef Cloth* (*createHatClothFunc)();
    typedef void (*deleteHatClothFunc)(Hat* thiz);
    
    struct _Hat {
    	createHatClothFunc createHatCloth;//    
    	deleteHatClothFunc deleteHatCloth;//    
    };
    
    Hat * oper_hat_create(void);//      
    
    hat.c
    #include 
    #include "retval.h"
    #include "hat.h"
    
    static Cloth* oper_createHatCloth()
    {
    	Cloth *cloth = malloc(sizeof(cloth));
    	if(cloth != NULL) { 
    		printf("create hat cloth
    "
    ); } return cloth; } static void oper_deleteHatCloth(Hat* thiz) { printf("delete hat cloth
    "
    ); if(thiz != NULL) { SAFE_FREE(thiz); } return; } Hat * oper_hat_create(void) { Hat *thiz = (Hat *)malloc(sizeof(Hat)); if(thiz != NULL) { thiz -> createHatCloth = oper_createHatCloth; thiz -> deleteHatCloth = oper_deleteHatCloth; } return thiz; }
    path.h
    #include 
    #include "cloth.h"
    
    typedef struct _Path Path;
    
    typedef Cloth* (*createPathClothFunc)();
    typedef void (*deletePathClothFunc)(Path* thiz);
    
    struct _Path {
    	createPathClothFunc createPathCloth;//    
    	deletePathClothFunc deletePathCloth;//    
    };
    
    /*      */
    Path * oper_path_create(void); 
    
    path.c
    /*   ,           */
    #include 
    #include "retval.h"
    #include "path.h"
    
    static Cloth* oper_createHatCloth() //  
    {
    	Cloth *cloth = malloc(sizeof(cloth));
    	if(cloth != NULL) { 
    		printf("create paths cloth
    "
    ); } return cloth; } static void oper_deletePathCloth(Hat* thiz) {// printf("delete paths cloth
    "
    ); if(thiz != NULL) { SAFE_FREE(thiz); } return; } Hat * oper_path_create(void) { Path *thiz = (Path *)malloc(sizeof(Path)); if(thiz != NULL) { thiz -> createPathCloth = oper_createHatCloth; thiz -> deletePathCloth = oper_deletePathCloth; } return thiz; }
    factory.c
    #include 
    #include 
    #include 
    
    #include "hat.h"
    #include "paths.h"
    #include "cloth.h"
    #include "retval.h"
    #include "factory.h"
    
    /*          clothName              */
    Cloth* factory_create_op(char clothName) {
    	Cloth *cloth = (Cloth*) malloc(sizeof(Cloth));
    	
    	if(NULL != cloth) {
    		switch (clothName) {
    			case 'h':
    				cloth = (Cloth*)oper_hat_create();
    				break;
    			case 'p':
    				cloth = (Cloth*)oper_path_create();
    				break;
    			default:;
    		}
    	}	
    	
    	return cloth;
    }
    
    /*      */
    void facory_delete_op(Factory *thiz) {
    	assert(thiz != NULL);
    	
    	SAFE_FREE(thiz);
    }
    
    Factory *FactoryCreate(void) {
    	Factory *thiz = malloc(sizeof(Factory));
    	if(thiz != NULL){
    		thiz -> create_op = factory_create_op;
    		thiz -> delete_op = facory_delete_op;
    	}
    	
    	return thiz;
    }
    
    factory.h
    #ifndef __FACTORY_H__
    #define __FACTORY_H__
    
    #include 
    #include "cloth.h"
    
    
    typedef struct  _Factory Factory;
    
    typedef Cloth* (*factoryCreateFunc)();
    typedef void (*factoryDeleteFunc)(Factory *thiz);
    
    struct _Factory{
    	factoryCreateFunc create_op;
    	factoryDeleteFunc delete_op;
    };
    
    Factory *FactoryCreate(void);
    Cloth* factory_create_op(char clothName);
    void facory_delete_op(Factory *thiz);
    
    #endif
    
    main.c
    #include 
    #include 
    
    #include "factory.h"
    #include "cloth.h"
    
    int main(int argc, char *argv[]) {
    	Factory *factory = FactoryCreate();
    	
    	Cloth *clothA = factory_create_op('h');
    	oper_createCloth(clothA);
    	oper_deleteCloth(clothA);
    	
    	Cloth *clothB = factory_create_op('p');
    	oper_createCloth(clothB);
    	oper_deleteCloth(clothB);	
    	
    	factory->delete_op(factory);
    	return 0;
    }
    

    コンパイル出力は次のとおりです.
    create hat cloth
    delete hat cloth
    create paths cloth
    delete paths cloth
    

    4.短所
    以上の実現により,商品を増やす際に工場を修正する必要があり,同時に服以外の種類の商品を増やすことができないことが明らかになった.
  • は開閉原則に違反しています.単純工場モデルは製品を拡張する際に工場を修正する必要があります.開閉の原則は拡張開発、修正閉鎖にこだわっている.
  • は新しい種類の商品を拡張することをサポートしていません.