数据结构与程序架构(二)

在上篇文章中,我们通过一个简单例子演示了从数据结构的角度来思考我们的程序架构的优势,然而,由于上一个例子过于简单,你可能会认为,这和我们(在架构设计时)常用的Callback机制有什么差别呢?事实上,它们之间是有差别的,Callback机制虽然也是将函数数据化的一种方法,但它关注的仍然是函数间的调用关系(即回调函数的接口反映的是框架程序要如何调用其子模块,以及子模块如何响应这个调用)。一旦回调函数的接口定下后,框架程序要如何调用,以及调用的顺序基本上是固定的,而且实现接口的模块通常也假定框架程序总是按我们预想的调用方法调用。然而,当我们的需求发生了变化,并且不得不修改(或增加)接口时,必然需要修改框架程序,而这种修改是极其容易引入一些bug的,而且往往也难以察觉,因为我们很难保证照顾到每一个修改的方方面面。另外Callback机制还有一个固有的缺陷,就是它容易导致递归的循环(我们在实现一些状态机时可能会经常遇到这种情况),这种循环调用不但使得我们的调试难度加大(因为程序的执行逻辑是否正确很难直观的检查出来),而且解决起来往往也很费力,甚至很可能需要修改我们的设计。

不难发现,以上这些(项目实践中会经常遇到的)问题正是因为我们在做架构设计时,只关注框架程序与子模块间的调用关系造成的,而要改进这些问题,就必须改变我们的设计思路,即从关注调用关系转变为关注子模块之间的组织结构,以及数据和/或信号(参见附注1)是如何在这种结构中传递的。在这种思路的引导下,当我们的需求改变了,以前我们是修改接口以及相关的调用逻辑,现在我们只需要修改传递的数据和/或信号内容,以及子模块间的组织结构(如果必要),而框架程序的处理逻辑完全不用变。

附注1:本文中的信号并非指操作系统的signal或event,而是指用于控制逻辑流的数据,你可以将它理解为windows的消息,但它们之间还是有一些微妙的差别,通过阅读本文,如果你能体会到其中的差别,说明你已正确理解了本文的主旨。

这种设计思想其实是借鉴了硬件工程师的程序设计方法,让我们来看看硬件工程师是如何设计程序的:

(图片来源:http://www.51hei.com/dianzi/304.html)

        图1:逻辑门符号图

上图是一组逻辑门的符号图(学过数理逻辑的朋友应该不会陌生),其中,每一个逻辑门就是一个处理单元(我们在做架构设计时,每个子模块也是一个处理单元),它接收1或2或多个输入信号,并产生一个输出信号,再来看看下面这个加法器的逻辑电路图:

(图片来源:http://www.elecfans.com/article/88/131/189/2009/2009032838767.html)

        图2:加法器电路图

不难发现图2的加法器就是由(3个)图1中的逻辑门按特定方式链接起来的一种结构(也叫拓扑),它的计算行为完全由这个结构和在其中传递的信号来控制。按同样方式,我们有减法器、乘法器、除法器(乃至于复杂的编解码器)等等,它们都是一种拓扑结构。现在你应该不难明白本文的主旨了吧,即模拟逻辑电路的方式来设计软件架构,这种架构可以改进我们之前所说的种种问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值