设计模式专题之C语言-原型模式

1.简介

原型模式(Prototype Pattern)是一种创建型设计模式,它允许一个对象通过复制现有的对象来创建新对象,而不是通过 new 关键字创建新对象。这种模式可以提高性能和复用性,特别是在创建新对象需要复杂的初始化或者资源密集型操作时。

2.通俗讲解

假设你是一位玩具制造商,你正在制作两种玩具模型:圆形小球和矩形积木。你想要快速地生产出大量的这些玩具模型,但是每次从头开始制作一个新的模型都需要花费很多时间和精力。于是,你决定采用一种更高效的方法——克隆现有的模型。

制作玩具模型的过程:

  • 准备模具:
    首先,你需要准备一个圆形小球的模型和一个矩形积木的模型。
    模型包含了玩具的基本信息,比如颜色、大小等。
  • 制作模型:
    对于圆形小球,你需要记录它的半径。
    对于矩形积木,你需要记录它的宽度和高度。
  • 克隆模型:
    一旦有了基本模型,你可以通过“克隆”来快速制造出更多的玩具。
    “克隆”意味着复制一个模型的所有特征,比如颜色、大小等。
  • 检查克隆的玩具:
    你可以检查克隆出来的玩具是否与原始模型完全一样。
    比如,圆形小球的克隆体应该有同样的颜色和半径;矩形积木的克隆体应该有同样的颜色、宽度和高度。
  • 继续生产:
    通过不断克隆这些模型,你可以快速地制造出大量的玩具。

3.实战

3.1.代码

在 C 语言中,没有直接支持对象的概念,但我们可以使用结构体和函数指针来模拟这一行为。下面是一个简单的例子,我们将实现一个 Shape 结构体,并且提供两种形状:圆形和矩形。

这段代码就像是一个小型的玩具工厂,其中包含了一个简单的生产线:

  • 准备模型:
    在代码中,圆形小球对应着 Circle 结构体,矩形积木对应着 Rectangle 结构体。
    每个结构体都包含了模型的基本信息,比如圆形小球的半径,矩形积木的宽度和高度。
  • 制作模型:
    创建一个圆形小球的实例,记录它的半径。
    创建一个矩形积木的实例,记录它的宽度和高度。
  • 克隆模型:
    使用 circle_clone 函数来克隆圆形小球。
    使用 rectangle_clone 函数来克隆矩形积木。
    克隆过程中会复制所有相关的数据,比如半径、宽度和高度。
  • 检查克隆的模型:
    通过打印克隆后的圆形小球和矩形积木的信息,我们可以验证它们是否与原始模型一致。
  • 清理:
    最后,我们需要释放所有分配的内存,以避免内存泄漏。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Shape 类型定义
typedef struct Shape {
    char* name;
    void (*clone)(struct Shape* source, struct Shape* target);
} Shape;

// Circle 类型定义
typedef struct Circle {
    Shape shape;
    int radius;
} Circle;

// Rectangle 类型定义
typedef struct Rectangle {
    Shape shape;
    int width;
    int height;
} Rectangle;

// Shape 克隆函数
void shape_clone(Shape* source, Shape* target) {
    target->name = strdup(source->name);
    target->clone = source->clone;
}

// Circle 克隆函数
void circle_clone(Circle* source, Circle* target) {
    shape_clone(&source->shape, &target->shape);
    target->radius = source->radius;
}

// Rectangle 克隆函数
void rectangle_clone(Rectangle* source, Rectangle* target) {
    shape_clone(&source->shape, &target->shape);
    target->width = source->width;
    target->height = source->height;
}

