.. Kenneth Lee 版权所有 2018-2020
:Authors: Kenneth Lee :Version: 1.0
有无之道——一个新的软件架构定义
我一直在找寻方法想要定义什么是软件架构,有很长一段时间我都喜欢IEEE的定义,也就 是把软件架构定义为构成产品的一组组件和它们之间/它们和外部的关系。
但当我写架构设计文档的时候,我发现我常常需要写超过这个范围的东西,才能控制得住 整个开发过程。比如,版本,特定的策略等。
所以在那个定义之外,我还需要加上这句话:“软件架构还包括基于这个组件和关系的定义 之上实施的一组策略”。
所以最后就变成那个很玄的定义了:“架构设计是架构师的设计”。
但所有这些定义,用起来感觉还是有点不对的地方。引入道德经的名称空间后,我明白了 ,它们都有一个严重的问题:就是会给人一个错误的引导,觉得架构设计是一种“有”,而 忘掉了“无”,架构不是架构师的设计,而是整个产品本身,是对其他工程师乃至整个生态 的设计。架构设计是设计全体,而不是设计本身,所以所有关于架构设计的定义都有意无 意地忽略了这一点,所以讨论起来很容易就走到一个错误的路径上去,越用力越错。我们 需要有一个更好的定义,把整个架构设计的用力方向稳住。
总的来说,架构设计的设计行为,和设计目标是不对应的。架构设计的一切“设计”都是为 了导致参与这个软件的所有力量,都按设计的目标发展,而不是设计本身向设计目标发展 。设计本身越向着目标去,整个系统就离目标越远。这就是架构设计的“有无之道”。架构 设计是通过一系列的“有”的行为,导致“无”(架构设计没有做的部分),向有利于目标的 方向去发展。
所以架构设计规划的设计,是为了让生态的其他伙伴进来补充“架构师没有设计的部分”, 架构设计要看到某些工作是有利益的,从而让出这个利益,让其他力量可以补充进来,从 而形成更大的利益空间,然后用那个新的利益空间,吸引更大的其他力量参与进来补充整 个软件的开发。
所以架构师写的代码,是为了让后续的工程师加入写作的时候,可以把它们统统删除掉, 替换成更好的代码,但这些“更好的代码”恰恰落在架构师的设计范围内。而不是架构师一 开始就写出别人不可替换的代码。
所以架构师设置了架构和商用分支,不是为了让自己或者自己的团队“占有”这个分支,从 而取得比别人更大的优势,而是利用这些分支进行利益分配,让整个软件的开发力量“各归 其根”,有一个可以活下去的地方,从而发挥出整体力量。
所以我构思了另一个定义:
| 软件架构是定义软件如何成长起来直到达成其目标的过程(道),
| 然后在这个过程上创建一系列的概念(名),
| 使第三方力量在这些名上进行争抢,从而让“道”强化,
| 最终使开发过程(的事实)顺着这条“道”一直通向目标的过程。
在这个过程中,未知的东西会变成知,所以,软件架构不是一个稳定的过程,而是一个持 续变更的过程。
我为这个定义画一幅图:
.. figure:: _static/架构目标树.jpg
架构设计的定义方法,其中黑线是定义,蓝线是实际在名上的争议和对未知限制的妥协, 而红色是实际的发展路向
也就是说,架构设计是设计一组不成熟的概念,铺设在预想的成功路径上,让第三方力量 在名上左右用力,确定最优位置,最后靠这些力量把实际的路径打通。
这个定义最大的问题是,它似乎是万能的,所有事情都可以这样定义,没有突出软件的特 点。所以,它需要有一组软件实践来作为定义这个“道”的材料,这些材料我认为主要包括 :
演示代码:演示代码是最直接的说明一个架构的构想的方法,特别是在今天有大量的 Boiler Plate的情况下,构造一个演示代码变得越来越容易,既然如果,“可以运行的 代码重于千万个文档”,架构师通过演示代码,引导合入过程,在一定程度上就可以完 成对系统的引导。关键在于,架构师不能指望自己写“好代码”,但也不能指望自己写“ 坏代码”(如果这个代码会错误引导架构师的意思),这个本质要从反馈上来决定。这 种方法也不是万能的,是架构师和团队互动而形成的。这种方法一般用于在构造核心生 态圈的过程中。
IEEE1471定义的模块和接口表述方法:这是一般人最常用的描述系统架构的方法,通常 用于定义名称空间。定义模块的名称,角色,接口的名称和地位,核心目的是统一整个 生态的工作语言。这个方法唯一要注意的是:它只是架构设计的基础,而不是架构设计 本身。
版本:版本是利益分配的基本方法。在架构发展的过程中,外行只能通过“能运行的程 序”来判断你的工作好不好,是否有进展。投资方也只能通过某个版本带回来了多少收 益来判断是否可以继续支持整个工作是否可以继续下去。负责销售版本的团队很容易获 得更多的名,但他们并非支持整个体系得以发展的原因。架构师必须有能力平衡这里的 利益平衡。一般来说,我们需要管理两种版本:架构版本-没有收益的版本,但它是所 有其他版本的根,用于收集面向未来的设计;战地版本-有直接收益的版本,为眼前的 商业利益服务,它有生命周期,当生命周期结束,基于新的架构版本的战地版本会重新 被开发出来。版本意味着开发成本,很多投资者会希望用一个版本解决所有问题,但具 体用多少个版本,这是具体的需求和技术问题决定的,不以人的希望所左右,所以,这 是架构师和投资方的博弈问题。
工程方法(比如TDD等):工程方法是名称空间的另一个角度,相同的工程方法可以有 效提高团队间的沟通。但工程方法更多时候是一种文化,架构师常常有一种误解,觉得 自己可以改变整个开发团队的文化,而更多时候,其实是架构师必须顺应开发团队的文 化。这是很多空降的架构师在新的岗位上发挥不出来的原因(这常常还不是架构师的错 ,而是管理团队错误的期望导致的),文化不能被短时间改变,君子终日行不离辎重, 架构师进行设计,也不能离开“整个团队本来在什么位置”。
针对目标的逻辑链:这个补充其他部分,对于我们为什么需要执行某个行为的具体讨论 。这是架构设计文档的主体,但并没有什么确定的方法,这和架构设计的层次,具体的 现实都密切相关。
最后补充说明一下:很多人容易发生的误会的是对架构设计的规模的认识:这里谈的架构 设计,是指卷入人员在100人以上,生命周期超过5年的软件的设计。这样的软件在整个生 命周期控制过程中,架构师的直接控制十分有限,架构师甚至没有能力查看或者理解整个 设计中十分之一的部分,架构师具体控制什么的问题变得非常突出,这种,我们才认为有“ 架构设计”这种说法。否则我们认为只是“系统设计”,系统设计只是关注一轮组合中实现必 须的功能,生命周期在一年以下。
但很小的模块也可以有构架考量,因为每个模块都是活在一个更大的系统中的,看到大系 统的行为特征,小系统的认识就可以更加准确。
todo:先写一个基本定义,其他东西等我想明白了再慢慢补充。