大话设计模式C语言之抽象工厂

抽象工厂模式

抽象工厂 (AbstractFactory) 模式是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类。

案例代码

抽象产品接口

抽象产品(Abstract Product)为构成系列产品的一组不同但相关的产品声明接口。

抽象button接口 button.h
1
2
3
4
5
6
7
8
9
10
#ifndef BUTTON_H
#define BUTTON_H

typedef struct Button Button;

void button_draw(Button *self);
void button_destroy(Button *self);

#endif

抽象checkbox接口 checkbox.h
1
2
3
4
5
6
7
8
9
10
#ifndef CHECKBOX_H
#define CHECKBOX_H

typedef struct Checkbox Checkbox;

void checkbox_draw(Checkbox *self);
void checkbox_destroy(Checkbox *self);

#endif

具体产品

具体产品(Concrete Product)是抽象产品的多种不同类型实现。 所有变体都必须实现相应的抽象产品。这里只简单给出win产品族的实现

button实现 button_win.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#include <stdlib.h>
#include "button.h"

struct Button {
int dummy;
};

static void win_button_draw(Button *self) {
(void)self;
printf("Draw Windows Button\n");
}

void button_draw(Button *self) {
win_button_draw(self);
}

void button_destroy(Button *self) {
free(self);
}

Button *win_button_create(void) {
return calloc(1, sizeof(Button));
}

checkbox实现 checkbox_win.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
#include <stdlib.h>
#include "checkbox.h"

struct Checkbox {
int checked;
};

static void win_checkbox_draw(Checkbox *self) {
if (self->checked) {
printf("Draw Windows Checkbox [X]\n");
} else {
printf("Draw Windows Checkbox [ ]\n");
}
}

/* ===== 对外暴露的抽象接口实现 ===== */

void checkbox_draw(Checkbox *self) {
if (!self) {
return;
}
win_checkbox_draw(self);
}

void checkbox_destroy(Checkbox *self) {
free(self);
}

/* ===== 工厂内部使用的创建函数 ===== */

Checkbox *win_checkbox_create(void) {
Checkbox *cb = calloc(1, sizeof(*cb));
if (!cb) {
return NULL;
}

cb->checked = 0;
return cb;
}


抽象工厂 gui_factory.h

抽象工厂(Abstract Factory)接口声明了一组创建各种抽象产品的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef GUI_FACTORY_H
#define GUI_FACTORY_H

#include "button.h"
#include "checkbox.h"

typedef struct GuiFactory GuiFactory;

/* 抽象工厂接口 */
Button *gui_factory_create_button(GuiFactory *self);
Checkbox *gui_factory_create_checkbox(GuiFactory *self);
void gui_factory_destroy(GuiFactory *self);

/* 工厂创建函数(静态多态) */
GuiFactory *win_factory_create(void);
GuiFactory *linux_factory_create(void);

#endif

具体工厂 win_factory.c

具体工厂 (Concrete Factory) 实现抽象工厂的构建方法。 每个具体工厂都对应特定产品变体, 且仅创建此种产品变体。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <stdlib.h>
#include "gui_factory.h"

/* 内部依赖具体产品 */
Button *win_button_create(void);
Checkbox *win_checkbox_create(void);

struct GuiFactory {
Button *(*create_button)(void);
Checkbox *(*create_checkbox)(void);
};

static Button *create_button(void) {
return win_button_create();
}

static Checkbox *create_checkbox(void) {
return win_checkbox_create();
}

GuiFactory *win_factory_create(void) {
GuiFactory *f = calloc(1, sizeof(*f));
f->create_button = create_button;
f->create_checkbox = create_checkbox;
return f;
}

Button *gui_factory_create_button(GuiFactory *self) {
return self->create_button();
}

Checkbox *gui_factory_create_checkbox(GuiFactory *self) {
return self->create_checkbox();
}

void gui_factory_destroy(GuiFactory *self) {
free(self);
}

测试客户端代码 main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "gui_factory.h"

int main(void) {
GuiFactory *factory = win_factory_create();
/* GuiFactory *factory = linux_factory_create(); */

Button *btn = gui_factory_create_button(factory);
Checkbox *cb = gui_factory_create_checkbox(factory);

button_draw(btn);
checkbox_draw(cb);

button_destroy(btn);
checkbox_destroy(cb);
gui_factory_destroy(factory);

while(1);
return 0;
}

总结

   简单工厂是指将对象的创建封装在独立的函数中,并用条件语句区分对象类型。工厂方法是一种面向对象的设计模式,将对象的创建解耦分散到不同的子类工厂,也就是将实例化延迟到子类中,并支持实现模板流程。抽象工厂也是一种面向对象的设计模式,它主要用于生产同一产品族不同系列的产品对象。