C语言实现行为型模式:策略、模板方法、观察者
导读:行为型设计模式关注对象之间的通信与职责分配。本文介绍策略、模板方法、观察者、迭代器、责任链、命令六种模式,全部代码可直接编译运行。
一、原理简析
行为型模式关注对象之间的通信与职责分配,让对象之间的交互更加灵活和可维护。
六种模式对比:
| 模式 | 核心作用 | 解决问题 |
|---|---|---|
| 策略 | 算法封装切换 | 消除if-else分支 |
| 模板方法 | 算法骨架 | 部分步骤可变 |
| 观察者 | 一对多通知 | 状态同步 |
| 迭代器 | 顺序访问 | 遍历封装 |
| 责任链 | 链式处理 | 请求传递 |
| 命令 | 请求封装 | 解耦发送者和接收者 |
二、实操步骤
2.1 策略模式:算法封装切换
#include <stdio.h>
typedef struct Strategy {
int (*Calc)(int, int);
} Strategy;
int AddCalc(int a, int b) { return a + b; }
int SubCalc(int a, int b) { return a - b; }
int MulCalc(int a, int b) { return a * b; }
typedef struct Context {
Strategy *st;
int (*DoCalc)(struct Context*, int, int);
} Context;
int DoCalc(Context* c, int a, int b) {
return c->st->Calc(a, b);
}
int main(void) {
Strategy add = {AddCalc};
Strategy sub = {SubCalc};
Context ctx = {0};
ctx.DoCalc = DoCalc;
ctx.st = &add;
printf("10 + 5 = %d\n", ctx.DoCalc(&ctx, 10, 5));
ctx.st = ⊂
printf("10 - 5 = %d\n", ctx.DoCalc(&ctx, 10, 5));
return 0;
}
2.2 模板方法模式:算法骨架
#include <stdio.h>
typedef struct Template {
void (*Step1)(void);
void (*Step2)(void);
void (*Run)(struct Template*);
} Template;
void TemplateRun(Template* t) {
printf("流程开始\n");
t->Step1();
t->Step2();
printf("流程结束\n");
}
void Step1A(void) { printf("步骤1A:初始化\n"); }
void Step2A(void) { printf("步骤2A:处理\n"); }
int main(void) {
Template A = {Step1A, Step2A, TemplateRun};
A.Run(&A);
return 0;
}
2.3 观察者模式:一对多通知
#include <stdio.h>
#include <string.h>
#define MAX_OBS 5
typedef struct Observer Observer;
typedef struct Subject {
char state[20];
Observer* obs[MAX_OBS];
int count;
void (*Attach)(struct Subject*, Observer*);
void (*Notify)(struct Subject*);
} Subject;
struct Observer {
char name[20];
void (*Update)(Observer*, const char*);
};
void SubjectAttach(Subject* s, Observer* o) {
s->obs[s->count++] = o;
}
void SubjectNotify(Subject* s) {
printf("发布者:状态 [%s]\n", s->state);
for(int i=0; i<s->count; i++) {
s->obs[i]->Update(s->obs[i], s->state);
}
}
void ObserverUpdate(Observer* o, const char* state) {
printf(" [%s] 收到:%s\n", o->name, state);
}
三、对比表格
|
策略模式 算法切换 | 函数指针数组 | 消除分支 |
| ↓ |
|
模板方法 算法骨架 | 继承+钩子 | 步骤可变 |
| ↓ |
|
观察者模式 一对多 | 注册回调 | 状态同步 |
四、核心流程图
flowchart TB
subgraph 行为型上["行为型模式(上)"]
A["策略模式<br/>算法切换"]
B["模板方法<br/>骨架固定"]
C["观察者模式<br/>一对多通知"]
D["迭代器模式<br/>顺序访问"]
E["责任链模式<br/>链式处理"]
F["命令模式<br/>请求封装"]
end
A --> B --> C --> D --> E --> F
五、常见问题解决
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 策略vs状态 | 目的混淆 | 策略客户选,状态自动切 |
| 观察者内存泄漏 | 未注销观察者 | 记得调用Detach |
| 责任链死循环 | next指针闭环 | 检查指针设置 |
六、总结
本文介绍了6种行为型设计模式。行为型模式关注对象间的通信,让系统更加灵活和解耦。
来自 linuxros.cn · linuxROS
核心要点:
- 策略:算法可切换,消除if-else
- 模板方法:骨架固定,步骤可变
- 观察者:状态变化自动通知
- 迭代器:遍历封装,不暴露内部
- 责任链:请求沿链传递
- 命令:请求封装,解耦发送接收
下期预告:《C语言实现行为型模式:备忘录、状态、访问者、中介者、解释器》—— 剩余5种行为型模式。
关注公众号:linuxros
回复「设计模式」,获取完整23种设计模式C语言实现源码