在面向对象设计模式中,存在代理模式(Proxy Pattern)和委托模式(Delegation Pattern),二者有很大相似性,但在类的实现上存在少许不同。
而在C语言中,由于天生没有类的概念,因此可以认为这两种模式是一样的。其目的都是为了调用方提供一种动态且一致的接口。
不管是代理还是委托,特点都是调用方自己不做事,把要做的事交给代理去做。
问题
某个产品需要两种指令格式,并需要能够随时切换到另一种格式。
通常实现
因为需要软件运行期间动态切换,所以需要实现两种格式的处理函数,并记录当前使用哪种模式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| int mode = 0;
void cmd_mode_0_proc(char *buf) { }
void cmd_mode_1_proc(char *buf) { }
void cmd_proc(void) { if (mode == 0) { cmd_mode_0_proc(buf); } else { cmd_mode_1_proc(buf); } }
void change_mode(int value) { mode = value; }
|
代理实现
将处理函数封装起来,给调用方统一接口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| typedef struct { void (*proc)(char *buf); } cmd_proxy_t;
cmd_proxy_t proxy;
void cmd_mode_0_proc(char *buf) { }
void cmd_mode_1_proc(char *buf) { }
void change_mode(int value) { if (value == 0) { proxy.proc = cmd_mode_0_proc; } else { proxy.proc = cmd_mode_1_proc; } }
void cmd_proc(void) { proxy.proc(buf); }
|
代理模式的实现将处理函数的选择从调用方移出。对调用方来说,简化了处理流程,只要交给代理去完成即可。而具体应该调用哪种处理流程是由代理决定的。
什么时候用代理模式呢?就是上面它的特点:动态和统一接口。软件需要在运行时动态修改其行为,而对于调用方并不希望关心其行为的变化,就可以交由代理来处理了。