int main() {
    // 创建 Circle 实例
    Circle* circle = malloc(sizeof(Circle));
    circle->shape.name = strdup("Circle");
    circle->shape.clone = (void (*)(Shape*, Shape*))circle_clone;
    circle->radius = 10;

    // 创建 Rectangle 实例
    Rectangle* rectangle = malloc(sizeof(Rectangle));
    rectangle->shape.name = strdup("Rectangle");
    rectangle->shape.clone = (void (*)(Shape*, Shape*))rectangle_clone;
    rectangle->width = 20;
    rectangle->height = 30;

    // 克隆 Circle 和 Rectangle
    Circle* cloned_circle = malloc(sizeof(Circle));
    circle_clone(circle, cloned_circle);

    Rectangle* cloned_rectangle = malloc(sizeof(Rectangle));
    rectangle_clone(rectangle, cloned_rectangle);

    // 打印信息
    printf("Original Circle: %s with radius %d\n", circle->shape.name, circle->radius);
    printf("Cloned Circle: %s with radius %d\n", cloned_circle->shape.name, cloned_circle->radius);
    printf("Original Rectangle: %s with dimensions %dx%d\n", rectangle->shape.name, rectangle->width, rectangle->height);
    printf("Cloned Rectangle: %s with dimensions %dx%d\n", cloned_rectangle->shape.name, cloned_rectangle->width, cloned_rectangle->height);

    // 清理内存
    free(circle->shape.name);
    free(cloned_circle->shape.name);
    free(rectangle->shape.name);
    free(cloned_rectangle->shape.name);
    free(circle);
    free(cloned_circle);
    free(rectangle);
    free(cloned_rectangle);

    return 0;
}

3.2.代码解析

  • 原型模式的实现:
    使用结构体 Shape 作为基类,并包含了一个名为 clone 的函数指针成员。
    Circle 和 Rectangle 结构体分别继承了 Shape,并提供了它们各自的 clone 方法。
  • 克隆功能:
    在 main 函数中,我们创建了一个圆形和一个矩形,并为每个对象分配了内存。
    我们使用 circle_clone 和 rectangle_clone 函数来创建圆形和矩形的副本。
    副本具有与原对象相同的属性值。
  • 内存管理:
    在 shape_clone 函数中,我们使用 strdup 复制字符串,以确保 name 字段不会指向相同的内存位置。
    在程序结束前,我们释放了所有分配的内存,避免内存泄漏。
  • 性能考虑:
    使用原型模式可以避免构造函数中的复杂初始化逻辑,从而提高创建新对象的速度。
    如果对象的状态依赖于外部环境或需要复杂的计算,原型模式尤其有用。

总结来说,通过这个简单的示例,我们展示了如何在 C 语言中使用原型模式来简化对象的创建过程。这种方式不仅提高了代码的可读性和可维护性,还能够有效地减少对象初始化的时间消耗。

3.3.代码运行

Original Circle: Circle with radius 10
Cloned Circle: Circle with radius 10
Original Rectangle: Rectangle with dimensions 20x30
Cloned Rectangle: Rectangle with dimensions 20x30

3.4.结果分析

我们首先准备了两个模型:圆形小球和矩形积木。然后,我们使用这些模型来制造新的玩具。为了制造新玩具,我们只需简单地克隆现有的模型,这样就省去了重新制作模型的步骤。最后,我们检查新玩具是否与原来的模型相同。通过这种方式,我们可以快速地制造出大量一致的玩具模型,而无需每次都从头开始制作。这正是原型模式在代码中的应用。

4.总结

  • 什么是原型模式?
    在原型模式中,一个类声明了一个克隆方法,用于创建自己的副本。这些副本是原始对象的浅拷贝或深拷贝。浅拷贝只复制对象本身,而深拷贝会递归地复制对象及其内部的所有引用。

  • 为什么使用原型模式?
    减少初始化时间:如果创建一个对象需要复杂的初始化过程,那么克隆已有的实例会更快。
    避免重复初始化:当对象的创建依赖于复杂的外部状态时,可以通过克隆已经设置好的对象来避免重复设置。
    封装创建细节:对象的创建逻辑被封装在其内部,外部不需要知道具体的创建细节。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

甜航一直在

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值