05设计模式_抽象工厂模式_C语言实现

抽象工厂模式

1 简介和模拟场景

在“简单工厂方法模式”和“工厂方法模式”中,我们已经讲过“硬盘”的实现。

现在我们回到之前的模拟场景中,我们发现生产电脑除了需要硬盘,还需要内存条、CPU、主板。那么这些部件又该如何实现呢?

根据“简单工厂方法模式”和“工厂方法模式”中创建硬盘的实现案例,我们很容易如法炮制出创建内存条、CPU、主板的代码(如有疑问请自行回到“简单工厂方法模式”和“工厂方法模式”章节)。

既然生产电脑的各种部件都创建出来了,那么下一步就只需要在产线上将各部件组装在一起即可。到这里一切似乎很完美,但仔细分析就会发现一个问题:生产电脑的各个部件并非完全独立,它们之间可能存在配套关系,比如:intel的CPU需要和intel的主板配套,如果产线上将intel的CPU和AMD的主板安装在一起,生产出的电脑可能无法正常工作。

如果我们使用了“简单工厂方法模式”或者“工厂方法模式”来创建各部件,组装产线上需要进行各部件的组合,但组装产线上又不关注具体部件的创建过程,也就是说组装产线上并不知道当前使用的是哪个供应商的部件,所以很难识别各部件的匹配关系。那就可能出现部件不配套的问题

抽象工厂提供一个创建一系列相关或者相互依赖对象的接口。它可以解决上述部件不配套的问题。

比如:我们可以把CPU和主板放在一个工厂找那个创建,在创建时保证intel CPU和intel主板一起创建出来,AMD CPU和AMD主板一起创建出来。

这样给到组装产线的部件就已经配套好了,不会出现部件不配套的问题了。

顺便啰嗦几句:

个人认为抽象工厂模式中“抽象”这个词有点名不符实,如果叫做家族工厂模式会更贴切些。即:一个工厂一次把属于一个家族的多个对象都创建出来。

但既然伟大的GOF已经给它取了抽象工厂这个名字,我们也就不纠结了,就叫抽象工厂模式好了。我们只要能够理解抽象工厂模式,知道它跟工厂方法模式的区别就好了。

2 使用抽象工厂实现CPU和主板对象的创建

参与者

  1. AbstractFactory: CpuAndBoardAbstractFactory

声明创建Cpu和Board对象的接口

  1. ConcreteFactory: IntelConcreteFactory / AmdConcreteFactory

实现不同供应商的Cpu和Board对象的创建

  1. AbstractProduct: Cpu和Board

分别声明Cpu和Board对象的接口

  1. 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 主板

猜你喜欢

转载自blog.csdn.net/weixin_46826913/article/details/106890510