C语言工厂模式

前言

​ 工厂模式是在软件设计中常常使用一种设计模式。

​ 在使用工厂模式进行软件开发,在创建对象的过程中,不会对客户端暴露具体的逻辑实现,而是使用一个共有的接口来指向创建的对象。 通过这样的方式进行软件开发好处是,可以在不修改原本的代码的基础上加入新的产品,满足软件设计的开闭原则。

工厂模式的优点

  • 使用者在创建对象时,只需要知道该对象的名称即可。
  • 代码的扩展性强,如果需要增加一个新的产品,只需要增加一个实现即可。
  • 将代码的具体的实现和抽象接口分离。接口一致对外,实现可以根据需求的不同实现不同,实现层与层之间的解耦。

工厂模式的缺点

  • 产品增加时,对应的实现会变多,系统的复杂度会增加。
  • 实现和接口分离,可能使得代码变得相对不易理解。

应用场景

  • 一个系统要独立于它的产品的创建、组合和表示,即要将具体产品类分离出来。
  • 一个系统要有多个产品系列中的一个来配置,即系统有多个产品系列,但只使用一个产品系列。
  • 提供一个产品类库,但只想显示它们的接口而不是实现。

案例

​ 为了说明工厂模式,我这里举一个比较简单的例子。假设有shape这个接口,然后根据业务的不同有可能需要circle的实现方式也有可能时square的实现方式,当然也有可能时其他的具体形状,但是抽象出现就是一个形状和将这形状绘制的函数draw即可。

​ 创建Shape接口并实现

typedef struct Shape Shape;

struct Shape 
{
  void *priv_;
  void (*Draw)(struct Shape *c_this);
  void (*Destroy)(struct Shape *c_this);
};

void ShapeDraw(Shape *c_this);
void ShapeDestory(Shape **c_this);

void ShapeDraw(Shape *c_this) 
{
  assert(c_this != NULL);
  if(c_this->Draw != NULL) 
  {
    c_this->Draw(c_this);
  }
}

void ShapeDestory(Shape **c_this) 
{
  if(c_this == NULL || *c_this == NULL) 
  {
    return;
  }
  Shape *shape = *c_this;
  if(shape->Destroy != NULL) 
  {
    shape->Destroy(shape);
  }
  free(*c_this);
  *c_this = NULL;
}

创建并实现工厂类ShapeFactory

#include "shape.h"
Shape* ShapeFactoryCreateShape(const char *shape_type);

extern struct Shape* CircleCreate(void);
extern struct Shape* RectangleCreate(void);
extern struct Shape* SquareCreate(void);

Shape* ShapeFactoryCreateShape(const char *shape_type) 
{
  if(shape_type == NULL) 
  {
    return NULL;
  }
  if (0 == strcasecmp("CIRCLE", shape_type)) 
  {
    return CircleCreate();
  } 
  else if (0 == strcasecmp("RECTANGLE", shape_type)) 
  {
    return RectangleCreate();
  } 
  else if (0 == strcasecmp("SQUARE", shape_type)) 
  {
    return SquareCreate();
  }
  else 
  {
 	 return NULL;
  }
}

  • 创建实现接口的实体类
//1.Circle类
static void CircleDraw(struct Shape *c_this) 
{
  printf("Circle draw method.\n");
}

struct Shape *CircleCreate(void) 
{
  struct Shape *c_this = (struct Shape *)malloc(sizeof(struct Shape));

  if(c_this == NULL) {
    return NULL;;
  }
  memset(c_this, 0, sizeof(struct Shape));
  c_this->Draw = CircleDraw;
  return c_this;
}
//2.Rectangle类
static void RectangleDraw(struct Shape *c_this) 
{
  printf("Rectangle draw method.\n");
}

struct Shape *RectangleCreate(void) 
{
  struct Shape *c_this = (struct Shape *)malloc(sizeof(struct Shape));

  if(c_this == NULL)
  {
    return NULL;;
  }
  memset(c_this, 0, sizeof(struct Shape));
  c_this->Draw = RectangleDraw;
  return c_this;
}
//3.Square类
static void SquareDraw(struct Shape *c_this)
{
  printf("Square draw method.\n");
}

struct Shape *SquareCreate(void) 
{
  struct Shape *c_this = (struct Shape *)malloc(sizeof(struct Shape));

  if(c_this == NULL)
  {
    return NULL;;
  }
  memset(c_this, 0, sizeof(struct Shape));
  c_this->Draw = SquareDraw;
  return c_this;
}

  • FactoryPatternDemo类使用ShapeFactory来获取Shape对象
void main(void)

 {
  //获取 Circle 的对象,并调用它的 draw 方法
  Shape* circle_shape = ShapeFactoryCreateShape("CIRCLE");
  ShapeDraw(circle_shape);
  ShapeDestory(&circle_shape);

  //获取 Rectangle 的对象,并调用它的 draw 方法
  Shape* rectangle_shape = ShapeFactoryCreateShape("RECTANGLE");
  ShapeDraw(rectangle_shape);
  ShapeDestory(&rectangle_shape);

  //获取 Square 的对象,并调用它的 draw 方法
  Shape* square_shape = ShapeFactoryCreateShape("SQUARE");
  ShapeDraw(square_shape);
  ShapeDestory(&square_shape);
  system("pause");

}
posted @ 2023-07-10 22:29  Kroner  阅读(74)  评论(0编辑  收藏  举报