软件项目失败的20个原因

企业网D1Net-Peter Wayner   2020-07-10

导读:由于各种各样的项目管理和技术因素,从过高的期望值到基本的特性更改,软件开发项目经常会偏离轨道,甚至是被宣布失败。



每一个软件项目都是从远大的梦想和宏伟的愿景开始的。或许在另一个世界的某个地方,的确会有一个项目可以实现每一个人的梦想,但是在我们的世界中,软件项目总是跌跌撞撞地走向终点线,有时甚至会越过它。


当然,根据定义,软件项目的失败并不总是非此即彼的事情。你可能会得到运行良好但没人使用的代码。或者你可能会得到不能编译的代码。有时你可以从燃烧的残骸中抢救出一些有用的东西,但最好在它爆炸前逃跑。


当闷热的烂摊子冷却下来,分析就开始了,因为人们想知道是什么地方出了问题。以下是最常见的罪魁祸首。


1. 过少的团队成员


用太少的程序员做太多的事情是一个常见的问题。开发人员在耗尽精力之前只能编写这么多的代码。我曾经在一个团队工作过,在这个团队中,经理认为从敏捷团队中挤出更多工作的正确方法是安排每个“sprint”,让它在前一个sprint之后就立即开始。没有深思熟虑的停顿来找出什么是有效的,什么是无效的。Sprint 42于周三下午1:59结束,Sprint 43就于周三下午2:00开始了。回顾性分析会议通常被安排在下一个sprint开始之后。一些聪明的家伙建议他们将其改名为“马拉松”,但很快就投入了另一份工作。


当然,很难知道究竟有多少程序员才是足够的。有时路障和问题会阻碍我们前进。工作量翻倍也许不是经理的错,但如果你没有足够的人手,你的项目就注定要失败。


2. 团队成员太多


如果太少的程序员可能是不好的,那么太多就可能会更糟,因为网络效应也可能会毁灭一个软件项目。更多的人意味着需要更多的协调,也就意味着更多的会议,它将占用原本编写代码的时间。但是如果你召开的会议不够多,你很快就会发现团队A的API不能与团队B的微服务进行衔接。


如果我们可以通过给项目配备过多的人员来砸钱解决问题,那当然很好,但你不能这样做。


3. 太多的沟通


编写软件是一门孤独的艺术。人类可以一起工作,但只能在有限的时间内。许多开发人员讨厌开会,因为他们需要将自己的思维从沉浸式的逻辑思维转向更开放、更社会化的模式。这需要时间。一些团队领导试图通过召开更多的会议来使每个人保持同步以对抗失败。这是一个崇高的努力,但你依旧可以听到齿轮的磨擦声。团队需要分享足够的信息来保持同步,但太多的信息只会浪费大脑周期。


4. 基本功能的变化


理论上,开发人员喜欢认为自己是敏捷的。这就是他们拥抱这个词的原因。但有时敏捷会让人失去平衡。这一切取决于这种转变是否需要对基础框架进行根本性的改变。当只是移动按钮或改变颜色时,很容易变得敏捷。但是,当涉及到需要重新编写数据库模式或处理分片和复制时,就没有一种简单的方法可以优雅地进行调整了。


5. 为工作选择了错误的技术


即使你仔细计划并制定了正确的特性列表,如果使用了错误的技术,事情也可能会失败。例如,数据库被设计为通用和灵活的,但是存在架构上的限制。推动他们去做一些他们不想做的事情,当他们被要求扩展时,他们就会放慢速度,甚至是停止。或者,你可能会开始使用NoSQL数据库,因为它们听起来很酷,但后来发现你确实需要ACID级别的事务来保持一致性,而数据库却不提供这些事务。


6. 缺乏优先级


好的规划者会列出一个特性列表,并对它们进行优先排序。但有时优先事项与实施它们的现实并不一致。在最糟糕的情况下,可能最重要的特性是最难创建的。


你的开发者该怎么做?如果他们专注于最重要的特性,他们将无法取得任何进展,并且可能最终无法交付任何功能。但是如果他们开始完成那些简单的特性,他们就可能会得到一些毫无价值的东西。


好的计划所需要的不仅仅是一张清单。对远景的架构必须考虑到需求和交付它们的成本。


7. 市场窗口的关闭


