工厂模式,其实就是C++中的类的继承,只不过用C语言中的函数指针来实现了。
假设现在的需求是公司生产一系列产品,包括椅子,床等,要求先生产产品,然后将生产的产品销售出去。将来可能要增加新的产品,不希望修改现有的核心代码流程,满足开闭原则。
#include#include #include typedef struct PRO_STR { void (*produce)(struct PRO_STR *pthis); void (*sell)(struct PRO_STR **pthis); } PRO_STR, *pPRO_STR; // 实现两个接口 void produceProduct(PRO_STR *pthis) { if (pthis == NULL) return; pthis->produce(pthis); } void sellProduct(PRO_STR **pthis) { if (pthis == NULL || *pthis == NULL) return; (*pthis)->sell(pthis); free(*pthis); *pthis = NULL; } pPRO_STR createChair(); pPRO_STR createBed(); // 工厂创建接口 pPRO_STR factoryCreate(char *strName) { if (0 == strcasecmp("CHAIR", strName)) { return createChair(); } if (0 == strcasecmp("BED", strName)) { return createBed(); } } // 子类接口实现 void produceChair(PRO_STR *pthis) { printf("produce a chairn"); } void sellChair(PRO_STR **pthis) { printf("sell a chairn"); } pPRO_STR createChair() { pPRO_STR pthis = (pPRO_STR)malloc(sizeof(PRO_STR)); if (pthis == NULL) return NULL; pthis->produce = produceChair; pthis->sell = sellChair; return pthis; } void produceBed(PRO_STR *pthis) { printf("produce a bedn"); } void sellBed(PRO_STR **pthis) { printf("sell a bedn"); } pPRO_STR createBed() { pPRO_STR pthis = (pPRO_STR)malloc(sizeof(PRO_STR)); if (pthis == NULL) return NULL; pthis->produce = produceBed; pthis->sell = sellBed; return pthis; } int main() { pPRO_STR chair = factoryCreate("CHAIR"); produceProduct(chair); sellProduct(&chair); pPRO_STR bed = factoryCreate("BED"); produceProduct(bed); sellProduct(&bed); return 0; }
新的需求,每个产品有自己的属性。这时需要对外提供每个产品类别的属性结构体。
#include#include #include typedef struct PRO_STR { void (*produce)(struct PRO_STR *pthis); void (*sell)(struct PRO_STR **pthis); void (*print)(struct PRO_STR *pthis); void *attr; } PRO_STR, *pPRO_STR; // 实现两个接口 void produceProduct(PRO_STR *pthis) { if (pthis == NULL) return; pthis->produce(pthis); } void sellProduct(PRO_STR **pthis) { if (pthis == NULL || *pthis == NULL) return; (*pthis)->sell(pthis); free(*pthis); *pthis = NULL; } void printProduct(PRO_STR *pthis) { if (pthis == NULL) return; pthis->print(pthis); } pPRO_STR createChair(void *attr); pPRO_STR createBed(void *attr); // 工厂创建接口 pPRO_STR factoryCreate(char *strName, void *attr) { if (0 == strcasecmp("CHAIR", strName)) { return createChair(attr); } if (0 == strcasecmp("BED", strName)) { return createBed(attr); } } // 子类接口实现 typedef struct CHAIR { int heavyAbility; int legs; } CHAIR; void produceChair(PRO_STR *pthis) { printf("produce a chairn"); } void sellChair(PRO_STR **pthis) { printf("sell a chairn"); } void printChair(PRO_STR *pthis) { if (NULL == pthis) return; CHAIR *pChair = (CHAIR *)(pthis->attr); printf("heavy %d legs %d n", pChair->heavyAbility, pChair->legs); } pPRO_STR createChair(void *attr) { pPRO_STR pthis = (pPRO_STR)malloc(sizeof(PRO_STR)); if (pthis == NULL) return NULL; pthis->attr = (CHAIR *)malloc(sizeof(CHAIR)); if (NULL == pthis->attr) return NULL; pthis->produce = produceChair; pthis->sell = sellChair; pthis->print = printChair; memcpy(pthis->attr, attr, sizeof(CHAIR)); return pthis; } typedef struct BED { int big; int height; int lenth; } BED; void produceBed(PRO_STR *pthis) { printf("produce a bedn"); } void sellBed(PRO_STR **pthis) { printf("sell a bedn"); } void printBed(PRO_STR *pthis) { if (NULL == pthis) return; BED *pBed = (BED *)(pthis->attr); printf("big %d height %d length %d n", pBed->big, pBed->height, pBed->lenth); } pPRO_STR createBed(void *attr) { pPRO_STR pthis = (pPRO_STR)malloc(sizeof(PRO_STR)); if (pthis == NULL) return NULL; pthis->attr = (BED *)malloc(sizeof(BED)); if (NULL == pthis->attr) return NULL; pthis->produce = produceBed; pthis->sell = sellBed; pthis->print = printBed; memcpy(pthis->attr, attr, sizeof(BED)); return pthis; } int main() { CHAIR chairAttr = {100,4}; pPRO_STR chair = factoryCreate("CHAIR", &chairAttr); produceProduct(chair); printProduct(chair); sellProduct(&chair); BED bedAttr = {10, 10, 7}; pPRO_STR bed = factoryCreate("BED", &bedAttr); produceProduct(bed); printProduct(bed); sellProduct(&bed); return 0; }
编译执行
parallels@ubuntu-linux-20-04-desktop:~/leecode2/marco$ ./a.out produce a chair heavy 100 legs 4 sell a chair produce a bed big 10 height 10 length 7 sell a bed



