关于软件工程的几点思考

简介: 来阿里已经很长一段时间了,从刚开始来我就想写点关于软件工程,服务化和开发效率的个人理解,却一直没有想好怎么写,一直在心里筹划思考该如何准确地表达我所想的内容,也能够给别人带来一些有价值的信息,但是拖了很久了,想想还是写出来罢,没有必要追求那么完美,欢迎拍砖。(顺便说下,有观点认为拖延症患者都有或多或少的完美主义倾向,处女座的同学验证下哈。) ## 1 什么是软件工程? 服务化其实是一个软

来阿里已经很长一段时间了,从刚开始来我就想写点关于软件工程,服务化和开发效率的个人理解,却一直没有想好怎么写,一直在心里筹划思考该如何准确地表达我所想的内容,也能够给别人带来一些有价值的信息,但是拖了很久了,想想还是写出来罢,没有必要追求那么完美,欢迎拍砖。(顺便说下,有观点认为拖延症患者都有或多或少的完美主义倾向,处女座的同学验证下哈。)

1 什么是软件工程?

服务化其实是一个软件工程领域的课题,在说这个之前,我们需要先回答一下什么是工程?什么是软件工程?

1.1 什么是工程?

所谓工程(engineering),Wikipedia上的定义是:

Engineering is the application of mathematics, empirical evidence and scientific, economic, social, and practical knowledge in order to invent, innovate, design, build, maintain, research, and improve structures, machines, tools, systems, components, materials, processes and organizations.

简单来说字面理解就是一种把人类知识应用到实践中去的活动,当然这个是广义上的理解,狭义上来说能称得上工程的事情都不会太小,需要协调各个领域的专业人才为了一个共同的目标来劳动以构建一个相对复杂或者庞大的事物。

1.2 软件自身的特性对软件工程的影响

软件工程当然也是工程的一种,不过和传统工程有一个显著的区别,那就是软件本身的特性所带来的变化。
所谓软件,本质上都是一些承载人类智力活动结果的信息,随着技术的发展,信息的存储、修改、复制和传播变得越来越容易和廉价,相比于实物产品,软件有着几乎可以忽略的复制成本,和非常低的修改成本(不考虑修改本身所需要的智力活动)。因为这个特性,所以一个软件工程师可以轻易使用世界上最顶尖的人类智慧成果,也可以让自己的产品迅速影响亿万人群的生活。所以软件工程和其他工程的不一样之处在于软件工程是几乎完全纯粹的创作性劳动,而不需要有太多的重复劳动(理论上)。软件工程师的生产力主要受限于所在的平台,而其他领域的工程师的生产力可能还被其他因素所限制,比如一个医生(在我看来就是人体工程师啊,不过医学界的前辈比较聪明,给自己起名字叫doctor,听起来就高大上)她/他每天看的病人数是有限的,因为就算病症相同,也得一个一个来是不是?建筑工程师盖房子的时候,也只能一座一座盖。

2 影响软件工程的主要问题

由于上述软件工程的特点,就带来了一个问题,组织一个软件开发团队,无法照搬其他工程领域的组织方法和实践经验,有一些在其他领域制约效率的关键问题在软件工程领域可能就不是问题,而其他领域不怎么显著的问题,到了软件工程领域就变成了瓶颈了。
具体来说除了开发所需要的智力活动本身外,软件开发中最大也最容易被忽视的成本就是沟通成本,其次就是重用其他人的智力成果的成本问题。

2.1 沟通对于软件工程的影响

首先为什么沟通成本会成为软件工程中(除了开发本身)最大的成本呢?原因是多方面的,一个主要的原因在于通常需要软件来解决的问题都是复杂或者庞大的问题,即使搞清楚这个问题就需要大量的沟通和相互理解,其次不合理的团队组织会大大提高沟通的难度,降低沟通的效率。《人月神话》这本书里提出了两个关键的观点,一个是没有银弹,另外一个就是沟通成本会随着团队人数增长而指数级增长(如果团队组织保持最原始的形式)。

2.2 软件复用的成本

前面提到了软件的复制成本很低,然而软件复用的成本却并不低。所谓软件复用,是指重用他人的软件成果,为什么重用其他人的智力成果还会有很高成本呢?这个问题主要是一个软件工程师要想利用他人的成果,首先要了解他人的成果具体解决了什么问题,其次如何才能将他人的成果引入到自己的产品中来,最后就是软件都是有瑕疵的,当其他人的软件出现问题的时候,维护带来的工作成本。这些成本加在一起有时候甚至大过了软件工程师自己重新做一遍的成本,这也就是为什么软件行业不停地说不要重新发明轮子,但实际上很多人都在重新发明轮子的原因。

