一、背景

上一篇重点讲述了软件复杂度的由来和现象,以及不同视角下的复杂度是怎么呈现的,本篇文章将从更细致的方面来阐述形成复杂度的一些指标数据,并按不同维度进行区分。
这么做的一个原因就是希望通过本篇文章让软件复杂度更具象,让软件开发者更直白全面的感受复杂度。

二、复杂度的因素有哪些

这里我们从软件开发的整个生命周期来看复杂度在这个生命周期中具体与哪些因素有关。

2.1 需求调研阶段

2.1.1 需求与政策环境

很多复杂的需求尤其与政策环境有关,有些行业政策不允许,那么想做这块业务就会复杂,即使克服了相关技术挑战,仍然无法获取用户。
所以这里我们可以看到基于政策的导向,其实在复杂度的体现就是,政策支持,政策禁止,政策要求变更等。

2.1.2 需求与技术开发水平

很多时候我们异想天开的需求,在未来或许会实现,但是在当下,因为技术和生产力等因素,根本无法实现,比如控制卫星登月,火箭发射等等这些在计算机没有出现之前基本不可能实现。所以当我们提出了一些现实生活中的需求之后,怎么用技术开发实现就是一个复杂度的体现。从技术的角度来说,软件开发涉及到开发语言,开发环境,需要依赖的软件工具包和网络等。另外一方面也跟硬件有关,比如服务器,磁盘和内存CPU等。

2.1.3 需求调研落地

不同公司不同行业对于产品经理这个职业来说可有可无。那么在需求调研落地的时候就需要用文档和人来阐述需求内容,描述需求的复杂度等。在技术开发这边也会根据制定的方案实现需求。所以需求调研落地的复杂度体现在如何客观的呈现需求,如何把需求相关的干系人和一些非功能性需求讲明白。所以有时候复杂度不止是在代码工程里,也在文档中。

2.2 需求开发阶段

2.2.1 开发与测试过程

在开发阶段和测试阶段仍然存在一些复杂度的相关因素,比如bug。比如需求变化导致的代码返工,另外一方面就是对于开发技术和开发使用工具的应用,不同技术栈和实现方案对于需求的匹配度和交付效率都不一样,所以开发和测试过程也严重依赖技术和需求两个维度。

2.2.2 开发人员与团队分工

软件开发有个很特别的现象,就是一个比较复杂的软件可能是一个人完成的,不过在建筑等领域基本不可能。话说回来,当一个软件需要团队开发的时候,我们可以看到因为人的因素会产生一些复杂度,比如团队成员的开发水平,团队的开发方向,跨职能地域的团队配合等等。看上去与复杂度没有什么关系,但是实际上我们会因为这些原因导致软件研发产生一些失败的结果。当然团队沟通交流也是一个重要的复杂度因素。

2.2.3 软件工程与架构

很多讨论软件工程复杂度的话题或者书籍都局限于软件工程和代码模块本身,包括架构和耦合关系。但是本系列要讨论的是整个软件工程开发范围内的复杂度问题,范围比较广。所以对于复杂度的讨论也离不开对软件工程架构的复杂度分析。
这里将不再通过耦合,代码关联等角度来用数学公式去探究复杂度,而是通过统计的方法来看软件工程模块的复杂度。可以统计的内容包括代码行数,代码文件数,方法数,模块数,依赖的模块(组件,下游服务)数,依赖的软件(中间件,开发软件,容器软件)数,API接口数,应用架构风格的组成要素数量等。也就是说通过这些可以明显量化的指标来衡量软件工程的复杂度也可以是相对客观的。所以可以结合市面上在软件工程与架构角度的其他维度的复杂度分析方法来帮助更好的衡量复杂度。
前两天推荐的书籍《软件架构-架构模式,特征及实践指南》中有关于不同软件架构风格的衡量表,所以选了不同的架构模式就会产生对应的架构层面的复杂度。

2.3 需求交付阶段

在需求交付阶段,为了让系统正常发布,不同领域和规模的软件要求在发布环节依赖的工具和流程也不一样,所以复杂度有时候也体现在交付环节,尤其是大型分布式网站。现在BAAS,IAAS,SAAS,PAAS等概念也比较火,在需求交付环节所体现的复杂度也不一样。

