06设计模式_生成器模式_C语言实现

生成器模式

1 简介

生成器模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

这句话怎么理解呢?

我们来把一些关键词逐一解释下:

复杂对象:通常是指含有多个部件,且需要按某种步骤将各部件组合在一起的对象。

对象的构建:指将各部件按某种步骤组合成一个对象的过程。

对象的表示:指各部件的具体实现。

2 模拟场景

我们还是举生产电脑的例子。

这个例子的具体场景和工厂类方法中生产电脑的场景不太一样。(如果想详细了解工厂类方法中的场景,请自行查看工厂类方法对应的章节)

在工厂类方法中,我们关注的是如何创建电脑的单个部件或者相互依赖的几个部件。但我们都知道,仅有电脑的部件还不行,还需要将各部件组合起来才能形成一台完整的电脑。这就是生成器模式所说的“复杂对象的构建”

我们再考虑下,一家电脑厂商通常会生产不同型号的电脑,比如高性能电脑、低成本电脑。

生产不同型号的电脑的过程有如下特点:

组装过程一样,都是先有主板,然后把CPU、内存条、硬盘安装到主板上。即:同样的构建过程

采用的硬盘、内存条、CPU、主板不一样。即:不同的表示

这就可以采用生成器模式“同样的构建过程可以创建不同的表示”的特点来实现。

3 使用生成器模式实现电脑对象的创建

参与者

  1. Product: Computer

定义电脑(被创建的复杂对象)的接口

  1. Builder: ComputerBuilder

指定创建Computer的各部件的接口----BuildHardDisk()、BuildDdr()、BuildCpu()、BuildBoard()

指定返回Computer的接口----GetComputer()

  1. ConcreteBuilder: HighPerfComputerBuilder、LowCostComputerBuilder

实现ComputerBuilder接口

  1. Director: ComputerDirector

使用ComputerBuilder接口,指定Computer的构建步骤。即:提供一个Construct()方法,该方法调用ComputerBuilder的接口,按步骤创建Computer。

UML

在这里插入图片描述

Computer示例代码

computer.h

#ifndef COMPUTER_H
#define COMPUTER_H

struct Computer {
    char hardDisk[30];
    char ddr[30];
    char cpu[30];
    char board[30];
    void (*SetHardDisk)(struct Computer *this, char *hardDisk);
    void (*SetDdr)(struct Computer *this, char *ddr);
    void (*SetCpu)(struct Computer *this, char *cpu);
    void (*SetBoard)(struct Computer *this, char *board);
    void (*Show)(struct Computer *this);
};

// 构造函数
void Computer(struct Computer *this);
// 析构函数
void _Computer(struct Computer *this);

#endif

computer.c

#include <stdio.h>
#include <string.h>
#include "computer.h"

static void SetHardDisk(struct Computer *this, char *hardDisk)
{
    strncpy(this->hardDisk, hardDisk, 30);
    this->hardDisk[30 - 1] = '\0';
}

static void SetDdr(struct Computer *this, char *ddr)
{
    strncpy(this->ddr, ddr, 30);
    this->ddr[30 - 1] = '\0';
}

static void SetCpu(struct Computer *this, char *cpu)
{
    strncpy(this->cpu, cpu, 30);
    this->cpu[30 - 1] = '\0';
}

static void SetBoard(struct Computer *this, char *board)
{
    strncpy(this->board, board, 30);
    this->cpu[30 - 1] = '\0';
}

static void Show(struct Computer *this)
{
    printf("输出电脑对象:\n");
    printf(" %s\n", this->board);
    printf(" %s\n", this->cpu);
    printf(" %s\n", this->ddr);
    printf(" %s\n", this->hardDisk);
}

void Computer(struct Computer *this)
{
    this->hardDisk[0] = '\0';
    this->ddr[0] = '\0';
    this->cpu[0] = '\0';
    this->board[0] = '\0';
    this->SetHardDisk = SetHardDisk;
    this->SetDdr = SetDdr;
    this->SetCpu = SetCpu;
    this->SetBoard = SetBoard;
    this->Show = Show;
}

void _Computer(struct Computer *this)
{
    this->SetHardDisk = NULL;
    this->SetDdr = NULL;
    this->SetCpu = NULL;
    this->SetBoard = NULL;
    this->Show = NULL;
}

ComputerBuilder示例代码

computer_builder.h

#ifndef COMPUTER_BUILDER_H
#define COMPUTER_BUILDER_H

#include "computer.h"

