一、背景
上一篇重点讲述了软件复杂度的由来和现象,以及不同视角下的复杂度是怎么呈现的,本篇文章将从更细致的方面来阐述形成复杂度的一些指标数据,并按不同维度进行区分。
这么做的一个原因就是希望通过本篇文章让软件复杂度更具象,让软件开发者更直白全面的感受复杂度。
二、复杂度的因素有哪些
这里我们从软件开发的整个生命周期来看复杂度在这个生命周期中具体与哪些因素有关。
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 动态性
最近一年加了很多微信群,也跟不同的 友和同事讨论过复杂度的问题,关于复杂度的话其明显的一个特征就是动态性,也有人觉得复杂度是动态守恒的,为什么这么说呢,因为复杂度有其客观的一面也有主观的一面,所以叫动态守恒也不是没有道理。
3.2 脆弱性
软件复杂度的脆弱性是指软件本身可能随时被替代,那这样的话软件复杂度就无从谈起。因为业务下线,因为更换软件等原因我们研究的软件对象则失去了焦点,对应的复杂度也就消失了。不过也体现了整个需求的变化,只是映射到不同软件组件或者软件系统中从需求的层面来说复杂度还在。
3.3 传递性
在数学加法上有个定律叫交换律,就是a+b=b+a。所以这里我们在衡量一个复杂度因素的时候往往会准备替代或者更改另外的复杂度,但是带来的问题就是会使其他复杂度因素提高。一个很简单的例子就是过度设计,或者提前优化,这么做看上去是好的,面向未来编程,但是实际上系统的稳定性要求比较高的情况下这么做很容易出问题。
3.4 相关性(等价替换)
从3.3所表现的特征来看,我们在简化复杂度的时候可以通过相关性来进行一些相对精确的度量,比如在迭代需求的时候加人就可以提高效率,缩短交付时间,那么多出来的人就可以与时间成负相关。那这样的话我们可以相对细致的观察衡量不同因素之间的相互影响。从而尽量降低主观上的复杂度判定。
五、总结
本篇文章从整个软件研发的生命周期来分析相关的复杂度因素,并且尝试得到一些复杂度的量化维度。在分析量化维度的时候也发现复杂度在软件中也会体现出一些性质,所以也简单分析了下其特征。后面的文章将继续深入复杂度的量化维度,并给出一个相关的量化模型。
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!