初识设计模式之工厂模式
什么是工厂模式?
工厂模式是最经常被使用的设计模式之一。
根据不同需求,通过使用一个公共接口指向所需要创建的新对象,且创建逻辑不会暴露给客户端。
使用该模式的好处是,可以在不修改原有代码的基础上加入新的产品,满足软件设计的开闭原则。
优点
- 使用者只需要知道对象ID就可以创建新对象。
- 代码扩展性强,增加新产品时,只需要在库中添加类即可,不需要改变用户代码。
- 代码解耦性强。
缺点
- 产品增多时,对应的类将会变多,增加了系统的复杂度。
- 增加了系统的抽象性,使之不好理解。
实现原理
类比场景
小明想通过绘图笔画个圆形。
在使用之前,需要创建个画图箱,具体步骤如下:
1、创建公共画笔(创建接口结构体)。
2、赋予画图功能(在接口中添加功能函数)。
3、要实现公共画笔可根据画图需求继承圆形笔、矩形笔、方形笔其中一个的功能(根据对象ID实例化对象,并调用对象函数)。
4、分别创建圆形笔、矩形笔、方形笔(创建实现接口的实体类)。
完成以上步骤后,画图笔先是根据画圆形的需求,创建公共画笔并继承圆形笔的功能,然后绘制圆形。
代码实现
1、创建Shape接口并实现
//shape.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Shape
{
char type[128];
void (*draw)(struct Shape *c_this);
}Shape;
void ShapeDraw(Shape *c_this);
Shape* ShapeFactoryCreateShape(char *type);
Shape* CircleCreate(void);
Shape* RectangleCreate(void);
Shape* SquareCreate(void);
2、创建并实现工厂类
//drawshape.c
#include "shape.h"
void ShapeDraw(Shape *c_this)
{
if(c_this!=NULL)
c_this->draw(c_this);
}
Shape* ShapeFactoryCreateShape(char *type)
{
if(type == NULL)
return NULL;
if (strcmp("circle", type)==0)
return CircleCreate();
else if (strcmp("rectangle", type)==0)
return RectangleCreate();
else if (strcmp("square", type)==0)
return SquareCreate();
else
return NULL;
}
3、创建实现接口的实体类
//shapefactory.c
#include "shape.h"
//1.Circle类
static void CircleDraw(Shape *c_this)
{
printf("Circle draw\n");
}
Shape *CircleCreate(void)
{
Shape *c_this = (Shape *)malloc(sizeof(Shape));
if(c_this==NULL)
return NULL;
memset(c_this, 0, sizeof(Shape));
c_this->draw = CircleDraw;
return c_this;
}
//2.Rectangle类
static void RectangleDraw(Shape *c_this)
{
printf("Rectangle draw\n");
}
Shape *RectangleCreate(void)
{
Shape *c_this = (Shape *)malloc(sizeof(Shape));
if(c_this == NULL)
return NULL;
memset(c_this, 0, sizeof(Shape));
c_this->draw = RectangleDraw;
return c_this;
}
//3.Square类
static void SquareDraw(Shape *c_this)
{
printf("Square draw\n");
}
Shape *SquareCreate(void)
{
Shape *c_this = (Shape *)malloc(sizeof(Shape));
if(c_this == NULL)
return NULL;
memset(c_this, 0, sizeof(Shape));
c_this->draw = SquareDraw;
return c_this;
}
4、FactoryPatternDemo类使用ShapeFactory来获取Shape对象
//factorypatterndemo.c
#include "shape.h"
void main(void)
{
//获取 Circle 的对象,并调用它的 draw 方法
Shape* circle_shape = ShapeFactoryCreateShape("circle");
ShapeDraw(circle_shape);
free(circle_shape);
//获取 Rectangle 的对象,并调用它的 draw 方法
Shape* rectangle_shape = ShapeFactoryCreateShape("rectangle");
ShapeDraw(rectangle_shape);
free(rectangle_shape);
//获取 Square 的对象,并调用它的 draw 方法
Shape* square_shape = ShapeFactoryCreateShape("square");
ShapeDraw(square_shape);
free(square_shape);
}
Makefile
MainPro : shapefactory.o drawshape.o shape.h
gcc factorypatterndemo.c shapefactory.o drawshape.o -o MainPro
shapefactory.o : shapefactory.c shape.h
gcc -c shapefactory.c -o shapefactory.o
drawshape.o : drawshape.c shape.h
gcc -c drawshape.c -o drawshape.o
.PHONY:clean
clean :
rm -rf *.o
运行
root@instance-3xw0fccv:~/DesignMode/factory# make
gcc -c shapefactory.c -o shapefactory.o
gcc -c drawshape.c -o drawshape.o
gcc factorypatterndemo.c shapefactory.o drawshape.o -o MainPro
root@instance-3xw0fccv:~/DesignMode/factory# ./MainPro
Circle draw
Rectangle draw
Square draw