2.4 需求运维阶段

需求运维阶段也包括正常的软件维护,当系统下线的那一天,复杂度在这个系统中会消失,但是更全局的复杂度或许还在。我相信在数字化转型的这个阶段里会有更多的遗留系统受到挑战,上云还是购买服务等技术决策都会在需求运维阶段得到讨论。当然也有自己独立维护,慢慢迭代的场景。所以需求运维阶段其复杂度看上去是相对稳定的,如果有一些其他变化,比如人员更换,软件底层更换等等都将对复杂度产生影响。
另外一些在需求运维阶段可以量化的复杂度因素有维护人员数量,更改一个功能或者修复一个bug需要多长时间,需要多少机器等硬件资源。所以从这些量化指标来看的话似乎与工程效率或者研发效能有关,但是实际上这是复杂度的体现。关于复杂度与研发效能的关系等后面会专门讨论。
很多人在维护遗留系统的时候都在抱怨,或者举步维艰。一方面是没有用好的方法论来处理遗留系统,另外一方面是其复杂度对于维护者来说经常变化。这样的话要耗费精力对抗复杂度从而达到目标,就有种想推倒重来的冲动。

2.5 复杂度因素思维导图

三、复杂度的量化维度

关于复杂度的量化维度我也思考了很久,因为导致复杂的因素太多了,每个因素都是从不同领域出现的,他们之间有相互的关联,但是需要总结一下有哪些复杂维度,这样的话会更容易明白整个大型系统的复杂度信息,也方便我们度量。
这里我借用了算法中经常讲的两个统一语言:时间复杂度和空间复杂度。相对来说这里对于整体复杂度而言其含义指的是整个软件在时间和空间的两个维度的复杂度。当然我们衡量软件的复杂度也跟企业效益,利益有关,有时候我们需要考虑到成本的因素,所以这里也单独列了一下成本复杂度。当然在一定程度上成本复杂度的因素可以转换为时间或者空间复杂度。把成本复杂度单独列出来我们可以将一些我们看不到但是却很重要的复杂因素归为此类。

3.1 时间复杂度

这里的时间复杂度总体上体现在软件研发的生命周期里,一个软件研发的生命周期越长可能就越复杂。或者说在一个需求里,对于程序员来说是一个很简单的改动,但是需求梳理和发布都需要很长的时间,那么复杂度也会提高。所以很多时候我们面对不同难度的需求就会做不同难度的方案,有时候就是简单的bugfix。那这样的话时间复杂度就很明显的降低了。
当然还有另外一些因素也是归属于时间复杂度上面,比如我们做方案的时间,开会评审测试用例联调的时间。又或者说需求做着做着换方向了,不做了,暂停了等等。其花费的时间按不同因素来看就是整个软件系统的复杂度的体现。

3.2 空间复杂度

空间复杂度这里也不仅仅是代表着服务器的数量,服务器的配置,我说的这个空间复杂度的含义可能广泛的多,包括团队人数,跨地域的团队数量,更多的是指软件系统的一些规模指标。从整个软件研发的生命周期来看,空间复杂度越高那么整个软件系统的复杂度也就越高,比如从软件内部来看,一个电商网站的正常运行,背后不仅仅是一些硬件和人上的支持,也包括软件本身的相互支持,软件组件之间也有关联关系,这使得整个软件系统从业务和技术的角度来看复杂度是很高的。说白了老板让仿造淘宝整个网站的需求,为什么程序员感到尴尬,就是因为及其复杂,很多淘宝中用到的技术是靠团队的力量和跨团队的协作完成的,一个人基本不太可能完成整个淘宝系统的全部系统功能。

3.3 成本复杂度

现在我们讨论一下另外一个关于复杂度的维度,很多时候为什么企业会招大量的程序员,就是因为投入产出比是合适的,雇佣性价比更高的程序员投入产出比也越高,对于软件系统的研发成本也有帮助。软件系统一旦做出来提供服务之后,产生了更好的效益才能为企业提供利润,程序员的工资也越高。
我们看一下另外的的一个因素,比如政策方面,如果政策允许或者不允许,在软件设计方面就会产生一些不同的复杂度,尤其是一些涉及到民生和安全领域的系统。如果是新系统的话那么政策方面可能不会对其产生影响,但是已经运行的系统因为政策因素而调整的话,复杂度就会变化。
其他的因素诸如软件专利授权,技术授权等也算在成本复杂度中。下面会给出相对详细的复杂度量化维度思维导图。

