咱们之因此一遍又一遍地听到上述问题,背后是有缘由的。为了保持竞争力,企业天天都须要新的软件功能,但随着时间的流逝,咱们交付软件的速度彷佛停滞不前,或者更糟,变得更慢了。前端
我想解释为何会这样。不过,为了探讨这个话题,须要先了解一个我最关心的话题:本质复杂性和偶发复杂性。后端
任什么时候候,当你在解决一个问题,不只仅是软件问题,都有两种类型的复杂性:安全
本质复杂性——这是包含在问题中的复杂性。若是不解决这种复杂性,就没法解决问题。它也被称为内在复杂性。微信
偶发复杂性——这是用来解决问题的方法和工具所带来的复杂性。这种复杂性不是你要解决的问题的一部分,而是在解决方案中引入的复杂性。它也被称为偶然复杂性。网络
IBM 360 系统之父 Fred Brooks 在经典论文“没有银弹:软件工程的本质性与附属性工做”中提出了这个概念。能够这么想,若是你要解决一个数学问题,本质复杂性就是指对数学的了解,由于只有懂数学才能解题。若是你想解决这个问题,要么学习所需的数学知识,要么找个懂数学的人帮忙。若是你想解决这个问题,就没法逃过学习数学这一关。架构

咱们假设,这是一个颇具挑战性的数学问题,彻底用人脑来解决是徒劳的,因此须要使用计算器。这就是偶发复杂性。还记得第一次使用图形计算器的情形吗?在这个时候,偶发复杂性就是学习如何在计算器上输入全部复杂的数学信息来帮你解决问题。你不必定要使用计算器,但你知道它对你有用,并且不会太难学。app
如今,咱们假设你对 Mathematica 很熟悉。Mathematica 是一个很是强大和复杂的软件,不过既然你已经知道它了,就决定用它来解决问题。你在学习 Mathematica 上投入了不少,因此不须要不少额外的努力,只是增长了解决方案的偶发复杂性。框架
几周后,你的一位同事遇到相似状况,他记得你曾经解决过一个相似问题。他们来找你,看你是如何解决问题的,而后你把 Mathematica 发给他们。你认为这个时候会发生什么?你认为他们会去学习数学吗?不,他们会想出另外一种解决问题的方法,或者试图让你替他们解决问题。分布式
正如你所看到的,这两种复杂性来自不一样的地方,但它们之间有着紧密的联系。若是不引入一些偶发复杂性,就没法解决问题。即便是一支铅笔和一张纸也会带来一些微不足道的偶发复杂性。工具
若是没有偶发复杂性,就没法解决问题。
这可能会让你感到惊讶,在过去 20 年中,软件领域本质复杂性与偶发复杂性比率在急剧降低。David Heinemeier Hansson(Ruby on Rails 之父)用“概念压缩(conceptual compression)”这个词来描述这种趋势以及它是如何让咱们的行业变得更好的。在过去的 20 年中,开源框架和库的激增是减小软件系统偶发复杂性最强大的力量。
与 20 年前相比,解决业务问题所需的代码量已经减小了一个数量级,所以你可能会认为开发软件将比那时快一个数量级。但这种状况彷佛并无发生,为何会这样?
软件变得愈来愈容易开发,但与此同时,其余现象也在发生:
-
咱们对软件的要求愈来愈高 -
公司内部的软件数量呈爆炸式增加 -
采用新技术的步伐正在加快
尽管咱们正在利用愈来愈多的外部工具和库来开发软件,让软件开发变得愈来愈容易,但咱们对软件的要求也愈来愈高,仅这一点就抵消了大量的收益。若是咱们用现代工具来开发 2000 年代的 Web 应用程序,会看到软件开发的生产力有十倍 (或更多) 的提高。

