架构
“架构”一词与建筑行业有着不可分割的关系,
在最初引入到软件行业中时,
是为了表达在编写计算机程序之前进行规划和设计的重要性。
IEEE给出了软件架构的标准定义。
Architecture:
The fundamental organization of a system embodied in its components, their relationships to each other, and to the environment, and the principles guiding its design and evolution.
维基百科中的描述也值得借鉴,
Software architecture refers to the high level structures of a software system, the discipline of creating such structures, and the documentation of these structures.
“架构”定义了软件系统中,各构成要素之间的关系与组织方式,
从而体现出系统的一种结构性特征。
细节
一个具体的软件,总是由各种细节组成,软件工程师也需要考虑细节问题。
因为实现一个具体功能的方式总是灵活的,
所以,在细节层面上会存在有多种多样的选择。
经常局限在细节上考虑问题,容易使人忽视全局性质。
我们致力于在局部上消除冗余,却未必会看到子系统之间的重复,
追求代码片段的可维护性,也未必会有利于系统整体的清晰易懂。
因此,为了保持良好的全局性质,在细节上就必定会有所损失。
结构性质对细节来说,与其说是指导方针,倒不如说是一种人为限制。
例如,在分层架构中,每一层必须是封闭和单向的,不允许跨层请求,
层次之间也必须隔离的,层内的变化不能影响到其它层。
这在某些场景下,可能会造成不便,但是如果随意的开放某个层次的访问权限,
整个项目就是紧耦合的,变得一团糟。
物理结构和逻辑结构
从数据结构的角度来看,
物理结构,是指数据的逻辑结构在计算机中的存储形式。
逻辑结构,是指数据对象中数据元素之间的相互关系。
考虑到软件项目,工程的物理结构,可以指相关文件的组织方式,
工程的逻辑结构,可以指相关概念之间的关系。
物理结构是重要的,它决定工程是如何存储和部署的,
逻辑结构也是重要的,它决定了项目的参与者们如何理解它。
从细节上来看,代码坏味是结构性欠佳的一种表现,
它们通常是更深层次灾难的根源。
数学结构
数学结构,是与概念相对应的数学模型。
例如,我们使用链表,栈和队列,来表示数据对象之间的线性关系,
我们使用monad来表示执行流程中所反映出来的一种自相似性,
使用进程代数作为并发系统的形式模型。
这些数学模型,有广泛的应用范围,但是也更加抽象,
增加了在工程中直接使用的难度。
因为软件需求通常是定制化的,所以即使两个系统有相同的数学结构,
在细节上,具体表现形式之间的差异,也可能是巨大的。
因此,洞悉数学结构,虽然可以帮助我们看到事物本质,
但是另一方面,也要谨防忽视产品之间差异性带来的危害。
复杂性
软件工程的目的在于控制复杂性,而不是增加复杂性。——Pamela Zave
对于不同利益相关者而言,他们眼中的软件系统必须是直观且容易理解的。
例如,4+1 architectural view model提供了一种软件架构的描述模型,
它从不同的视角,对系统进行专门的描述。
易知,开发者看来简单的事情,最终用户未必认可,反之亦然。
因此,复杂性是相对于人而言的,而不是系统本身。
复杂的细节,经过封装和信息隐藏,可能会表达一个直观的概念,
对细节的暴露程度不加管控,才是复杂的根源。
沟通与说明
知识是需要讲解的,信息的传递也需要沟通,
良好的设计,并不会自然而然的被人理解。
因此,设立流程和规范,不如促进人们加强沟通,
工程师们对前景和蓝图缺乏共识,才导致了系统整体结构的紊乱。
只有保持相同的愿景,在局部上才能有所折中,
让步总是出现在未来可以得到更多利益的时候。
此外,在说明怎样做的时候,很多人都忘记说明自己的意图和动机,
像法律条文一样教条性的陈述,只会使人敬而远之。
结语
软件作为一个整体,需要考虑的问题还有很多,
除了功能性需求之外,还有非功能性需求,
只有站在整体考虑问题,才能跳出程序员的范围,从商业角度看待软件项目。
反观日常工作中,我们坚持的种种原则,
可能都只是为了缓解强迫症的不安和焦虑罢了。(自嘲