3.4 总结

3.4.1 复杂度衡量尺度

上面的三个维度基本讲清楚了复杂度 的分类,但是我们现在还没有为复杂度找到一个相对通用或者统一的衡量标准。如果极端点看的话,成本复杂度可以拆分到时间和空间复杂度。空间复杂度在一定程度上可以转换为时间复杂度。也就是说我们可以把时间当作一个可能的衡量尺度。那么,是不是可以认为做一个软件用到的时间有多长其复杂度就可以用时间来表示。我觉得一定程度下是可以的。所以可以灵活运用时间标尺来衡量复杂度。
另外如果拆分开来分别看三个维度的复杂度的衡量标尺的话,我觉得可以是时间,数量(规模),和金钱。
那么很多时候我们可能更关注时间,如何更好的通过时间来评估复杂度呢,这里可以将整个软件系统的生命周期当作一个比较大的时间,在不同的时间段里可以按小时为最小单位,天,周,月。来评估其阶段性的复杂度。

3.4.2 复杂度量化维度思维导图

四、复杂度的特征

通过上面的讨论分析我们可以感受到复杂度其实有一些比较隐秘的性质,当然我也不是数学家或者比较厉害的软件工程领域专家,这里不对复杂度本身做概念定义,所以在这一小节中就单讨论一下复杂度的一些性质或者特征,如果有哪位看到这篇文章觉得不合适的话,欢迎交流指正。

3.1 动态性

最近一年加了很多微信群,也跟不同的网友和同事讨论过复杂度的问题,关于复杂度的话其明显的一个特征就是动态性,也有人觉得复杂度是动态守恒的,为什么这么说呢,因为复杂度有其客观的一面也有主观的一面,所以叫动态守恒也不是没有道理。

3.2 脆弱性

软件复杂度的脆弱性是指软件本身可能随时被替代,那这样的话软件复杂度就无从谈起。因为业务下线,因为更换软件等原因我们研究的软件对象则失去了焦点,对应的复杂度也就消失了。不过也体现了整个需求的变化,只是映射到不同软件组件或者软件系统中从需求的层面来说复杂度还在。

3.3 传递性

在数学加法上有个定律叫交换律,就是a+b=b+a。所以这里我们在衡量一个复杂度因素的时候往往会准备替代或者更改另外的复杂度,但是带来的问题就是会使其他复杂度因素提高。一个很简单的例子就是过度设计,或者提前优化,这么做看上去是好的,面向未来编程,但是实际上系统的稳定性要求比较高的情况下这么做很容易出问题。

3.4 相关性(等价替换)

从3.3所表现的特征来看,我们在简化复杂度的时候可以通过相关性来进行一些相对精确的度量,比如在迭代需求的时候加人就可以提高效率,缩短交付时间,那么多出来的人就可以与时间成负相关。那这样的话我们可以相对细致的观察衡量不同因素之间的相互影响。从而尽量降低主观上的复杂度判定。

五、总结

本篇文章从整个软件研发的生命周期来分析相关的复杂度因素,并且尝试得到一些复杂度的量化维度。在分析量化维度的时候也发现复杂度在软件中也会体现出一些性质,所以也简单分析了下其特征。后面的文章将继续深入复杂度的量化维度,并给出一个相关的量化模型。