有时候这不是程序员的错。我曾经的一个项目是把一本最畅销的参考书变成一个应用程序。在互联网出现之前的几年里,这本书非常畅销。该公司计划利用这一需求,制作一个交互式的版本,让人们可以对数据进行排序和搜索。编程团队交付的软件包含了书中的所有内容,但比书本身更快、更漂亮、更轻。但是没有人想要它了。因为已经有足够多的其他来源了,没有人需要另一个应用程序来做几乎和新闻网站一样的事情。


有时候一个想法看起来很不错,但市场已经改变了。


8. 糟糕的架构决策


在一个项目中,我的任务是更改数据库中某一行中的一个数字。当用户完成注册后,我要将用户的id号添加到最新的订单中。听起来很简单,对吧?但是系统是建立在微服务架构上的,我不能通过编写一行代码来告诉数据库更新该列来解决这个问题。不行。架构的计划是在现有堆栈中添加一个新的微服务调用,即使这样做也很困难,因为我的第一个微服务调用需要触发另一个微服务调用等等。


最后,创建这个微服务网络的架构奇才告诉我,这一切都非常简单,并勾勒出了一条贯穿整个体系结构五层的蜿蜒路径。我的工作是向5个不同的微服务添加5个新的API调用,这也意味着需要为每个层添加5组自动化测试。这些年来,每个API都是由不同的团队开发的,这就要求我理解和模仿五种不同的编码风格。所有的一切就是为了改变一个数字。


架构决策可能会持续一生--尤其是当你的自我意识已经完全投入其中而你无法改变它的时候。项目经理必须时刻注意主架构何时会不起作用,并做出重大决策。


9. 政治冲突


将技术故障归咎于政治因素似乎有些含糊其辞,但事实已经越来越真实了。随着项目的扩大和跨越多个组织,出现派系和团队来争夺控制权、资源和最终权力也就不足为奇了。


政治派系不同于真正的技术差异。通常有一些技术标准或代码库会以不同的方式做同样的事情。以XML和JSON为例。我能感觉到这两种技术的粉丝都急于解释为什么它们不一样,以及为什么他们最喜欢的选择是正确的。但是当一个团队的一部分喜欢一个选择,而另一部分则最尊重有竞争关系的另一方时,摩擦就会把他们分开。


随着架构师将应用程序拆分为多个更小的服务和API,这种情况将变得更加常见。不同的团体最终会控制这些,但他们不会总是和睦相处。如果A组喜欢JSON,而B组喜欢XML,那么你的团队要么需要同时实现它们,要么更改其中一个。所有这三种情况,对于必须同时与A组和B组合作的团队来说都是一种痛苦。


10. 押注于还没有准备好投入生产的技术


程序员喜欢最新的工具和框架。他们愿意相信,新方法将扫除上一代人遗留下来的所有糟粕。


但通常情况下,下一代的技术可能还没有准备好投入生产。新功能或许看起来很完美,但通常会有一些不太明显的缺陷。有时代码只支持少数的文件类型,或者只支持几个数据库的接口。他们向你保证,其他产品很快就会推出,但是你的项目需要在这个月就发布,而“很快”则可能意味着需要6个月或更多的时间才能完成所需的特性。


11. 押注于即将过时的技术


根据我的经验,旧的技术通常更可靠,更经得起考验,但这并不意味着旧技术是完美的。即使软件项目已经投入使用,也可能会缺少对软件项目至关重要的特性。更糟糕的是,押注于老技术可能会让你错过未来可能出现的变化。新的思想、协议和文件格式出现了,但它们可能还无法实现。如果竞争团队的某个人坚持认为你应该支持某种新协议,那么旧的技术将会带来伤害。


12. 不切实际的截止日期


截止日期是棘手的。许多项目需要在特定的季节或事件之前进入市场。然而,当第一次写下截止日期时,开发人员可能还没有发现他们前进道路上的障碍。然后,如果项目失败,并且没有启动软件,事件就过去了,那么整个项目就会被视为失败,即使代码已经准备好顺利运行。截止日期可以帮助每个人集中精力,齐心协力,但也可能会让人产生不切实际的期望。


13. 无法预见的竞争


