软件的复杂度的产生原因及控制原则
软件复杂度产生的原因
沟通问题
- 用户对某些需求只存在一个概念,对具体要实现成一个什么样子没有想法。另外用户与开发者思维的不一致,用户也很难将他的意思很清晰的传达给开发者。
- 因为沟通不畅、客户需求不清晰等多种因素会带来需求变更和修改。如果不能很好地控制这种变更,可能会因为多次修改导致业务逻辑纠缠不清,系统也开始变得不可维护。
管理困难
- 通常团队人员完成的功能也是按照模块化或层次进行划分,每个人完成的模块都是系统的一个相对较小的部分,对整个系统是无法做到完全了解。
- 团队内部成员无法做到相互了解,团队越大需要团队成员花费越多的时间来维护需求一致性。
- 人越多沟通越复杂,越难协调,多地协同更为困难。
- 归根到底,管理的困难是源于维护软件的一致性和完整性。
编写规范
- 在开发早期阶段,可能制定了一系列的设计及开发规则,但是由于开发者不是由一个人构成,那么对设计及实现上各有不同,出现了灵活性的体现。但正是这种灵活性的体现,可能会导致后期的很多问题。
- 缺乏统一编码风格,也没有统一的概念能够将不同的部分组织在一起,导致程序错综复杂和不可维护。
软件规模
- 软件的需求决定了系统的规模。当需求呈现线性增长趋势时,为了实现这些功能,软件规模也会线性增长。由于需求不可能做到完全独立,导致出现相互影响相互依赖的关系,修改一处就会牵一发而动全身。
软件结构(技术)
- 在很多情况下,我们需要满足安全、高性能、高并发、高可用性的需求,就需要在系统中引入防火墙、访问控制、缓存、并行处理、CDN、异步消息以及支持分区的可伸缩结构。如果我们需要支持对海量数据的高效分析,就要考虑海量数据该如何分布存储并有效地利用各个节点的内存与CPU资源运算。
- 一方面增加了系统架构的复杂性及更多资源满足安全、高性能、高并发、高可用性的需求,另一方面也因为架构复杂化及引入了更多的资源,使得系统的高可用面临挑战,并增加了维护数据一致性的难度。
控制复杂度的原则
KISS(Keep it Simple Stupid)原则
1)单一职责:每个程序只做一件事情,通过添加新特性而非修改旧系统去应对新需求
2)统一接口:每个程序的输入输出都是统一格式,A程序的输出可以直接作为B程序的输入,以支持程序之间的自由组合
保持结构的清晰与一致
- 整洁架构:无需依赖于任何基础设施就可以对它进行测试,只需通过边界对象发送和接收对应的数据结构即可
– 遵循“关注点分离”架构原则(思想)
– 识别整个架构不同视角以及不同抽象层次的关注点,并为这些关注点划分不同层次的边界,从而使得整个架构变得更为清晰,以减少不必要的耦合。
– 合理地进行职责分配,良好的封装与抽象,并在约束的指导下为架构建立一致的风格 - 稳定依赖原则:整洁架构遵循稳定依赖原则,不对变化或易于变化的事物形成依赖
拥抱变化
- 开发过程中,应尽可能做到敏捷与快速迭代,以此来抵消变化带来的影响;
- 在架构设计层面,需要分析哪些架构质量属性与变化有关,尽量做到可进化,可扩展,可定制。
可进化
- 实现:划分设计单元的边界
- 目的:确定每个设计单元应该履行的职责以及需要与其他设计单元协作的接口。
- 原因:每个设计单元都有自己的边界,边界内的实现细节不会影响到外部的其他设计单元,我们就可以非常容易地替换单元内部的实现细节,保证了它们的可进化性。
可扩展
- 要点:识别软件系统中的变化点。
- 变化点:业务规则、算法策略、外部服务、硬件支持、命令请求、协议标准、数据格式、业务流程、系统配置、界面表现。
- 核心: 封装、隐藏细节、隔离变化、降低耦合
可定制
- 引入元数据支持系统的可定制。
- 插件模式:提供统一的插件接口,使得用户可以在系统之外按照指定接口编写插件来扩展定制化的功能。