如何衡量软件系统的复杂度(二)相关推荐

  1. 如何衡量软件系统的复杂度(三)

    一.背景 前面两篇已经大体讨论了整个软件系统中的复杂度相关的衡量指标,但是如何相对客观的通过复杂度模型来构建出来并输出相关复杂度数据,就需要对不同的衡量指标和影响因素做量化,同时需要仔细考量不同复杂度 ...

  2. OS- -调度(二)

    OS- -调度(二) 文章目录 OS- -调度(二) 一.调度 3.交互式系统中的调度 轮询调度(时间片法) 优先级调度 多级队列 最短进程优先 保证调度 彩票调度 公平分享调度 4.实时系统中的调度 ...

  3. 文本相似度的衡量之余弦相似度

    余弦计算相似度度量 相似度度量(Similarity),即计算个体间的相似程度,相似度度量的值越小,说明个体间相似度越小,相似度的值越大说明个体差异越大. 对于多个不同的文本或者短文本对话消息要来计算 ...

  4. python衡量数据分布的相似度/距离(KL/JS散度)

    背景 很多场景需要考虑数据分布的相似度/距离:比如确定一个正态分布是否能够很好的描述一个群体的身高(正态分布生成的样本分布应当与实际的抽样分布接近),或者一个分类算法是否能够很好地区分样本的特征(在两 ...

  5. OpenCV4.1.2之性能衡量与优化方法| 十二

    目标 在图像处理中,由于每秒要处理大量操作,因此必须使代码不仅提供正确的解决方案,而且还必须以最快的方式提供.因此,在本章中,你将学习 衡量代码的性能. 一些提高代码性能的技巧. 你将看到以下功能:c ...

  6. perplexity 衡量指标_困惑度(perplexity)的基本概念及多种模型下的计算(N-gram, 主题模型, 神经网络)...

    让人困惑的困惑度 发现网络上流传的关于困惑度(perplexity)大多数都是利用了N-gram或者主题模型的例子来阐述的.但是现在这个年代来学习这个指标的人多半都是想研究神经网络的,而两者对困惑度 ...

  7. 衡量文章词汇复杂度Type Token Ratio (TTR)

    Type Token Ratio (TTR): 一种有用的衡量复杂性的方法,它记录词汇丰富程度或词汇的多样性. Token 形符:文章所用单词总数,包括标点的字数 Type 类符:文章中不重复单词的数 ...

  8. 一个人的最高境界两个字!{一}第一个字:“度” {二}第二个字:“给”

    ❤️第一个字:"度"

  9. ​​​​​​ 如何衡量完善度?

    DWD层完善度:衡量DWD层是否完善,最好看ODS层有多少表被DWS/ADS/DM层引⽤.因为DWD以上的层引⽤的越多,就说明越多的任务是基于原始数据进⾏深度聚合计算的,明细数据没有积累,⽆法被复⽤, ...

最新文章

  1. Java IDEA import sun.reflect.ConstructorAccessor报错
  2. css案例学习之继承关系
  3. bat遍历当前目录下的文件,批量重命名
  4. 【Qt】QModbusDataUnit类
  5. LESS CSS 框架简介(转)
  6. 上传文件的input问题以及FormData特性
  7. Python数据类型-----列表
  8. python-容器数据类型-知识小结
  9. “ORA-01034 - Oracle not available”和“ORA-27101 - shared memory realm does not exist”
  10. 力扣236. 二叉树的最近公共祖先(JavaScript)
  11. c语言网吧添加卡,c语言网吧计费系统源代码.docx
  12. 新闻管理系统(增删改查+分页+阅读+发布评论+删除评论+数据库)
  13. 程序员有文化,多可怕!
  14. 罗马建立在水渠上:为什么需要优先建设绿色光网?
  15. 4T移动硬盘 分区_手机连接移动硬盘教程
  16. mysql的flush logs
  17. 动网论坛7.0获得WebShell的分析
  18. PostgreSQL 与 MySQL 相比,优势何在?
  19. C语言-getchar/putchar详解
  20. 知识更新越来越快,但是学习起来越来越困

热门文章

  1. ISO8583报文协议 2013-10-16 10:44 563人阅读 评论(0) 收藏...
  2. 宠物类食品猫粮、狗粮、动物粮食上架亚马逊提交FDA认证注册解析
  3. ppt太大了怎么改小一些?
  4. JS 下载 URL 链接文件(点击按钮、点击a标签、支持代理与非代理下载)
  5. 中企动力牵手七鑫易维 以眼球追踪技术剔除建站顽疾
  6. Laragon 在Windows中快速搭建Laravel本地开发环境
  7. js中new操作符具体做了什么
  8. 字符类型与Unicode 编码
  9. 什么是抽象类和抽象方法,以及他们的特点
  10. 安卓电视通过U盘安装第三方软件教程