六个月项目如何成为Vaporware的真实故事
上次我写了《 持续融合:战争故事》 。 这篇文章描述了第二次世界大战的反坦克犬项目,以及他们是如何在太晚时才发现它的问题的。
那使我想起了过去的真实软件开发情况。
那是我职业生涯的开始。
多年前…
我在一家为汽车经销商构建企业软件的公司工作。 它旨在帮助销售。
像AWS这样的云服务提供商。 不存在。 客户负责购买计算机并在自己的Intranet中运行该软件。 他们中的一些人还必须支付专门的IT部门来配置和维护其网络。
该系统是基于网络的。 它建于2003年,并延续了十年。
在前端,屏幕的每个部分都是在iframe中创建的。 JavaScript仅用于基本交互。
在后端,我们使用了Java平台企业版 。 所有的类和包都紧密地耦合在一起,并且有一个PostgreSQL数据库。
那是一块巨石 。
有一个Java类,所以很大的Eclipse在打开时会冻结。
许多年前,我在一个具有Java类的整体应用程序中工作,因此大型Eclipse在打开时会冻结。
客户系统是该系统的高级模块之一。 我的任务是更改它的设计,并添加大量积压在积压中的所需功能。
客户模块非常混乱,无法扩展。 我建议使用jquery UI重写它,以便它允许我们通过更改一个CSS文件而不是多个CSS文件来修改设计,并添加所需的功能。
任务看起来并不简单,但是我相信事情最终会得到解决。 我开始在最大的iframe中一点一点地更改页面,然后更改与之相关的其他位置,直到重写整个模块。
我不知道的一件事是,我要更改的页面与页脚(另一个iframe)耦合在一起。 它也连接到其他iframe内的其他页面,这些页面又连接到另一个iframe内每个人的列表屏幕!
客户模块很大而且很混乱。 但是,我建议重写所有这些内容,认为事情最终会得到解决。
哦,我是否提到没有测试?
10年的代码,因此无法验证功能。 即使是从一开始就在那儿的那些人也不记得系统许多部分的用例。
尽管如此,我还是坚持不懈地努力。 我是唯一有勇气进行此重写的人。 在这种情况下, 英雄不是错误修复者,而是我天真地跳入了这个大怪物,却不知道其含义。
由于几个月前发生的事情,我绝对得到了同行的信任。 我进行了同样的跳转,以将一个小型调度系统重建为功能更完善的JavaScript系统。 从客户的角度来看,重写是成功的。 尽管回想起来,我可以看到它有很多可维护性问题。
每个人,包括我自己,都相信它将以相同的方式工作。
但事实并非如此。
客户模块没有测试,也没有人知道系统的工作方式。 但是,我建议重写所有这些内容,认为事情最终会得到解决。
当时我们正在使用CVS。 我写了很多代码,并且可以在本地计算机上“正常”工作。
一段时间后,我开始被问到事情进行得如何,还剩多少。 我总是一遍又一遍地重复同样的事情:
无法预测会花费多长时间,但是一切正常。
而在我看来!
当时,即使没有测试,该系统仍在为标准工作。 心态是,也许我在这里和那里都错过了一些用例,但是一段时间后它们会被重新发现,我会修复它们。
然后六个月过去了...
一开始,我开始将主干集成到我的开发分支中。 但是,没有人每天都进行小的更改,大多数情况下,一旦完成工作,这就是一个很大的更改。 我浪费了很多时间来解决冲突,而不是去编码,所以几个月后我放弃了。
最后,我意识到团队的其他成员在同一代码库的基础上开发了许多其他功能。 随之而来的冲突数量以及必须重写的功能数量使得任何合并都是不可能的。
此外,与此同时,另一位同事发布了客户模块的移动网络版本。 新客户模块中编码的许多业务规则也已在移动Web版本中编码。 台式机中的功能必须在移动设备中完全重写,从而使工作重复。
那是一场噩梦。
但这是有趣的事情:管理层并不期望这一点。
他们的期望是移动版本将轻松适应桌面需求,并且新的客户模块将成功发布。
但是,事情并没有按计划进行。
Customer Module项目变成了Vaporware,并且像Anti-Tank Dog一样被删除了。 它无法集成到主干中。
而且,新功能不会轻易适应移动版本。
仅仅浪费了6个月的工作。
客户模块已成为Vaporware ,其功能无法轻松移植到移动版本。
这是持续集成的重要性的一个清晰示例。
一开始,我尝试将主干合并到分支中。 但是,由于其他团队成员没有对主线进行小的更改,因此很难跟上。
如果我每天都将某些内容合并到主干中,那将迫使我和团队的其他成员尽早处理冲突,而不是让冲突积聚。
这将使包括管理人员在内的每个人都能更早地发现该代码与移动设备上的工作方式不兼容。 这样一来,他们就可以从一开始就更改整体策略,而不必等到达到无法采取其他措施的状态。
您可以将其称为“持续集成”,“基于主干的开发”,“ 尽早发布,经常发布 ”,“ 通过尽早连续交付有价值的软件来满足客户 ”或任何其他通用术语。
总而言之,这是重点:
避免不可逆的代码冲突的唯一方法是每个人都试图尽快合并。 最好是同一天多次。 如果有人花太长时间,他们只会在为时已晚时才看到问题。
那时我还没有今天的知识。 如今,事情将发生极大的变化,这些问题都不会发生。
我打错了电话。 因此,我是应该责怪的人。 没有人
回想起来,除了不断地集成代码外,我还可以想到一些可以通过不同方式来改进该过程的小事情。
我本可以避免个人主义。
在那个团队中,没有人练习过结对编程或Mob编程 。 没有人有足够的经验来看到好处。
如果我对此提出了建议并进行了尝试,或者至少了解了交流的好处,那么我们可能会知道每个人都在做什么。 我们早些时候已经发现,客户模块重写无法轻松地与移动版本集成,反之亦然。 也许那会让我们改变我们的编码策略和方式。
在编码之前,我本可以考虑更多。
少编码,多思考。 对于那些寻求“黑客”头衔的人来说,这是一种违反直觉的思维方式。 如果您只考虑编码,则只能成为Cowboy Coder 。
那正是我。
我不仅可以优化编程知识 ,还可以优化软件开发团队的工作方式。 作为开发人员, 我将是专业人士,将帮助您塑造组织 ,我必须对出错的地方负责。
我最终指责这一过程。 我最终指责手术刀 。
如果您从未遇到过这些问题,那么恭喜您。 通过他人的失败,您在软件开发中最重要的事情之一中学到了您的特权: 不要花太长时间来致力于他人的工作 。
如果您能够解决一个复杂的问题,您就不会聪明。 如果您可以从别人的错误中吸取教训,从而避免发生复杂的问题,那么您就很聪明。
互联网上充斥着成功的故事,有些人害怕暴露自己的失败。
我不是。
失败与成功一样好,区别在于现在您可以从中学到一些东西。
我没有失败。 我刚刚发现了10,000种行不通的方法。
- 托马斯·爱迪生
没有软件开发人员希望浪费6个月的工作,而我已经学到了这困难的方法。
希望这可以帮助其他人不要浪费6个月的时间,而这本来可以在6分钟内避免的。
希望…
另请参阅有关如何防止这些问题发生的技术 。
谢谢阅读。 如果您有任何反馈意见,请通过Twitter , Facebook或Github与我联系。
From: https://hackernoon.com/continuous-integration-a-merge-story-16d8c81b4077