互联网开发模式二:敏捷与重构

敏捷开发的意义和实践

敏捷开发是我们现在最常见的一个“开发模式”,然而很多时候,我们看到“敏捷”两个字,似乎就是让程序员多加点班,或者忽略一些过程加快把代码弄出来,而真正理解“敏捷”含义的并不多。实际上,敏捷并不会加快单位代码的开发速度!敏捷最主要的目标,是应对需求不明确和需求变更,而这两者正式互联网服务中最常见的情况。

需求变更的原因

在互联网服务中,由于没有直接的“客户”下单要求,所以很多需求,都是由公司内部的人“代表”的,最典型的就是我们的“老板”们了。正式因为没有明确的“下订单”的过程,所以很多传统的需求分析变得没法做了,因为不管是老板还是产品经理,都是面对着成千上万的客户去猜测他们的需求,如果他们自己能代表客户还好,如果猜错了,项目的代码肯定要修改。

很多互联网公司都非常重视“数据”,原因就是这些“数据”往往代表了用户对产品的看法,而这些看法成了互联网产品设计的唯一客观标准。然而这些数据本身,会包含了大量复杂性,由于统计方式、产品形态、季节时间等等,都会产生偏差。我们的项目需求,往往就是在这些偏差中确定。这就难免产生需求的变更了。

互联网的客户个体多,服务内容丰富,功能变化快,是互联网项目中需求变更很多的主要原因。因此这也让敏捷开发,成为互联网项目开发中最重要的方法。————敏捷强调的是用原型来验证需求,在互联网服务里就是,尽快推出服务,通过数据来验证想法。如果我们能越频繁的修正原型,就能越快的接近真正的需求,也就是说,如果我们的互联网服务能越快的修正各种问题,同时越快的推出新的版本,就能让用户越牢固的“黏在”这个服务上。

架构设计实体化:单元测试

敏捷开发讲究要快速的修改代码,我们往往会发现,代码修改的越频繁,BUG越多,这似乎是一个无法解决的矛盾。然而,在敏捷开发方法论中,有一个用来防止这种修改造成的BUG增加的重要措施,就是——单元测试

单元测试本质上,充当着自动的QA人员的角色,如果我们把所有的设计和需求,都先按单元测试的形式“固化”编写下来,那么我们在修改代码后,就能快速的、自动的、反复的去验证我们的代码有没有问题。如果这些测试足够全面和详细,那么我们是不会担心代码修改导致大量的BUG的,因为单元测试会自动帮我们支出问题所在。一旦我们知道了问题,修正起来反而变成是最简单的事情了。

假如一个项目的代码丢失了,但全面的单元测试都还在,那么要重建这个项目并不困难,因为所有的需求,都被蕴含在这些测试代码中,程序员们几乎不需要去重新啃文档,谈需求,他们只要把代码弄成能通过单元测试就好了。

这种需求的“代表物”不但是程序员开发的概念和目标,而且还可以自动的帮程序员去验证他们的实现。所以,如果你要使用敏捷开发,要尝试频繁修改原型,就一定要使用TDD(测试驱动开发),特别是高度重视单元测试的作用。

统一软件设计思路的重要性

曾几何时,我们认为,使用什么语言开发,用结构化编程,还是面向对象编程……这些一般人难以深入理解的事情,都是程序员这伙顽固的家伙的怪癖,基本属于私人喜好的范畴。外人既不应该深入干预,也没办法去影响,因为如果你不识好歹去在这些事情上冒犯程序员,他们随时可能一言不合就辞职。既然我们只需要可以运行的代码,我们为什么冒风险去激怒程序员呢?

然而,在互联网服务的开发过程中,代码本身并不是某一个固定的、静态的东西,它需要不断的与时俱进,需要跟随这业务的发展而变化,同时也会从某一个程序员手里,流向整个开发团队。在这种情况下,软件开发习惯、代码的风格、程序的设计思路,就变成一个非常重要的事情了。

代码交流:面向对象

确实现在还存在大量的讨论,说“面向对象不是万能的”。说得对,但是,世界上有什么东西是万能的呢?我只能说,在需求变更非常快的情况下,面向对象思想,是现在我们能选择的最好工具了。

在“数据结构+算法=程序”的时代,软件主要是以计算任务为主,电脑是为了代替人脑进行超乎想像的运算任务而存在。而在互联网时代,软件主要的任务已经变成了处理这个真实世界的信息了。信息的存储、交换的任务,已经远远超过了“计算”的任务数量。

虽然我们知道,所谓的信息处理,最底层还是依赖大量的“计算”,然而,我们的程序员们,早已不再需要编写大量“计算”的代码,我们面临的挑战,是如何用代码准确而快速的表达这个世界。

面向对象思想包括分析、设计、编码三个部分(OOA/OOD/OOP)。这些思想看起来繁文缛节,似乎非常啰嗦。然而,其核心思想却非常简单:从表达过程,转向表达对象。人类的思维中,对象、或物体,是一个个具备自己的信息特征的个体,而行为和过程,往往是依附于这些个体的。比如鸟会飞、账号会锁定、汽车会死火等等。

