前言:
最近在学习《Unix编程艺术》。以前粗略的翻过,以为是介绍unix工具的。现在认真的看了下,原来是介绍设计原则的。它的核心就是第一章介绍的unix的哲学以及17个设计原则,而后面的内容就是围绕它来展开的。以前说过,要学习适合自己的资料,而判断是否适合的一个方法就是看你是否能够读得下去。我对这本书有一种相见恨晚的感觉。推荐有4~6年工作经验的朋友可以读一下。
正题:
作者在介绍Unix设计原则时,其中有一条为“表示原则:把知识叠入数据以求逻辑质朴而健壮”。结合之前自己的一些经验,我对这个原则很有共鸣,所以先学习了数据驱动编程相关的内容,这里和大家分享出来和大家一起讨论。
数据驱动编程的核心
数据驱动编程的核心出发点是相对于程序逻辑,人类更擅长于处理数据。数据比程序逻辑更容易驾驭,所以我们应该尽可能的将设计的复杂度从程序代码转移至数据。
真的是这样吗?让我们来看一个示例。
假设有一个程序,需要处理其他程序发送的消息,消息类型是字符串,每个消息都需要一个函数进行处理。第一印象,我们可能会这样处理:
- void msg_proc(const char *msg_type, const char *msg_buf)
- {
- if (0 == strcmp(msg_type, "inivite"))
- {
- inivite_fun(msg_buf);
- }
- else if (0 == strcmp(msg_type, "tring_100"))
- {
- tring_fun(msg_buf);
- }
- else if (0 == strcmp(msg_type, "ring_180"))
- {
- ring_180_fun(msg_buf);
- }
- else if (0 == strcmp(msg_type, "ring_181"))
- {
- ring_181_fun(msg_buf);
- }
- else if (0 == strcmp(msg_type, "ring_182"))
- {
- ring_182_fun(msg_buf);
- }
- else if (0 == strcmp(msg_type, "ring_183"))
- {
- ring_183_fun(msg_buf);
- }
- else if (0 == strcmp(msg_type, "ok_200"))
- {
- ok_200_fun(msg_buf);
- }
-
- 。。。。。。
- else if (0 == strcmp(msg_type, "fail_486"))
- {
- fail_486_fun(msg_buf);
- }
- else
- {
- log("未识别的消息类型%s\n", msg_type);
- }
- }
上面的消息类型取自sip协议(不完全相同,sip协议借鉴了http协议),消息类型可能还会增加。看着常常的流程可能有点累,检测一下中间某个消息有没有处理也比较费劲,而且,没增加一个消息,就要增加一个流程分支。
按照数据驱动编程的思路,可能会这样设计:
- typedef void (*SIP_MSG_FUN)(const char *);
-
- typedef struct __msg_fun_st
- {
- const char *msg_type;
- SIP_MSG_FUN fun_ptr;
- }msg_fun_st;
-
- msg_fun_st msg_flow[] =
- {
- {"inivite", inivite_fun},
- {"tring_100", tring_fun},
- {"ring_180", ring_180_fun},
- {"ring_181", ring_181_fun},
- {"ring_182", ring_182_fun},
- {"ring_183", ring_183_fun},
- {"ok_200", ok_200_fun},
-
- 。。。。。。
- {"fail_486", fail_486_fun}
- };
-
- void msg_proc(const char *msg_type, const char *msg_buf)
- {
- int type_num = sizeof(msg_flow) / sizeof(msg_fun_st);
- int i = 0;
-
- for (i = 0; i < type_num; i++)
- {
- if (0 == strcmp(msg_flow[i].msg_type, msg_type))
- {
- msg_flow[i].fun_ptr(msg_buf);
- return ;
- }
- }
- log("未识别的消息类型%s\n", msg_type);
- }