一个好的产品经理在进入市场之前会调查竞争情况,但是没有人能预测什么样的竞争会突然出现。如果新的竞争对手引入了你必须复制的新特性,请参阅上面关于特性更改和优先级不匹配的部分。


14. 匆忙的流程


许多软件项目都是从想要修复某些东西的个人或团队的愿景开始的。他们可能会想出“Snapchat for Y”或“Uber for Y”这样的短语,然后就期望产品团队能像Snapchat或Uber一样反应迅速。问题在于,确定项目的范围、描绘数据流和设想UI的工作量通常是编写代码的十倍。而幻想家们想要马上将想法变成代码。


线框图、数据库模式和用户描述不是一蹴而就的,而是工作中必不可少的一部分。但大多数人认为软件项目只是编写代码来实现一个想法而已。


15. 错误地相信软件的力量


梦想家常常对软件改变世界的力量抱有不切实际的信念。很多人以为社交媒体会把我们团结在一起,但不知为何,它只是暴露了一直以来都很明显的断层线。软件项目通常是以幻灯片开始的,这些幻灯片承诺将彻底改变世界的某个角落。然后,当向数据库中塞入数据并不能改变任何人时,人们就会感到愤怒、无聊、困惑甚至更糟。他们说,这个软件被破坏了,因为它未能实现大家所期待的神奇转变。


许多软件项目可以编译、通过QA、发布,甚至获得不错的评审,但却最终未能实现幻灯片上的任何承诺,因为那些改变世界的承诺是不可能的。


16. 邪恶的分包商


我们喜欢那些提供库和工具的厂商,这些库和工具使得我们只需要使用几行代码就能创造奇迹。但是偶尔,他们会听到自己的力量,并利用它来摧毁一个项目。版本1.0的预算表非常好,以至于管理层会毫不犹豫地批准版本2.0。然后供应商就可能会通过三倍或五倍的价格来挤压我们。


即使供应商不是故意这样做的,也可以感受到这种影响。免费的库可以让一个项目看起来非常便宜。然后,当需求飙升,第二个版本扩大了需求时,实际价格就会开始上升了。


17. 翻天覆地的巨变


在大流行和抗议的一年里,没有什么比时代精神改变得更快了。该项目是否将强大的隐私保护作为了一个核心特征?唉。大流行使得每个人都对追踪接触者感兴趣了。有人想专注于商务旅行吗?唉。酒店业已经崩溃了。需要一年或更长时间的大型软件项目可能有被灾难性事件中断的风险。一开始看起来似乎是个很不错的想法,但到了要付诸实践的时候,就可能会变得毫无希望、毫无意义。


18. 技术迁移


不仅仅是世界的变化。科技界的潮流变化也会产生同样的效果。NoSQL曾经是一个天才的想法,它能够将我们从关系模式中解放出来。然后又有人意识到文件的膨胀是因为每个记录都带有一个本地模式。虽然一个好的敏捷开发团队可以在技术的巨大变化改变领导层和客户的态度时进行调整。但是即使是最敏捷的团队也不能处理那些会把他们的架构计划全部搞垮的重大变化。这个系统是建立在假设X是一个好主意的前提下的,而在突然之间X变成了一个垃圾。或许有时候最好的选择是把它炸掉,然后再重新开始。


19. 太多附庸


一些软件项目的起步很好,甚至被成功地发布了。然后就会有人添加了一到三个额外的特性,将新代码移植到现有的版本上,使代码继续蹒跚前行。英勇的开发人员可能会多次实现这个目标,特别是在最初的架构师计划良好的情况下。但是在某个时候,基础就崩溃了。可能是数据库无法处理负载。可能是需要太多连接来满足各种查询。好的软件可能会变得过于臃肿,有时只是因为一些小小的改进把它推到了边缘。


20. 目标的改变


最初的计划是建立一个数据库来跟踪客户支出,以帮助制定营销计划。后来,一些天才又增加了一个功能,试图利用人工智能来将消费与天气预报联系起来。或者有人想让这个软件自动为搜索引擎广告出价。改变目标也可能会颠覆一个项目。


很少有变化会自己毁掉一切。但是新的目标可能会揭示弱点并触发失败的模式。也许是这个团队现在太小了,无法成功地完成这个项目。也许是其技术基础对于新方法来说非常低效。总之,当决定改变目标时,每个人都会很难预料到这些烦躁的组合。