所以如果我们的代码,是以表达对象,把信息和行为统一起来,是最接近于我们的认识规律的。

在互联网开发领域,由于网络无处不在,涉及到的领域异常广泛,如果我们没有一个能把代码世界和现实世界联系的纽带,我们的项目将非常难以理解。——难以理解的项目,就难以变化,从而就失去了互联网最显著的特征。所以我认为,面向对象的思想,是每一个互联网开发人员都应该理解的,并且应该是面对大部分业务时,首先考虑选择的。

代码架构与重构

我见过无数的代码架构图,里面画满了进程和服务器的拓扑,各种线条上标注了通讯协议,编码格式,还有各种流程图和协作图,然而,这些架构设计,无一例外的对于需求变更毫无帮助。因为它们描述的是一种现状,甚至连现状都不是,只是一种关于现状的猜测。随着项目代码的不断变化,代码数量和关系都会膨胀,这种进程、通讯级别的结构,除了越来越复杂以外,根本对于指导项目如何应对各种“代码腐化”毫无用处。

因此我们想到了流行的“重构”,然而,如果我们只是重构进程的关系,通信的层次,那些错综复杂的代码调用关系一样存在。各种回调、事件、耦合还是让代码无法理解。我们只是在试图把混乱塞到一些瓶子里面,并没有解决混乱本身。

所以,我们需要的另外一个思想武器:代码结构。只有我们从另外一个角度,另外一个视图去观察代码,才能把握代码之间耦合的情况。正如建筑里的平面图和立面图,都是不可或缺的。

所以我们应该高度重视“代码架构”,也就是描述代码之间的关系的架构,而不是进程之间的关系的架构。在关注代码互相调用、耦合的关系上,我们能把混乱复杂的代码关系理清,整理出一个便于理解,便于修改的代码外观。

这些工作看起来完全是针对开发人员的,但是实际上,这些工作是能提高整个开发效率的。它能让代码从难以修改,变得容易修改,从而得以支持快速的业务需求变化,这是对业务、对产品最重要的支持能力。

明天将推送新这个系列最后一篇《持续集成与DevOps》,感谢关注。

感谢大家的阅读,如觉得此文对你有那么一丁点的作用,麻烦动动手指转发或分享至朋友圈。如有不同意见,欢迎后台留言探讨。

原文发布于微信公众号 - 韩大(handa1740168)

原文发表时间:2016-08-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏ThoughtWorks

在医疗健康领域引入软件开发安全实践

BSI简介 “Build Security in DNA”简称BSI,是在开发过程中内置安全的软件开发实践。 顾名思义,BSI是要将各种安全措施从早期就纳入到软...

2584
来自专栏Java架构师学习

阿里十年,只剩下这套Java开发体系了

以前我一直被公司和技术牵着走,并不是自己在选择技术,而是不自觉地被推到了这个位置上。想想有多少人对于自己将来要从事的职业和技术类型进行过深入思考和比较呢?当我跳...

612
来自专栏FreeBuf

CISO元素周期表

距离4月19日在美国举办的RSA大会,时间过去了将近一个月,大会的盛况已经逐渐淡出人们的视线,但是大会上发布的新的理念和产品却在安全圈逐步发酵,相信未来会对安全...

763
来自专栏Java架构师进阶

架构师是怎样炼成的?

随着软件行业的发展,软件人才也在不断地细分。以前,他们被统称为软件开发工程师。而现在,系统分析员、配置管理员、测试工程师,新兴的岗位名称不断出现。其中,软件架构...

442
来自专栏猿天地

开发十年,只剩下这套Java开发体系了

蓦然回首自己做开发已经十年了,这十年中我获得了很多,技术能力、培训、出国、大公司的经历,还有很多很好的朋友。

753
来自专栏PHP技术

谷歌是如何做到几乎从不宕机的?

摘要: 某一天,你需要使用Google,但Google并不可用——你上一次遇见这种情况是什么时候?很有可能,这种情况根本没有发生过(译注:这文章是美国人写的)。...

2955
来自专栏顶级程序员

百度挂掉之后,Google是如何做到从不宕机的?

昨日夜间,百度客户端及移动端百度搜索出现故障。用户无论使用任何关键词进行搜索,都会得到“很抱歉,您要访问的页面不存在!”的提示,并收到检查访问的网址是否正确,...

3665
来自专栏SDNLAB

多接入边缘计算 – 第2部分:保护MEC的安全挑战

多接入边缘计算(MEC)是一种网络架构,为网络运营商和服务提供商提供云计算能力以及网络边缘的IT服务环境。

71
来自专栏大数据文摘

解密:“女博士”如何领导美帝神秘机构DARPA

1144
来自专栏EAWorld

微课堂 | 云计算平台架构设计与核心流程

本文为普元软件产品部主任架构师顾伟在普元云计算架构设计群的微课堂分享,转载需保留此处版权申明。 ? 今天我和大家分享的是:我们在做新一代产品时的总体设计思路以...

3454

扫描关注云+社区