2.3 专业团队的局限性

在传统的领域,我们经常可以看到按照专业分工来组织团队,对于软件开发团队来说,这种模式曾经也被广泛运用,然而今天却被越来越多的软件企业抛弃,为什么?在我看来,这个主要问题在于传统行业因为劳动成果的不可复制性,所以要获得更大的产出能力,需要组织更大规模的团队,而更大规模的团队还能保持较高的效率显然需要更加严密的组织才可能更有效率的运作,在这方面军队是一个典型的例子。从这个角度来说按照专业分工来说能够大大降低管理的成本,同时因为重复性劳动较多,所以沟通也不会成为太大的问题。然而对于软件工程来说,按照专业分工来组织团队的效率确不会太高,因为一方面获得更大产出能力并不需要更大规模的团队,另外一方面却因为创造性工作需要更多的沟通和协调,按照专业来分工会带来大量的跨团队沟通,对于工程效率来说大量的沟通需求就是一个噩梦(Jeff Bezos就特别敏锐地指出了这一点)。所以要打造高效率的软件工程团队,按照专业分工来组织的方式未来必然会被抛弃。
同时对于一个公司来说,也不是所有的工作都是和软件开发具有同样特性的,典型的例子HR永远会是一个按照专业来组织的团队,即使在一个软件公司。

3 关于解决软件工程中的几个观点

3.1 “强内聚,松耦合”对软件工程的价值

要解决软件工程中的沟通问题,前人总结了很多经验和方法,这里就不一一展开了,其中的关键点在于软件工程师都熟知的一句话:“强内聚,松耦合”。关于这个说法本身,各种解释已经很多这里也不多说了,这里想说的是,这句话不仅仅说的是软件设计本身,同时也是在说软件开发组织时所需要考虑的形式。在软件开发组织的时候,如果每个单元(unit)都能够做到把大量的沟通需求局限于单元内部,而不是外散到其他各个单元(unit),那么就能尽可能降低沟通带来的成本,提高软件开发的效率,反之则是无穷无尽的开会,返工和重复建设。另外需要强调一点的是,内聚和耦合是相辅相从的,在一个抽象层面上的过度内聚(功能单一),会导致另外一个层面上的紧耦合,软件工程的艺术之处在于如何平衡各个抽象层面的关系,选择合适的内聚程度来降低整个系统的沟通成本。这个限制究其根本还是因为人类大脑的物理限制,我们在思考问题的时候只能同时考虑5到7个对象,所以面对一个复杂问题的时候,我们需要把问题抽象成不同的层次,并尽可能避免跨越层级思考。今天人类社会的发展和进步,越来越需要高水平的协作,然而人类的大脑进化是相对缓慢的,所以在无法突破大脑极限的前提下,如何组织和协调是非常关键的问题。

3.2 层次化的软件和层次化的团队分工

在信息技术领域,其实分层是非常清晰的,比如网络协议的分层,硬件到软件应用的分层等等都充分体现了前人的智慧和思维水平。软件行业发展到今天,解决的问题规模越来越大,复杂度成倍提升甚至指数级提升,在这种情况下,如何组织和编写大型软件的方法发生了巨大的变化。之前的软件通常都是作为一个产品整体呈交,所以会出现一个非常庞大的团队以非常长的周期来构建大型软件,就好像修建一座大型建筑一样,各种专业人士分工明确,各司其职。而今天首先我们需要应对瞬息万变的业务变化,同时复杂度的增加带来的沟通成本已经到了非常严重的程度,所以人们提出了服务化或者说微服务的概念。从硬件层,OS层,JVM层,模块(库)层到应用层(书本上讲的这种,不是阿里内部通常说的应用啊),现在我们在这个基础上提出了新的一层抽象,也就是服务层。一个服务可能是单个或多个应用,在一个大的系统中完成一个特定的功能和业务,而在这个层面,服务的设计和架构应该尽可能满足“强内聚,松耦合”的原则。只有这样,才能保证服务和服务之间所需要沟通和理解的信息减少,同时也需要通过确定的SLA来降低服务使用者的产品成本。

3.3 团队的成员分工

上面提到的划分主要说的是团队分工,在一个团队内部,是不是也不要专业分工了呢?从我的个人经验和认识来看,我认为没有一个统一的标准,通常来说,软件团队的成员我们更加希望是一专多能,每个人都有自己的专长,但是对于非擅长领域也能完成基本的工作任务。有点类似现代军队的特战分队,各种专业人士都有,但是这些人首先都是一名战士而非文弱书生。这样的团队才能够面对难题的时候依靠专业能力解决难题,同时面对大量的普通工作时能够互为替补,迅速取得结果。

