- 软件灵活性设计:如何避免陷入编程困境
- (美)克里斯·汉森等
- 2899字
- 2025-02-24 18:54:41
1.2 灵活的智能组件
大型系统是由许多较小的组件构成的,每个组件都对整体的功能有所贡献,要么直接提供该功能的一部分,要么与其他组件合作,按照系统架构师指定的模式相互连接以建立所需的功能。系统工程中的一个核心问题是允许建立组件之间相互连接的接口,以便将这些组件的功能组合起来,建立复合功能。
对于相对简单的系统来说,系统架构师可以为各种接口制定正式的规范,这些接口必须由需要互连的组件的实现者来满足。事实上,电子学的惊人成功是基于这样一个事实:制定这样的规范并满足它们是可行的。高频模拟设备是通过具有标准化阻抗特性的同轴电缆和标准化的一组连接器进行互连的(见[4])。一个元件的功能和它的接口行为通常只需要几个参数就可以指定(见[60])。在数字系统中就更清楚了:有信号含义的静态规范(数字抽象)、有信号时间的动态规范(见[126])、有元件形态因子的机械规范[5]。
不幸的是,随着系统复杂性的增加,这种先验的规范实施变得越来越困难。我们可以规定一个下棋的程序是合法的(即它不会作弊),但如何规定它能下一盘好棋呢?软件系统建立在大量定制的高度专业化的组件上,软件组件的个性化特性加剧了指定软件组件的难度。
相比之下,生物学在没有非常大规格(考虑到要解决的问题)的情况下构建了巨大且复杂的系统。我们身体里的每一个细胞都是单个受精卵的后代。所有的细胞都有完全相同的遗传基因(大约1GB ROM),包括皮肤细胞、神经元、肌肉细胞等。这些细胞自己组建起来,成为独立的组织、器官和器官系统。事实上,这1GB ROM规定了如何从大量容易发生故障的组件中建立极其复杂的机器(人类)。它规定了如何操作这些基本组件以及如何配置它们。它还规定了如何在各种恶劣的条件下可靠地操作这台复合机器,使其具有很长的寿命,以及如何保护这台机器不被吃掉。
如果软件组件变得更简单或更通用,它们的规格就会更简单。如果组件能够自适应周围的环境,其规格的精确度就不那么重要了。生物系统利用以上两种策略来建立强大的复杂生物体。不同的是,生物细胞是动态可配置的,并且能够使自己适应环境。这是可能的,因为细胞的分化和特化方式取决于环境。但是软件通常没有这种能力,因此必须通过手动方式来调节每个部分。生物学是怎么工作的呢?
想想另一个例子。我们知道,大脑的各个组成部分是由巨大的神经元连接在一起的,而基因组中没有足够的信息来详细说明这种相互连接。大脑的各个部分很可能在互享重要经验的基础上,学会了相互交流[6]。因此,接口必须是自我配置的,基于一些一致性规则、来自环境的信息和广泛的探索行为。这在启动阶段是相当昂贵的(成长为一个具有正常机能的人类需要数年时间),但它提供了一种迄今为止在工程实体中没有发现过的鲁棒性。
一种观点认为,生物系统使用的是诱导性而非强制性的背景信号[7]。没有一个主指挥者规定每个部分必须做什么,相反,各部分根据其周围环境选择它们的角色。细胞的行为不在信号中编码,它们在基因组中单独表达。信号的组合只是使一些行为得以实现,而使另一些行为失效。这种微弱的联系允许在不修改定义位置机制的情况下,在不同位置上实施被启用行为的变化。因此,以这种方式组织的系统是可进化的,因为它们可以容纳某些区域的适应性变化而不改变其他区域的子系统行为。
传统上,软件系统是围绕着命令式模型建立的,在这个模型中,有一个内置于结构中的控制层。各个部分被认为是沉默的工人,做他们被告知的事情。这让适应性变得非常困难,因为所有的变化都必须反映在整个控制结构中。在社会系统中,我们很清楚严格的权力结构和集中指挥所带来的问题,但软件设计却仍遵循这种有缺陷的模式。我们可以做得更好:让各部分更聪明,各自负责以简化适应性,因为只有那些直接接受变化影响的部分需要回应。
形体构造
所有脊椎动物的形体构造基本相同,但细节上的差异却很大。事实上,所有具有双侧对称性的动物都有同源基因,如Hox复合体。这种基因在发育中的动物体内产生一个近似的坐标系统,将发育中的动物分成不同的区域[8],为细胞的分化提供区域背景。通过与近邻接触而获得的信息中会产生更多的背景资料,从细胞遗传程序中可能的行为里选择特定的行为[9],甚至构造的方法也是一样的——导管腺、肺和肾等器官的形态形成是基于一个胚胎学的技巧,当上皮细胞内陷至间充质时,会自动[10]产生由分化间充质包围的盲端小管组成的分支迷宫[11]。
好的工程也有类似的考量(即好的设计是模块化的),比如无线电接收器的设计。目前有七种已被发现的重要的“形体构造”,如直接转换、TRF(调谐无线电频率)和超外差式接收器。每一种都有一系列由Hox复合体的工程等价物定义的位置,从天线到输出换能器的系统模式。例如,超外差式接收器(见图1.1)有一套标准的位置(从头到尾)。

