设计模式 之美 -- 简单工厂模式
生活随笔
收集整理的這篇文章主要介紹了
设计模式 之美 -- 简单工厂模式
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 1. 解決問題
- 2. 應用場景
- 3. 實現
- C++實現:
- C語言實現
- 4. 缺點
1. 解決問題
舉例如下:
我們實現一個賣衣服的功能,衣服的種類有很多:帽子,褲子,T恤。。。 每賣一種衣服,我們都要進行一次實例化,通過new/malloc申請空間,會有如下兩種問題:
- new /malloc之后往往需要跟隨一堆異常處理代碼,當衣服種類越來越多,我們的代碼會顯得異常臃腫。
- 當新的服務員來到商店,他想要賣衣服,但是不知道買衣服的流程(從哪個倉庫取出來?進行什么樣的加工。。。。)
此時,簡單工廠就能解決這樣的問題
- 簡單工廠模式將 new/malloc以及一些衣服的加工操作 進行封裝,并不會暴露給外界,將對象的創建和使用完全分離。
- 新來的同事不需要知道 賣衣服的具體流程,直接調用生產函數拿到衣服的對象,直接賣就可以。
總之,建立對象的類就像加工一個產品,使用產品的人不需要知道我的產品怎么加工的,只需要使用工廠生成產品,直接用即可。從軟件開發角度來說,工廠模式降低了模塊之間的耦合度。
2. 應用場景
- 針對需要大量實例化對象的類 的設計
- 邏輯處理是簡單單一的場景
3. 實現
維護一個工廠類,專門負責創建不同的產品,創建產品的內容由工廠自己決定。
C++實現:
實現功能:簡單工廠模式 創建不同種類的衣服,直接售賣,而不需要關心衣服的創建 銷毀邏輯。
#include <iostream>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 <stdio.h>
#include <stdlib.h>#define return_if_fail(p)\if(!(p)){\printf("%s:%d Warning:"#p"Failed\n",__func__,__LINE__);\return;}#define return_val_if_fail(p, ret)\if(!(p)){\printf("%s:%d Warning:"#p"Failed\n",__func__,__LINE__);\return (ret);}#define SAFE_FREE(p) if(p != NULL){free(p); p = NULL;}
cloth.h 衣服廠商
#ifndef __CLOTH_H__
#define __CLOTH_H__#include <stdio.h>
#include <stdlib.h>
#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 <stdio.h>
#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 <stdio.h>
#include "retval.h"
#include "hat.h"static Cloth* oper_createHatCloth()
{Cloth *cloth = malloc(sizeof(cloth));if(cloth != NULL) { printf("create hat cloth\n");}return cloth;
}static void oper_deleteHatCloth(Hat* thiz) {printf("delete hat cloth\n"); 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 <stdio.h>
#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 <stdio.h>
#include "retval.h"
#include "path.h"static Cloth* oper_createHatCloth() //創建
{Cloth *cloth = malloc(sizeof(cloth));if(cloth != NULL) { printf("create paths cloth\n");}return cloth;
}static void oper_deletePathCloth(Hat* thiz) {//刪除printf("delete paths cloth\n"); 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 <stdio.h>
#include <stdlib.h>
#include <assert.h>#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 <stdio.h>
#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 <stdio.h>
#include <stdlib.h>#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. 缺點
通過以上的實現,我們很明顯的發現當增加商品的時候需要修改工廠,同時無法增加除了衣服之外的其他種類商品。
- 違反了開閉原則:簡單工廠模式在擴展產品的時候需要去修改工廠。開閉原則講究的是對擴展開發,對修改關閉。
- 不支持擴展新種類的商品。
總結
以上是生活随笔為你收集整理的设计模式 之美 -- 简单工厂模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 论文查重多少钱啊?
- 下一篇: 大半年前定的费列罗喜糖,现在商家违约,请