4 服务化与工具化

人类区别于动物主要在于工具的运用,一个工具的价值对于社会来说不仅仅是单个个体的价值,也包括规模化应用后带来的整体价值。比如汽车在普及之后极大地改变了人类社会的形态,这个背后除了汽车成本的降低,还有一个因素就是人们使用汽车的难度也在不断的降低,随着技术的发展,人和车之间所需要的沟通越来越少,越来越符合人类的沟通方式,相比之前,现在一个人只需要更少的训练就能正确地使用汽车。

另外一个例子就是做家务,在没有洗衣机,烘干机,扫地机器人,厨房电器等等设备的年代,家务活也是非常繁重的,以至于家务需要全家人参与才能完成,而且还不能很好地完成,只有贵族和富豪才能拥有优渥的生活,而今天各种方便的工具大大简化了家务劳动的复杂度,这样人们就可以从家务劳动中解放出来,去做自己更想做得事情。这个简化的背后,这些工具的易用性是保证使用者效率提升的关键因素,如果工具很难使用的话,也就无法取得广泛地使用。

从软件的角度来说,工具化意味着降低学习成本和使用成本,然而今天的软件产品越来越复杂和庞大,把软件部署到用户自己的计算机系统上这种方式会给软件的演化和维护带来巨大的成本,所以随着网络技术的发展,越来越多的软件组件采取了服务化的形式提供。服务化的主要核心要点是用户通过网络来使用软件,用户和服务提供方之间通过SLA来约定服务质量,不再需要维护软件本身。所以服务化和工具化并不矛盾,而是工具化在网络时代的另一种形式。

5 系统性能与开发效率

阿里的同学对于软件系统的性能都非常看重,几乎到了毫秒必争的地步,然而开发效率方面考虑的不够多。个人认为系统性能固然重要,但是如果系统性能的提升是以开发效率降低为代价的话,最好还是要慎重一些。主要问题在于现在的互联网竞争不仅仅比拼的是产品本身的质量,同时也是团队效率的竞争。产品能否快速上线,往往不是靠堆人就能解决的问题,而一个基础系统架构的决定,可能会影响整个公司一多半的开发人员的工作效率。
这里面有个很关键的点在于,系统性能的提升好处是很容易拿到数据来衡量的,而对于这些产品的使用者来说带来的困扰却分散到了各个团队每个人日常的工作中,所以很难衡量。从KPI的角度来说,有数字容易衡量的KPI才是好的KPI,拿到了结果的成绩才是好的成绩,可现实中很多不是那么容易衡量的因素也在影响着个人和公司的命运,这些也需要我们找到合适的观察和衡量的手段,有时候甚至依赖领导者的直觉来做出判断,从而做出合理的决定。

回到系统性能和开发效率的问题,我们在衡量系统性能提升的同时,能否估算一下对于使用者带来的复杂度,对于开发效率的影响,以及本身维护成本的提升呢?
从服务化的角度来说,可能因为远程调用链路的增加,确实会带来更长的网络延时,可是我们是否从业务架构的角度优化整个流程,能否找出真正的性能瓶颈并且优化,这些是服务化必须面临和解决的问题,实际上很多问题都是有解的,主要在于我们是否跟进去并且找到了根本原因。

6 平台化与服务化

6.1 什么是平台化

在说平台化之前,我觉得有必要先定义什么是平台,因为平台这个词已经被广泛使用,对于平台的内涵至少有两类理解:

  • 提供一个特定个抽象层面的完整的建模和执行能力的集合,所有的能力由平台完成一定程度的抽象和封装,平台的使用者不需要知道能力的具体提供者,比如Windows平台,PC平台。
  • 提供一个供多方参与者完成一类活动的环境或者说生态,其中能力提供者和使用者互相知道对方的存在,平台的提供者主要负责规则和标准的维护。

个人更加倾向于前者,在我看来平台具有以下几个特点,首先平台是一层逻辑完备的资源、功能和方法的抽象,所谓完备是指对于平台的使用者来说,平台提供的问题建模能力能够覆盖其(几乎)所有的场景,一般情况下无需引入平台外的能力,而抽象层意味着使用者无需感知下层细节。其次平台对于使用者中立,对于所有的使用者来说,平台是一致的。

6.2 平台化和服务化矛盾吗?