图1.1 由Edwin Armstrong少校在1918年发明的超外差式接收器,至今仍然是无线电接收器的主要“形体构造”
本构造中所确定的模块都可以分解成其他模块(如振荡器、混频器、滤波器和放大器等),直至各个电子元件。此外,每个模块都可以通过许多可能的方式进行实例化:射频部分可能只是一个滤波器,也可能是一个复杂的滤波器和放大器组合。事实上,在模拟电视接收器中,混频器的输出部分被视频链处理为AM,另一部分被处理为FM以产生音频。而有些部分(如转换器)可能会被递归说明(就像Hox复合体的部分被重复一样)以获得多转换接收器。
在生物系统中,这种隔间结构在更高的组织层次上也得到了支持。有一些组织专门成为隔间的边界,并有导管将它们相互连接。器官被这种组织所包围,并由导管相互连接,整个结构被包装成体腔,是高等生物中排列着特殊组织的腔体。
类似的技术也可以用在软件设计中。软件主体只是一个包装器,它将部分指定的组件组合在一起。这是一类组合器(combinator):将子部分组合在一起成为一个更大的部分。通过创建组合器语言(combinator languages),其中的组件和复合体都有相同的接口规范。在组合器语言中,有可能从少量组合与搭配的组件中建立任意大的组合。自相似结构使组合程序变得容易。在第2章将开始构建基于组合器的软件,这个主题将贯穿本书的所有内容。
类似的事情也可以用领域专用语言来做。通过对领域进行抽象,可以在不同的领域使用相同的领域独立代码。例如,在任何与数字方面相关的领域,微积分都是有用的;另一个例子是第4章中的模式匹配,它可以应用于各种领域。
生物学机制是普遍的,因为原则上每个组件都可以作为任何其他组件。模拟电子元件在这个意义上并不通用,因为它们不能根据本地信号来适应周围的环境。但是存在一些通用的电子构件(例如,带有模拟接口的可编程计算机)[12]。对于低频应用,人们可以用这种构件创建模拟系统。如果每个构件都有成为系统中任何构件所需的全部代码,但通过与相邻构件的相互作用而被专门化,或者在组件中还有额外的非专用“干细胞”,那么可以设想建立自我重新配置和自我修复的模拟系统。但现在仍然单独设计和建造这些组件。
在编程中,有一个通用元素的概念——评估器(evaluator)。评估器接受对某些要执行的计算的描述以及该计算的输入。如果将输入传递给实现所需计算的定制组件,它将提供相应的输出。在计算方面,我们有机会追求胚胎发育的强大灵活策略。本书将在第5章中详细阐述评估器技术的使用。