struct ComputerBuilder {
    struct Computer *computer;
    void (*BuildHardDisk)(struct ComputerBuilder *this);
    void (*BuildDdr)(struct ComputerBuilder *this);
    void (*BuildCpu)(struct ComputerBuilder *this);
    void (*BuildBoard)(struct ComputerBuilder *this);
    struct Computer* (*GetComputer)(struct ComputerBuilder *this);
};

#endif

HighPerfComputerBuilder示例代码

high_perf_computer_builder.h

#ifndef HIGH_PERF_COMPUTER_BUILDER_H
#define HIGH_PERF_COMPUTER_BUILDER_H

#include "computer_builder.h"

struct HighPerfComputerBuilder {
    struct ComputerBuilder computerBuilder;
};

// 构造函数
void HighPerfComputerBuilder(struct HighPerfComputerBuilder *this);
// 析构函数
void _HighPerfComputerBuilder(struct HighPerfComputerBuilder *this); 

#endif

high_perf_computer_builder.c

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include "high_perf_computer_builder.h"

static void BuildHardDisk(struct ComputerBuilder *this)
{
    if (this->computer == NULL) {
        printf("err: computer is null\n");
    }
    this->computer->SetHardDisk(this->computer, "2T大容量硬盘");
}

static void BuildDdr(struct ComputerBuilder *this)
{
    if (this->computer == NULL) {
        printf("err: computer is null\n");
    }
    this->computer->SetDdr(this->computer, "32G内存");
}

static void BuildCpu(struct ComputerBuilder *this)
{
    if (this->computer == NULL) {
        printf("err: computer is null\n");
    }
    this->computer->SetCpu(this->computer, "i7八核八线程CPU");
}

static void BuildBoard(struct ComputerBuilder *this)
{
    if (this->computer == NULL) {
        printf("err: computer is null\n");
    }
    this->computer->SetBoard(this->computer, "高端主板");
}

static struct Computer* GetComputer(struct ComputerBuilder *this) {
    return this->computer;
}

void HighPerfComputerBuilder(struct HighPerfComputerBuilder *this) 
{
    this->computerBuilder.computer = malloc(sizeof(struct Computer));
    Computer(this->computerBuilder.computer);
    this->computerBuilder.BuildHardDisk = BuildHardDisk;
    this->computerBuilder.BuildDdr = BuildDdr;
    this->computerBuilder.BuildCpu = BuildCpu;
    this->computerBuilder.BuildBoard = BuildBoard;
    this->computerBuilder.GetComputer = GetComputer;
}

void _HighPerfComputerBuilder(struct HighPerfComputerBuilder *this) 
{
    if (this->computerBuilder.computer != NULL) {
        _Computer(this->computerBuilder.computer);
        free(this->computerBuilder.computer);
        this->computerBuilder.computer = NULL;
    }
    this->computerBuilder.BuildHardDisk = NULL;
    this->computerBuilder.BuildDdr = NULL;
    this->computerBuilder.BuildCpu = NULL;
    this->computerBuilder.BuildBoard = NULL;
    this->computerBuilder.GetComputer = NULL;
}

LowCostComputerBuilder示例代码

low_cost_computer_builder.h

#ifndef LOW_COST_COMPUTER_BUILDER_H
#define LOW_COST_COMPUTER_BUILDER_H

#include "computer_builder.h"

struct LowCostComputerBuilder {
    struct ComputerBuilder computerBuilder;
};

// 构造函数
void LowCostComputerBuilder(struct LowCostComputerBuilder *this);
// 析构函数
void _LowCostComputerBuilder(struct LowCostComputerBuilder *this); 

#endif

low_cost_computer_builder.c

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include "low_cost_computer_builder.h"

static void BuildHardDisk(struct ComputerBuilder *this)
{
    if (this->computer == NULL) {
        printf("err: computer is null\n");
    }
    this->computer->SetHardDisk(this->computer, "256G硬盘");
}

static void BuildDdr(struct ComputerBuilder *this)
{
    if (this->computer == NULL) {
        printf("err: computer is null\n");
    }
    this->computer->SetDdr(this->computer, "4G内存");
}

static void BuildCpu(struct ComputerBuilder *this)
{
    if (this->computer == NULL) {
        printf("err: computer is null\n");
    }
    this->computer->SetCpu(this->computer, "i3CPU");
}

static void BuildBoard(struct ComputerBuilder *this)
{
    if (this->computer == NULL) {
        printf("err: computer is null\n");
    }
    this->computer->SetBoard(this->computer, "普通主板");
}

static struct Computer* GetComputer(struct ComputerBuilder *this) {
    return this->computer;
}

