抽象工厂模式
1 简介和模拟场景
在“简单工厂方法模式”和“工厂方法模式”中,我们已经讲过“硬盘”的实现。
现在我们回到之前的模拟场景中,我们发现生产电脑除了需要硬盘,还需要内存条、CPU、主板。那么这些部件又该如何实现呢?
根据“简单工厂方法模式”和“工厂方法模式”中创建硬盘的实现案例,我们很容易如法炮制出创建内存条、CPU、主板的代码(如有疑问请自行回到“简单工厂方法模式”和“工厂方法模式”章节)。
既然生产电脑的各种部件都创建出来了,那么下一步就只需要在产线上将各部件组装在一起即可。到这里一切似乎很完美,但仔细分析就会发现一个问题:生产电脑的各个部件并非完全独立,它们之间可能存在配套关系,比如:intel的CPU需要和intel的主板配套,如果产线上将intel的CPU和AMD的主板安装在一起,生产出的电脑可能无法正常工作。
如果我们使用了“简单工厂方法模式”或者“工厂方法模式”来创建各部件,组装产线上需要进行各部件的组合,但组装产线上又不关注具体部件的创建过程,也就是说组装产线上并不知道当前使用的是哪个供应商的部件,所以很难识别各部件的匹配关系。那就可能出现部件不配套的问题。
抽象工厂提供一个创建一系列相关或者相互依赖对象的接口。它可以解决上述部件不配套的问题。
比如:我们可以把CPU和主板放在一个工厂找那个创建,在创建时保证intel CPU和intel主板一起创建出来,AMD CPU和AMD主板一起创建出来。
这样给到组装产线的部件就已经配套好了,不会出现部件不配套的问题了。
顺便啰嗦几句:
个人认为抽象工厂模式中“抽象”这个词有点名不符实,如果叫做家族工厂模式会更贴切些。即:一个工厂一次把属于一个家族的多个对象都创建出来。
但既然伟大的GOF已经给它取了抽象工厂这个名字,我们也就不纠结了,就叫抽象工厂模式好了。我们只要能够理解抽象工厂模式,知道它跟工厂方法模式的区别就好了。
2 使用抽象工厂实现CPU和主板对象的创建
参与者
- AbstractFactory: CpuAndBoardAbstractFactory
声明创建Cpu和Board对象的接口
- ConcreteFactory: IntelConcreteFactory / AmdConcreteFactory
实现不同供应商的Cpu和Board对象的创建
- AbstractProduct: Cpu和Board
分别声明Cpu和Board对象的接口
- ConcreteProduct: IntelCpu和IntelBoard / AmdCpu和AmdBoard
实现不同供应商的Cpu和Board
UML
CpuAndBoardAbstractFactory代码示例
cpu_and_board_abstract_factory.h
#ifndef CPU_AND_BOARD_ABSTRACT_FACTORY_H
#define CPU_AND_BOARD_ABSTRACT_FACTORY_H
#include "cpu.h"
#include "board.h"
struct CpuAndBoardAbstractFactory {
struct Cpu* (*CreateCpu)(struct CpuAndBoardAbstractFactory *this);
struct Board* (*CreateBoard)(struct CpuAndBoardAbstractFactory *this);
void (*DestroyCpu)(struct CpuAndBoardAbstractFactory *this,
struct Cpu* cpu);
void (*DestroyBoard)(struct CpuAndBoardAbstractFactory *this,
struct Board* board);
};
#endif
IntelConcreteFactory代码示例
intel_concrete_factory.h
#ifndef INTEL_CONCRETE_FACTORY_H
#define INTEL_CONCRETE_FACTORY_H
#include "cpu_and_board_abstract_factory.h"
struct IntelConcreteFactory {
struct CpuAndBoardAbstractFactory cpuAndBoardAbstractFactory;
};
// 构造函数
void IntelConcreteFactory(struct IntelConcreteFactory *this);
// 析构函数
void _IntelConcreteFactory(struct IntelConcreteFactory *this);
#endif
intel_concrete_factory.c
#include <stdio.h>
#include <stdlib.h>
#include "intel_concrete_factory.h"
#include "intel_cpu.h"
#include "intel_board.h"
static struct Cpu* CreateCpu(struct IntelConcreteFactory *this)
{
struct IntelCpu *intelCpu = NULL;
if ((intelCpu = malloc(sizeof(struct IntelCpu))) == NULL) {
printf("fail in malloc\n");
return NULL;
}
IntelCpu(intelCpu);
return (struct Cpu*)intelCpu;
}
static void DestroyCpu(struct IntelConcreteFactory *this, struct Cpu *cpu)
{
if (cpu != NULL) {
free(cpu);
cpu = NULL;
}
}
static struct Board* CreateBoard(struct IntelConcreteFactory *this)
{
struct IntelBoard *intelBoard = NULL;
if ((intelBoard = malloc(sizeof(struct IntelBoard))) == NULL) {
printf("fail in malloc\n");
return NULL;
}
IntelBoard(intelBoard);
return (struct Board*)intelBoard;
}
static void DestroyBoard(struct IntelConcreteFactory *this, struct Board *board)
{
if (board != NULL) {
free(board);
board = NULL;
}
}
// 构造函数
void IntelConcreteFactory(struct IntelConcreteFactory *this)
{
this->cpuAndBoardAbstractFactory.CreateCpu
= (struct Cpu*(*)(struct CpuAndBoardAbstractFactory*))CreateCpu;
this->cpuAndBoardAbstractFactory.CreateBoard
= (struct Board*(*)(struct CpuAndBoardAbstractFactory*))CreateBoard;
this->cpuAndBoardAbstractFactory.DestroyCpu
= (void (*)(struct CpuAndBoardAbstractFactory*, struct Cpu*))DestroyCpu;
this->cpuAndBoardAbstractFactory.DestroyBoard
= (void (*)(struct CpuAndBoardAbstractFactory*, struct Board*))DestroyBoard;
}
// 析构函数
void _IntelConcreteFactory(struct IntelConcreteFactory *this)
{
this->cpuAndBoardAbstractFactory.CreateCpu = NULL;
this->cpuAndBoardAbstractFactory.CreateBoard = NULL;
this->cpuAndBoardAbstractFactory.DestroyCpu = NULL;
this->cpuAndBoardAbstractFactory.DestroyBoard = NULL;
}
AmdConcreteFactory代码示例
amd_concrete_factory.h
#ifndef AMD_CONCRETE_FACTORY_H
#define AMD_CONCRETE_FACTORY_H
#include "cpu_and_board_abstract_factory.h"
struct AmdConcreteFactory {
struct CpuAndBoardAbstractFactory cpuAndBoardAbstractFactory;
};
// 构造函数
void AmdConcreteFactory(struct AmdConcreteFactory *this);
// 析构函数
void _AmdConcreteFactory(struct AmdConcreteFactory *this);
#endif
amd_concrete_factory.c
#include <stdio.h>
#include <stdlib.h>
#include "amd_concrete_factory.h"
#include "amd_cpu.h"
#include "amd_board.h"
static struct Cpu* CreateCpu(struct AmdConcreteFactory *this)
{
struct AmdCpu *amdCpu = NULL;
if ((amdCpu = malloc(sizeof(struct AmdCpu))) == NULL) {
printf("fail in malloc\n");
return NULL;
}
AmdCpu(amdCpu);
return (struct Cpu*)amdCpu;
}
static void DestroyCpu(struct AmdConcreteFactory *this, struct Cpu *cpu)
{
if (cpu != NULL) {
free(cpu);
cpu = NULL;
}
}
static struct Board* CreateBoard(struct AmdConcreteFactory *this)
{
struct AmdBoard *amdBoard = NULL;
if ((amdBoard = malloc(sizeof(struct AmdBoard))) == NULL) {
printf("fail in malloc\n");
return NULL;
}
AmdBoard(amdBoard);
return (struct Board*)amdBoard;
}
static void DestroyBoard(struct AmdConcreteFactory *this, struct Board *board)
{
if (board != NULL) {
free(board);
board = NULL;
}
}
// 构造函数
void AmdConcreteFactory(struct AmdConcreteFactory *this)
{
this->cpuAndBoardAbstractFactory.CreateCpu
= (struct Cpu*(*)(struct CpuAndBoardAbstractFactory*))CreateCpu;
this->cpuAndBoardAbstractFactory.CreateBoard
= (struct Board*(*)(struct CpuAndBoardAbstractFactory*))CreateBoard;
this->cpuAndBoardAbstractFactory.DestroyCpu
= (void (*)(struct CpuAndBoardAbstractFactory*, struct Cpu*))DestroyCpu;
this->cpuAndBoardAbstractFactory.DestroyBoard
= (void (*)(struct CpuAndBoardAbstractFactory*, struct Board*))DestroyBoard;
}
// 析构函数
void _AmdConcreteFactory(struct AmdConcreteFactory *this)
{
this->cpuAndBoardAbstractFactory.CreateCpu = NULL;
this->cpuAndBoardAbstractFactory.CreateBoard = NULL;
this->cpuAndBoardAbstractFactory.DestroyCpu = NULL;
this->cpuAndBoardAbstractFactory.DestroyBoard = NULL;
}
Cpu代码示例
cpu.h
#ifndef CPU_H
#define CPU_H
struct Cpu {
void (*Operation)(struct Cpu *this);
};
#endif
IntelCpu代码示例
intel_cpu.h
#ifndef INTEL_CPU_H
#define INTEL_CPU_H
#include "cpu.h"
struct IntelCpu {
struct Cpu cpu;
};
// 构造函数
void IntelCpu(struct IntelCpu *this);
// 析构函数
void _IntelCpu(struct IntelCpu *this);
#endif
intel_cpu.c
#include "intel_cpu.h"
#include "stdio.h"
void IntelOperationCpu(struct IntelCpu *this)
{
printf(" 这是 Intel CPU\n");
}
void IntelCpu(struct IntelCpu *this)
{
this->cpu.Operation = (void(*)(struct Cpu *))IntelOperationCpu;
}
void _IntelCpu(struct IntelCpu *this)
{
this->cpu.Operation = NULL;
}
AmdCpu代码示例
amd_cpu.h
#ifndef AMD_CPU_H
#define AMD_CPU_H
#include "cpu.h"
struct AmdCpu {
struct Cpu cpu;
};
// 构造函数
void AmdCpu(struct AmdCpu *this);
// 析构函数
void _AmdCpu(struct AmdCpu *this);
#endif
amd_cpu.c
#include "amd_cpu.h"
#include "stdio.h"
void AmdOperationCpu(struct AmdCpu *this)
{
printf(" 这是 Amd CPU\n");
}
void AmdCpu(struct AmdCpu *this)
{
this->cpu.Operation = (void(*)(struct Cpu *))AmdOperationCpu;
}
void _AmdCpu(struct AmdCpu *this)
{
this->cpu.Operation = NULL;
}
Board代码示例
board.h
#ifndef BOARD_H
#define BOARD_H
struct Board {
void (*Operation)(struct Board *this);
};
#endif
IntelBoard代码示例
intel_board.h
#ifndef INTEL_BOARD_H
#define INTEL_BOARD_H
#include "board.h"
struct IntelBoard {
struct Board board;
};
// 构造函数
void IntelBoard(struct IntelBoard *this);
// 析构函数
void _IntelBoard(struct IntelBoard *this);
#endif
intel_board.c
#include "intel_board.h"
#include "stdio.h"
void IntelOperationBoard(struct IntelBoard *this)
{
printf(" 这是 Intel 主板\n");
}
void IntelBoard(struct IntelBoard *this)
{
this->board.Operation = (void(*)(struct Board *))IntelOperationBoard;
}
void _IntelBoard(struct IntelBoard *this)
{
this->board.Operation = NULL;
}
AmdBoard代码示例
amd_board.h
#ifndef AMD_BOARD_H
#define AMD_BOARD_H
#include "board.h"
struct AmdBoard {
struct Board board;
};
// 构造函数
void AmdBoard(struct AmdBoard *this);
// 析构函数
void _AmdBoard(struct AmdBoard *this);
#endif
amd_board.c
#include "amd_board.h"
#include "stdio.h"
void AmdOperationBoard(struct AmdBoard *this)
{
printf(" 这是 Amd 主板\n");
}
void AmdBoard(struct AmdBoard *this)
{
this->board.Operation = (void(*)(struct Board *))AmdOperationBoard;
}
void _AmdBoard(struct AmdBoard *this)
{
this->board.Operation = NULL;
}
客户端代码示例
#include "cpu.h"
#include "board.h"
#include "cpu_and_board_abstract_factory.h"
#include "intel_concrete_factory.h"
#include "amd_concrete_factory.h"
#include "stddef.h"
#include "stdio.h"
void main()
{
struct Cpu *cpu = NULL;
struct Board *board = NULL;
struct CpuAndBoardAbstractFactory *abstractFactory = NULL;
printf("创建 Intel CPU和主板:\n");
struct IntelConcreteFactory intelConcreteFactory;
IntelConcreteFactory(&intelConcreteFactory);
abstractFactory = (struct CpuAndBoardAbstractFactory *)&intelConcreteFactory;
// 创建 Intel CPU对象
cpu = abstractFactory->CreateCpu(abstractFactory);
// 创建 Intel 主板对象
board = abstractFactory->CreateBoard(abstractFactory);
// 使用 Intel CPU对象
cpu->Operation(cpu);
// 使用 Intel 主板对象
board->Operation(board);
// 销毁 Intel CPU对象
abstractFactory->DestroyCpu(abstractFactory, cpu);
// 销毁 Intel 主板对象
abstractFactory->DestroyBoard(abstractFactory, board);
_IntelConcreteFactory(&intelConcreteFactory);
printf("创建 AMD CPU和主板:\n");
struct AmdConcreteFactory amdConcreteFactory;
AmdConcreteFactory(&amdConcreteFactory);
abstractFactory = (struct CpuAndBoardAbstractFactory *)&amdConcreteFactory;
// 创建 Amd CPU对象
cpu = abstractFactory->CreateCpu(abstractFactory);
// 创建 Amd 主板对象
board = abstractFactory->CreateBoard(abstractFactory);
// 使用 Amd CPU对象
cpu->Operation(cpu);
// 使用 Amd 主板对象
board->Operation(board);
// 销毁 Amd CPU对象
abstractFactory->DestroyCpu(abstractFactory, cpu);
// 销毁 Amd 主板对象
abstractFactory->DestroyBoard(abstractFactory, board);
_AmdConcreteFactory(&amdConcreteFactory);
}
客户端显示示例
-bash-4.2# ./test
创建 Intel CPU和主板:
这是 Intel CPU
这是 Intel 主板
创建 AMD CPU和主板:
这是 Amd CPU
这是 Amd 主板