案例分析:设计模式与代码的结构特性
本文介绍设计模式的最常用的模式——工厂模式
以C语言为例讨论工厂模式
根本上说,工厂模式的目的就根据不同的要求输出不同的产品。比如说吧,有一个印刷书本的工厂,它能印刷语文书,也能印刷数学书。如果用代码设计,应该怎么做呢?
1 typedef enum _Book_type
2 {
3 Chinese = 0,
4 Math,
5 }Book_type;
6 typedef struct _Book
7 {
8 Book_type type;
9 void (*print_book)(void);
10 }Book;
用枚举类型Book_type定义书本类型,想要增加书本的类型就在Book_type里添加相应的书本类型。
下面来实现既能印刷语文书,也能印刷数学书
1 void print_Chinese_book(void)
2 {
3 printf("printing Chinese book!\n");
4 return;
5 }
6
7 void print_math_book(void)
8 {
9 printf("printing math book!\n");
10 return;
11 }
这是用两个函数分别实现印刷语文书和印刷数学书
对于一个工厂来说,要印刷什么类型的书就看输入的参数是什么
1 Book* print_new_book(Book_type type)
2 {
3 Book* pBook = (Book*)malloc(sizeof(Book));
4 if(pBook == NULL)
5 {
6 printf("malloc failed!\n");
7 return NULL;
8 }
9
10 memset(pBook, 0, sizeof(Book));
11 switch(type)
12 {
13 case Chinese:
14 pBook->type = Chinese;
15 pBook->print_book = print_Chinese_book;
16 break;
17 case Math:
18 pBook->type = Math;
19 pBook->print_book = print_math_book;
20 break;
21 default:
22 printf("invalid book type\n");
23 free(pBook);
24 return NULL;
25 }
26
27 return pBook;
28 }
print_new_book函数就是工厂的功能,按照输入的参数印刷不同类型的书。如果要增加新类型的书,只要实现新类型书的印刷函数,和在Book_type添加新书本的类型,然后在print_new_book的switch语句中添加相应的赋值语句就可以了,这种方式对于扩充和删除部分工厂功能,不用大改工厂功能,很方便,易于扩展。
下面来举例说明工厂模式的使用
int main()
{
Book *pBook = NULL;
pBook = print_new_book(Chinese);
if(pBook == NULL)
{
return -1;
}
pBook->print_book();
free(pBook);
pBook = NULL;
pBook = print_new_book(Math);
if(pBook == NULL)
{
return -1;
}
pBook->print_book();
free(pBook);
pBook = NULL;
return 0;
}

这就实现了根据工厂输入参数的不同,实现了印刷了不同的书本。
这种模式对于功能增加或删除,都提供了良好的便利性,不用大改代码结构,就能轻松实现扩充和修改,即具有易扩展性。
代码中的Book结构体重的print_book函数指针实现了多态,print_book是一个函数指针,对print_book赋不同的值就能实现不同的函数功能,实现了多态机制。
整个代码中Book结构体就是一个抽象模块,只提供接口,不实现具体实现,类似于C++的接口。
每个模块中的都是高内聚的,而模块间都是低耦合的,这正是良好的设计。
下面提供完整代码,只要用gcc编译一下即可使用。
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef enum _Book_type { Chinese = 0, Math, }Book_type; typedef struct _Book { Book_type type; void (*print_book)(void); }Book; void print_Chinese_book(void) { printf("printing Chinese book!\n"); return; } void print_math_book(void) { printf("printing math book!\n"); return; } Book* print_new_book(Book_type type) { Book* pBook = (Book*)malloc(sizeof(Book)); if(pBook == NULL) { printf("malloc failed!\n"); return NULL; } memset(pBook, 0, sizeof(Book)); switch(type) { case Chinese: pBook->type = Chinese; pBook->print_book = print_Chinese_book; break; case Math: pBook->type = Math; pBook->print_book = print_math_book; break; default: printf("invalid book type\n"); free(pBook); return NULL; } return pBook; } int main() { Book *pBook = NULL; pBook = print_new_book(Chinese); if(pBook == NULL) { return -1; } pBook->print_book(); free(pBook); pBook = NULL; pBook = print_new_book(Math); if(pBook == NULL) { return -1; } pBook->print_book(); free(pBook); pBook = NULL; return 0; }

浙公网安备 33010602011771号