就平台化和服务化来说,这两者并不矛盾,服务化更多的强调的是单个功能或者业务逻辑的自治,而平台更多的是考虑如何达成一个完备的抽象层来完整地表述下层的能力,同时也能满足业务的需要。平台可能包含一些列的服务和工具,以及一套平台所使用的语言或者模型,平台的使用者通过平台提供的语言或者模型来给自己的业务问题建模和开发问题解决方案,由平台来执行使用者的指令,并转换成底层能力的调用来完成业务问题的实际解决。平台和服务相同点在于它们都是一种能力抽象模型,但是服务更多的是一个功能点,不是一个完备的能力集合,而平台是一个面,是一个完备的能力集合。
举例来说操作系统平台通常是一些列API,服务和工具的集合,Java是包含JVM,基础类库和一系列工具的集合,淘宝天猫是一些列的基础服务和工具的集合。对于使用者来说,一般情况下无需跳过平台接触到下层的细节,只需要在平台提供的框架内表述好问题的解决方案即可。

6.3 平台化能带来什么?

在我看来,平台化的好处是给使用者提供了一套完整的解决业务问题的基础,同时在抽象层的协议相对稳定的前提下,平台的提供者和使用者分工明确,双方可以各自优化自己的逻辑和实现来改进整个解决方案,平台的提供者可以通过平台的共享来最大化自己的价值。
平台的一个特点在与平台本身的设计对于设计者的要求很高,一个完备的抽象层不是能够轻易设计好的。另外平台本身通常是庞大而复杂的,如果一个平台的定位出了问题,大量的投入可能无法获得预期的收益。

7 总结

最近两天又看到了一篇关于腾讯的产品化思维的文章,从我的理解来说,叫产品化,平台化还是服务化其实只是用词不同 ( 更新:之前这个陈述是很不严谨的 )
不论是平台化,还是服务化,背后的关键在于是否根据软件工程的本质特点来做到“高内聚,低耦合”,从而打造高效率的软件团队,快速响应业务需要和适应行业竞争。

目录
相关文章
|
3月前
|
敏捷开发 安全 测试技术
软件工程:从概念到实践
【8月更文第20天】随着信息技术的快速发展,软件在现代社会中扮演着越来越重要的角色。从简单的移动应用到复杂的操作系统,软件已经成为连接人与数字世界的桥梁。为了有效地开发和维护这些软件系统,软件工程应运而生。本文将探讨软件工程的基本概念、目标、原则以及常用的生命周期模型。
162 0
|
4月前
|
监控
软件复用问题之软件工程中事中缓释,如何解决
软件复用问题之软件工程中事中缓释,如何解决
|
算法 Java 程序员
软件工程工作必备
软件工程工作必备
63 0
|
安全 测试技术 UED
从软件工程角度看测试
近几年的软件测试岗位,开始逐渐变为了QA,即质量保障。看似只是一个名词的变化,其实背后对应的是企业对软件测试这个岗位有了更多的要求和期望。当然也有同学会自嘲自己是点工、PageClienter等,面试造火箭入职拧螺丝的背后也存在很多无奈。
|
前端开发 Unix 图形学
没有银弹:软件工程的本质性与附属性工作
NO SILVER BULLET: ESSENCE AND ACCIDENTS OF SOFTWARE ENGINEERING It's adapted from berkeley . If you want to know more, you visit the orignal articlehere.
2310 0
|
新零售 移动开发 人工智能
程序员写好技术文章的几点小技巧
去年成为了内网技术分享平台的年度作者,受邀写一篇关于“如何写好文章”的文章。我本身并不喜欢写字,去年写的几篇文章,涉及的话题自带流量,所以阅读量多了一些,谈不上有多擅长。不过还是决定分享一下自己在写文章时用到的一些小技巧,希望对大家有帮助。
程序员写好技术文章的几点小技巧
《软件工程方法与实践》—— 1.4 软件工程的基本原理与基本原则
推迟实现。推迟实现是软件方法学的基本指导思想。软件开发过程应该理性地 “推迟实现”,即把逻辑设计与物理设计清楚地划分开来,尽可能推迟软件的物理实现。对于大中型的软件项目,在软件开发过程中,如果过早而仓促地考虑程序的具体实现细节,可能会导致大量返工和损失。
2256 0
|
测试技术
《软件工程方法与实践》—— 1.6 小结
软件是计算机系统中与硬件相对应的另一部分,是一系列程序、数据及其相关文档的集合。软件具有复杂性、一致性、退化性、易变性、移植性和高成本等特征。软件工程是由于软件危机的出现而被提出的,其主旨是以工程化的思想进行软件的开发与维护,目的是高效率地生产出高质量的软件。
1749 0