但咱们的世界并无停滞不前,消费者和企业对软件的指望一直在迅速增加。咱们指望软件能比 20 年前作得更多。当咱们开发出这些更大型、功能更丰富的应用程序时,为了保持它们的可靠性、功能性和可理解性,不得不改变软件的开发方式。
如下是咱们在过去 20 年里看到的几个行业变化:
源码控制——源码控制一直都存在,但并不像如今这么广泛。不认为这增长了偶发复杂性?那就去问问第一次使用 Git 的初级工程师,他们是怎么想的。
自动化测试——咱们引入了不少测试类型和测试工具。咱们须要进行验收测试、集成测试、单元测试等等……这给项目带来了大量的偶发复杂性,但有助于确保交付的软件是高质量的,且功能是符合预期的。
拆分系统——随着系统复杂性的增长,组件之间链接和交互的量会呈二次级数增加。也就是说,在某种程度上,若是软件设计得很差,交互量将会继续增加,直到由于自身的复杂性而垮掉。拆分系统,特别是进行分布式拆分,会带来大量的意外复杂性。
专门化——随着 Web 应用程序变得愈来愈复杂,出现了大量的专门化。在 2000 年,由软件工程师负责 UI 设计、UI 构建和应用程序后端构建都是很常见的事,而到了 2020 年,这些工做须要几个角色分别承担。开发 Web 应用程序的团队一般由 UI 设计师、UX 设计师、前端软件工程师、后端软件工程师和 DevOps 工程师组成。在较大的组织中,会有更加专门化的角色,如安全、架构、数据管理、数据科学,等等……全部这些额外的角色让咱们可以开发更大规模的软件,但所需的工具和流程了引入大量的偶发复杂性。
基础设施自动化——为了构建更大型、更复杂的环境来运行愈来愈多的应用程序,咱们已经开始自动化它们的构建和维护过程。这样咱们就能够更容易地进行大规模的环境管理,但须要一整套工具和知识。这些工具带来的复杂性是巨大的,致使 DevOps 成为大多数大型团队的专门角色。
频繁部署——因为应用程序的大小和复杂性都在增加,为了下降风险,咱们须要以较小的增量交付软件。为此,咱们引入了持续集成和持续部署的概念。一样,这对于大规模交付软件来讲是很是好的,但用于构建和操做这些管道所需的工具和技能引入了偶发复杂性。
多设备和形式因素——在之前,咱们能够说,咱们的软件运行在一个操做系统上,只有少数的几种分辨率。如今,咱们的应用程序须要在台式机、笔记本电脑和跨平台的移动设备上运行。一般,咱们会有原生移动应用程序和 Web 应用程序,或许还能够加入一些物联网应用程序和手表应用程序。咱们在访问数据的位置和方式上有了巨大的灵活性,改变了咱们的社会,但无疑增长了软件开发过程的复杂性。
在阅读上一个小节前,你可能已经很是清楚,人们对软件要求愈来愈多以及愈来愈多的软件开发形式会致使复杂性的增长。可是,从单个应用程序的角度来看,企业拥有更多的软件会增长开发单个应用程序的复杂性吗?
答案很简单:不会,除非你想让这个软件与其余软件发生交互。一家公司使用的软件越多,系统之间的重叠就越多,不一样的系统须要访问相同的数据才能正常运行,这就须要为更多的系统保存共享数据,并将全部系统集成起来。
举个例子,假设在 2000 年,你是一家办公椅生产商,那个时候你尚未网络系统。你须要为公司创建一个库存系统,因此须要开发软件来完成这件事。库存系统的用户是仓库工做人员,你能够经过生成夜间报告来得到库存信息,这些报告也能够被发送给整个公司的人。这个系统相对独立,报告功能对于每个人来讲都没有什么问题。
时间快进到 2020 年,你的库存系统已经不是一个独立的应用程序。你的合做伙伴能够直接将订单推送到你的系统中,Web 页面能够得到实时的库存更新,并在下单时更新库存。你的库存系统与物流系统直接集成,这样就能够自动生成物流标签和取货时间表。你直接在亚马逊上销售你的产品,因此你的库存系统直接与第三方软件集成。仓库的工做人员使用移动设备定位、扫描、登记和挑选商品,因此你还有一个用来完成这些事情的移动解决方案。
随着系统的激增,并覆盖了业务的各个方面,开始出现愈来愈多的重叠,一直到若是不与其余系统集成就没法知足需求的地步。虽然这带来了史无前例的生产力和自动化程度,但也给数据移动和集成引入了大量的偶发复杂性。
Marc Andreesen 提出了“软件正在吞噬世界”的说法。这个过程正在加速,并且看不到尽头。
在 2000 年,你一般会从单个厂商那里购买系统,如微软、Sun 或 Borland,你还可能还会购买一些组件,但无论怎样,整个生态系统都是由单个厂商提供的。此时,你所采用和集成的外部工具和技术相对较少,你所能完成的任务被限制在厂商所提供的功能上。
为了跟上快速变化的技术格局,公司开始采用更开放的技术。这带来了巨大的优点,由于你能够用这些工具完成之前只能在梦中想想的壮举。但切换工具一般是有代价的,最终会在流程中引入不少偶发复杂性。
虽然使用前沿的技术可能会在某些方面得到好处,但技术越新,维护的难度就越大。并且,越早采用一项技术,当它演化成为一项对广大用户都有用的技术时,你所经历的痛苦就越多。如何平衡一项新技术所带来的收益以及使用它所带来的痛苦是技术专家们长期以来一直在努力解决的问题。
咱们如今发现,挑选有用的工具、框架和技术是一项很是有价值的技能。若是不当心使用了未经验证的新工具或框架可能会产生有害的影响。它们可能会致使大量的偶发复杂性,更糟糕的是,若是框架在跨越鸿沟以前死亡,就会把你带入死胡同。
关于为何开发软件须要的时间愈来愈长,缘由还有不少,好比业务须要更快的迭代速度、企业架构标准或对安全性的重视程度,等等。但关键是,咱们在 2020 年开发的软件与在 2010 年开发的软件几乎没有什么类似之处,更不用说在 2000 年了。在很大程度上,这是一件好事。
但也有很差的地方。咱们彷佛又回到了 2000 年到 2007 年,那时每一个应用程序都是用一样的工具开发的,而其中有不少工具变得愈来愈复杂。如今,不少流行的工具和框架都来自于大型企业,但它们解决的不少问题是其余企业不会遇到的。
正由于如此,不少中小型企业,甚至是大型企业的一些部门都发现,他们运行软件的能力正在迅速降低,并且不知道如何扭转局面。为了加快开发速度,他们已经开始转向低代码和无代码,但在不少状况下,这也破坏了使用这些工具构建的系统的功能和寿命。
原文连接:
https://www.simplethread.com/why-does-it-take-so-long-to-build-software/
纯学习的Python公众号,天天4篇文章,没有任何广告!很是适合讨厌广告的Python读者关注看看!
本文分享自微信公众号 - 程序IT圈(DeveloperIT)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。