设计模式专题之C语言-访问者模式

1.简介

访问者模式是一种行为型设计模式,它允许我们向现有类结构添加新的行为,而无需修改这些类。这种模式使用了一个访问者类,该类定义了一组访问方法,每个方法对应于结构中的某个类。这样,我们可以轻松地在不改变原有结构的情况下,通过创建不同的访问者来为整个结构添加新功能。

适用场景

  • 当你需要对一个对象结构中的对象进行很多不同的并且不相关的操作时。
  • 当对象结构中的对象有共同的操作集合时。
  • 当需要对这些操作进行参数化时。

2.通俗讲解

假设我们有一个简单的图形系统,其中包含两种图形:圆形和矩形。我们希望添加一些行为,比如计算面积、绘制图形等,而不修改圆形和矩形本身的代码。

3.实战

结构体定义

  1. 图形接口:定义图形的基本接口,包括接受访问者的函数。
  2. 具体图形:实现具体的图形类。
  3. 访问者接口:定义访问者可以执行的行为。
  4. 具体访问者:实现具体的访问者类。

3.1.代码

#include <stdio.h>

// 定义图形结构体
typedef struct Graphic {
    void (*accept)(struct Graphic *self, void *visitor);
} Graphic;

// 圆形结构体
typedef struct Circle {
    Graphic graphic;
    int radius;
} Circle;

// 矩形结构体
typedef struct Rectangle {
    Graphic graphic;
    int width;
    int height;
} Rectangle;

// 访问者接口
typedef struct Visitor {
    void (*visitCircle)(void *visitor, Circle *circle);
    void (*visitRectangle)(void *visitor, Rectangle *rectangle);
} Visitor;

// 具体图形的实现
void circle_accept(Circle *self, void *visitor) {
    Visitor *v = (Visitor *)visitor;
    v->visitCircle(visitor, self);
}

void rectangle_accept(Rectangle *self, void *visitor) {
    Visitor *v = (Visitor *)visitor;
    v->visitRectangle(visitor, self);
}

// 创建圆形实例
Circle *create_circle(int radius) {
    Circle *c = malloc(sizeof(Circle));
    c->graphic.accept = &circle_accept;
    c->radius = radius;
    return c;
}

// 创建矩形实例
Rectangle *create_rectangle(int width, int height) {
    Rectangle *r = malloc(sizeof(Rectangle));
    r->graphic.accept = &rectangle_accept;
    r->width = width;
    r->height = height;
    return r;
}

// 面积计算访问者
void area_visitor(void *visitor, Circle *circle) {
    Visitor *v = (Visitor *)visitor;
    double area = M_PI * circle->radius * circle->radius;
    printf("Circle area: %.2f\n", area);
}

void area_visitor(void *visitor, Rectangle *rectangle) {
    Visitor *v = (Visitor *)visitor;
    int area = rectangle->width * rectangle->height;
    printf("Rectangle area: %d\n", area);
}

int main() {
    // 创建图形
    Circle *circle = create_circle(5);
    Rectangle *rectangle = create_rectangle(4, 6);

    // 创建访问者
    Visitor areaVisitor = {
        .visitCircle = &area_visitor,
        .visitRectangle = &area_visitor
    };

    // 使用访问者
    circle->graphic.accept(circle, &areaVisitor);
    rectangle->graphic.accept(rectangle, &areaVisitor);

    free(circle);
    free(rectangle);

    return 0;
}

3.2.代码解析

  1. 图形结构体 (Graphic) 包含了一个 accept 函数指针,用于调用访问者的方法。
  2. 具体图形 (Circle, Rectangle) 继承了 Graphic 并实现了自己的 accept 方法。
  3. 访问者结构体 (Visitor) 包含了指向访问者方法的函数指针。
  4. main 函数中,我们创建了一个圆形和一个矩形,然后创建了一个面积计算访问者,并使用这个访问者计算并打印出图形的面积。

3.3.代码运行

  1. 创建了一个半径为5的圆形。
  2. 创建了一个宽度为4、高度为6的矩形。
  3. 创建了一个面积计算访问者。
  4. 圆形调用了面积访问者,输出圆的面积。
  5. 矩形也调用了面积访问者,输出矩形的面积。
Circle area: 78.54
Rectangle area: 24
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

甜航一直在

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

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

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

打赏作者

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

抵扣说明:

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

余额充值