void LowCostComputerBuilder(struct LowCostComputerBuilder *this) 
{
    this->computerBuilder.computer = malloc(sizeof(struct Computer));
    Computer(this->computerBuilder.computer);
    this->computerBuilder.BuildHardDisk = BuildHardDisk;
    this->computerBuilder.BuildDdr = BuildDdr;
    this->computerBuilder.BuildCpu = BuildCpu;
    this->computerBuilder.BuildBoard = BuildBoard;
    this->computerBuilder.GetComputer = GetComputer;
}

void _LowCostComputerBuilder(struct LowCostComputerBuilder *this) 
{
    if (this->computerBuilder.computer != NULL) {
        _Computer(this->computerBuilder.computer);
        free(this->computerBuilder.computer);
        this->computerBuilder.computer = NULL;
    }
    this->computerBuilder.BuildHardDisk = NULL;
    this->computerBuilder.BuildDdr = NULL;
    this->computerBuilder.BuildCpu = NULL;
    this->computerBuilder.BuildBoard = NULL;
    this->computerBuilder.GetComputer = NULL;
}

ComputerDirector示例代码

computer_director.h

#ifndef COMPUTER_DIRECTOR_H
#define COMPUTER_DIRECTOR_H

#include "computer_builder.h"

struct ComputerDirector {
    void (*Construct)(struct ComputerDirector *this, struct ComputerBuilder *computerBuilder);
};

// 构造函数
void ComputerDirector(struct ComputerDirector *this);
// 析构函数
void _ComputerDirector(struct ComputerDirector *this);

#endif

computer_director.c

#include <stdio.h>
#include "computer_director.h"

void Construct(struct ComputerDirector *this, struct ComputerBuilder *computerBuilder)
{
    printf("开始构建电脑\n");
    printf(" 第一步:创建主板\n");
    computerBuilder->BuildBoard(computerBuilder);

    printf(" 第二步:在主板上安装CPU\n");
    computerBuilder->BuildCpu(computerBuilder);

    printf(" 第三步:在主板上安装内存条\n");
    computerBuilder->BuildDdr(computerBuilder);
    
    printf(" 第四步:在主板上安装硬盘\n");
    computerBuilder->BuildHardDisk(computerBuilder);
}

void ComputerDirector(struct ComputerDirector *this)
{
    this->Construct = Construct;
}

void _ComputerDirector(struct ComputerDirector *this)
{
    this->Construct = NULL;
}

客户端代码示例

main.c

#include <stddef.h>
#include <stdio.h>
#include "computer_director.h"
#include "high_perf_computer_builder.h"
#include "low_cost_computer_builder.h"

void main()
{
    struct Computer *computer = NULL;

    struct ComputerDirector computerDirector;
    ComputerDirector(&computerDirector);
   
    // 构建高性能电脑
    printf("构建高性能电脑\n");
    struct HighPerfComputerBuilder highPerfComputerBuilder;
    HighPerfComputerBuilder(&highPerfComputerBuilder);
    computerDirector.Construct(&computerDirector, (struct ComputerBuilder*)&highPerfComputerBuilder);  
    computer = highPerfComputerBuilder.computerBuilder.GetComputer((struct ComputerBuilder*)&highPerfComputerBuilder);  
    if (computer != NULL) {
        computer->Show(computer);
    }
    _HighPerfComputerBuilder(&highPerfComputerBuilder);
    
    printf("\n\n");

    // 构建低成本电脑
    printf("构建低成本电脑\n");
    struct LowCostComputerBuilder lowCostComputerBuilder;
    LowCostComputerBuilder(&lowCostComputerBuilder);
    computerDirector.Construct(&computerDirector, (struct ComputerBuilder*)&lowCostComputerBuilder);  
    computer = lowCostComputerBuilder.computerBuilder.GetComputer((struct ComputerBuilder*)&lowCostComputerBuilder); 
    if (computer != NULL) {
        computer->Show(computer);
    }
    _LowCostComputerBuilder(&lowCostComputerBuilder);

    _ComputerDirector(&computerDirector);
}

客户端显示示例

-bash-4.2# ./computer
构建高性能电脑
开始构建电脑
 第一步:创建主板
 第二步:在主板上安装CPU
 第三步:在主板上安装内存条
 第四步:在主板上安装硬盘
输出电脑对象:
 高端主板
 i7八核八线程CPU
 32G内存
 2T大容量硬盘


构建低成本电脑
开始构建电脑
 第一步:创建主板
 第二步:在主板上安装CPU
 第三步:在主板上安装内存条
 第四步:在主板上安装硬盘
输出电脑对象:
 普通主板
 i3CPU
 4G内存
 256G硬盘

猜你喜欢

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