项目已接近完成,但程序上有意粉代码。我要重写还是继续尝试发送?[关闭]


242

我是一名初学者Web开发人员(一年的经验)。

毕业几周后,我得到了一份工作,为一家所有者不是很多技术人员的公司构建Web应用程序。他招募我是为了避免他的想法失窃,服务公司收取高昂的开发成本,并希望他有一个年轻的人来长期维护该项目(我被录用后很久才得出这些结论)。

当时我还是Cocky,拥有计算机科学文凭,我接受了这个提议,认为我可以构建任何东西。

我在做主。经过一些研究,我选择了PHP,并从纯PHP开始,没有对象,只有丑陋的过程代码。两个月后,一切都变得混乱了,很难取得任何进展。Web应用程序非常庞大。因此,我决定检查一个MVC框架,这将使我的生活更轻松。那就是我偶然发现PHP社区中一个很酷的孩子的地方:Laravel。我喜欢它,它很容易学习,因此我立即开始编码。我的代码看起来更简洁,更有条理。看起来很好。

但是同样,Web应用程序非常庞大。该公司迫使我交付第一个版本,显然他们希望部署该版本并开始寻找客户。

因为Laravel很有趣,所以让我想起了为什么我首先选择了这个行业-在陷入糟糕的教育体系时我忘记了这一点。

因此,我从晚上开始从事小型项目,了解方法和最佳实践。我回顾了OOP,然后进行了面向对象的设计和分析,并阅读了Bob叔叔的Clean Code

这使我意识到我真的一无所知。我不知道如何正确地构建软件。但是到现在为止为时已晚,现在我快完成了。我的代码根本不是干净的,仅仅是意大利面条式的代码,是修复错误的真正痛苦,所有逻辑都在控制器中,并且几乎没有面向对象的设计。

我一直坚持认为我必须重写整个项目。但是,我做不到……他们一直在问什么时候才能完成。

我无法想象此代码部署在服务器上。另外,我仍然对代码效率和Web应用程序的性能一无所知。

一方面,公司正在等待产品,不能再等待了。另一方面,我看不到实际代码会更进一步。我可以完成,总结并部署,但是上帝只知道人们开始使用它时会发生什么。

我要重写还是继续尝试发送,还是错过了另一个选择?


142
按照开始的方式完成操作,并清理下一版本中的技术债务(如果有)。你的老板不知道有什么区别。确保测试良好。
罗伯特·哈维

45
“但是上帝只知道人们开始使用它时会发生什么。”…这就是软件开发的乐趣。更好地习惯它;)
直线加速器

144
这将是您构建的每个系统。
解散2014年

57
软件永远不会完成,一旦您关闭它,您将始终拥有洞察力,这使您想将整个代码库丢到窗外。别。交付一个有效的产品,然后掌握重构的技巧。这将是一个宝贵的教训。
Pieter B

14
我父亲曾经告诉我:“有时您必须射击工程师并运送。”
corsiKa 2014年

Answers:


253

您偶然发现了大多数CS教育的致命弱点:他们教给您工具和技术,但不教您交易。构建软件是一种技巧,只有通过多年的实践和使用软件的经验,才能获得这种技巧(用户比老师更严厉的批评者)。构建软件通常也是一项业务,业务目标可能会超越技术野心。

首先,运送。如果您向业务所有者显示该软件,并且他们认为该软件已准备好发布,则可以进行发布。如果不是那个时候,但是结束,完成它。唯一重要的软件是实际使用的软件。唯一赚钱的软件业务就是拥有产品的业务。

其次,您已经学到了很多有价值的东西,因此您应该感谢它所教给您的经验:

  1. 没有计划或架构的代码悬挂是灾难的根源
  2. 编程比编写代码要多得多
  3. 非技术企业所有者通常不了解技术决策的影响(例如聘请谁),并且由开发人员向他们解释事情。
  4. 在现有框架中,大多数问题已比您解决的问题好得多。了解存在的框架以及何时使用它们是值得的。
  5. 刚从学校毕业的人们在很少的指导下被分配到一个大项目中,往往会产生一碗意大利面条代码。这很正常。

以下是一些有关如何继续的建议:

  1. 交流,交流,交流。即使您不确定并看到多条路径,您也必须非常坦诚,坦诚地了解项目的状态以及如何进行的想法。这使企业所有者可以选择做什么。如果您对自己保留知识,则会剥夺他们的选择权。
  2. 抵制完全重写的诱惑。重写时,该业务没有产品。另外,重写很少能像您想象的那样好。而是选择一种体系结构并将代码库逐步迁移到该体系结构。即使是可怕的代码库也可以通过这种方式来挽救。阅读有关重构的书籍,以帮助您。
  3. 了解有关自动化测试/ 单元测试的信息。您必须建立对代码的信心,而这样做的方法就是用自动测试覆盖它。这与重构息息相关。只要您没有测试,就可以手动进行全面测试(尝试破坏您的代码,因为您的用户会这样做)。记录所有找到的错误,以便您可以对它们进行优先级排序和修复(您将没有时间修复所有错误,在现实世界中没有任何软件可以消除错误)。
  4. 了解有关如何部署Web应用程序并使之保持运行状态的信息。《Web操作:保持数据准时》一书是一个好的开始。

4
非技术商人要牢记自己的想法,无论如何也不会理解技术。由开发人员决定向他们提供具有成本和收益的技术上可行的选项(这涉及到众所周知的困难和普遍讨厌的事情,例如学习估计任务将花费多长时间)。
2014年

1
在这种情况下,可能需要完全重写-如果他基本上将第一个版本用作培训工具,则第二个版本将是“他应该写的一个版本”。我认为在所有其他情况下,重写都是不好的建议,但这里不是。不适用于编写代码的人,但他并不真正知道自己在做什么。请注意,修复它应该是另一个绝佳的培训机会!
gbjbaanb 2014年

2
我有一个可行的理论,即“每条生产代码至少要重写一次”。到目前为止,就我的专业经验而言,无论是从宏观(体系结构)还是从微观(方法)层面来讲,这都是非常真实的。诀窍是学习何时适当使用这些重构。
zourtney

11
+1为第一点。记住大家,运输也是一项功能
thegrinner 2014年

5
如果您的嘘声喜欢该网站,那就完成了。你的老板便宜了,并雇用了一个新的大学毕业生。他要么知道自己会得到什么,要么应该接受教育。您的软件存在错误。忍受它。大家都这样做。您比一年前聪明。要求加薪,或找到新工作(都不错)。如果您正在寻找新工作,请务必选择一个可以从中学习良好习惯的团队的雇主。
SeattleCplusplus 2014年

114

这听起来像是其他要扔给我修复的系统。

放松,这发生在很多人身上。没有经验,没有帮助,没有支持,没有指导的初级人员并不是成功的秘诀。雇用并期望初级程序员从头开始构建一个全新的系统,该系统运行良好,性能良好且可维护,这是不现实的。如果所有这些事情都发生在高级程序员身上,那真是太幸运了。

我认为您必须保持清洁。这不会很有趣。告诉他们您已经尽力了,它可以工作(大多数情况下),但是您担心它可能无法很好地执行,并且会出现很多错误(总是存在错误)。需要高级程序员对其进行审查,并且他们应该能够很快解决所有明显的性能/安全性问题。或者他们可以部署它并交叉手指。会变好,或冒烟。也许您可以在问题出现时解决问题。如果您拥有庞大的用户群,则可能没有。

或者,您可以在这种情况下做大多数人要做的事情:拿走钱,消失,让他们整理。我将由您自己决定什么是道德选择。

编辑(因为这个问题有很多票,我不妨增加一些内容)

成为程序员的部分乐趣在于,非技术人员(可能是您的经理,当然还有其他业务人员)根本不知道您做什么。这是好是坏。不好的部分原因是您必须不断解释软件开发项目的工作方式。计划,需求,代码审查,测试,部署和错误修复。解释测试的重要性并预留时间进行测试是您的工作。你必须在这里站稳脚跟。人们不会理解其重要性(“难道我们不能开始使用它吗?”),但一旦他们开始进行测试(而不是在实际环境中!),他们将很快了解其好处。他们之所以雇用您的原因之一是因为他们对软件开发一无所知,因此,由您来教育他们。您需要在此处强调测试和错误修复的重要性-请记住,他们不是程序员,他们不知道被零除和损坏的html标记之间的区别。

通常出现的许多问题实际上并不是错误。它们将是可用性问题,遗漏的需求,已更改的需求,用户期望(为什么我不能在手机上使用它?),然后是实际的实际错误。在上线之前,您需要解决这些问题-几天后通常可以解决或修复许多错误。如果人们期望一个完美的系统,那么他们将遭受很多痛苦。如果他们期待错误,那么在接下来的几周内您的生活将会变得更加轻松。

哦,不要将用户测试与单元测试或系统测试混淆。

  • 单元测试-我的代码功能是否返回正确的值
  • 系统测试-单击X时会引发错误吗
  • 用户验收测试(UAT)-程序是否符合要求?它会按照他们要求您执行的操作吗?它可以上线吗?

如果您没有写下他们要求您做的要求,那么UAT将会困难得多。这是很多人倒下的地方。将他们希望系统完成的工作写下来,将使您的生活变得更加轻松。他们会说“为什么不做X?” 您可以说“您告诉我让它做Y”。如果程序错误,请修复它。如果要求有误,请修复文档,再多花一两天(否,请坚持执行),进行更改,更新文档并重新测试。

完成几次该过程后,您就可以开始研究敏捷..但这是另一个世界:)

TL; DR 测试良好


7
真实而典型。我要说的是,离开公司显然是合乎道德的,管理该项目的劳动力不是新手初级的问题,因此我绝对会理解是否有人因此离开。
CsBalazsHungary 2014年

1
+1表示大多数人会拿走钱然后消失。这种事情使顾问保持工作。
James_pic

这里不是很好的测试定义。单元测试验证单元的技术规范,集成测试验证端对端系统的技术规范,验收测试(带有或不带有“用户”)验证产品的业务规范。“系统测试”可能意味着除单元测试以外的几乎所有其他内容。验证返回值在单元测试中并不总是必需的或有用的,很少有好的自动UI测试只有在系统“抛出错误”时才会失败。
2014年

“解释测试的重要性并留出时间进行测试是您的工作。” 我不是一个“真正的”程序员,但是我能解释的最好方法是车床操作员的机器上没有一套卡尺。他唯一知道自己做坏事的方法是当QC检查并告诉他错了时。如果您没有质量控制,也没有单元测试,那就像盲目地加工零件并将其发送出去。就像其他任何行业一样,如果您无法测试产品,就无法知道所运送的产品是否还能工作。
user2785724

@ user2785724-如果您正在编写代码,那么您就是一个真正的程序员。也许您的经验较少,但这并不能使您成为一名编码人员。
罗克兰

61

每当您从头开始时,由于Second System Syndromme,几乎可以肯定会犯同样数量或更多的错误。您的新错误将有所不同,但调试所需的时间将相似,因此对它的不合适方式将感到绝望。如果部署了第一个版本,还将延迟部署到生产中或新功能的部署,这将给公司造成严重麻烦。乔尔·斯波斯基(Joel Spolsky)称其为任何公司或开发人员都可能犯的“最严重的战略错误”

推荐的方法是在维护过程中一点一点地清理初始混乱。而且甚至不要仅仅为了它而尝试重构它。此外,管理人员通常认为这是浪费金钱(通常是浪费金钱),并且带来了引入新错误的不必要风险。一旦您痛苦地调试了代码,它可能看起来并不漂亮,但是它将起作用。因此,直到您出于其他原因需要触摸它(无论是错误修复,新功能还是只是市场营销要求的更改)而已。然后清理最难调整的零件。这通常称为童子军规则

在这一点上,您不必与经理争论。只需在请求的估算中包括最小的期望重构即可。您将通过经验中学到东西,因为该公司确实处于修复状态,并且您不想在将来制造问题并且只是不承认有可能迅速破解它时,您可能会从中获得收益。

最后,再推荐一本:《泥泞大球》


1
+ long.MaxValue为c2.com/cgi/wiki我喜欢这个网站,尽管它似乎有点死。
AnotherUser 2014年

4
我从来没有听说过Joel Spolsky,但是我花了一个固定的时间阅读了他的一些博客文章。他绝对好笑,而且知识渊博。
亚当·约翰斯

9
@AdamJohns:但是您正在使用他的软件。马上。他是该网站背后的主要人物。
2014年

1
@JanHudec他和阿特伍德。
jpmc26 2014年

5
最终,其他人在访问此站点之前从未听说过Spolsky。通过阅读这里,您会认为他是第二位。
MDMoore313 2014年

29

我忘了我第一次读的地方,但我只是想以更有力的方式回应别人说的话:

送货是一项功能。

没有什么比让一个人继续“清理”现有的(可能是骇人的,丑陋的,肮脏的)代码的人更糟糕的了,它们可以很好地工作,引入新的错误等。在现实世界中,重要的是要完成您的工作。你已经做到了。船。即使项目看起来很丑陋,也不要因为它的完美表现而对它进行重新设计。修复它时,请逐步进行修复,并使其成为一个良好的测试套件,以使回归尽可能少。


不确定它是否是真正的原始书,但是这篇文章是Google的第一本热门文章。当然,作者是Joel(他在该主题上写了很多文章,并且写得很好)。
Jan Hudec

24

每个项目都使您比以前更聪明。在完成每个项目之后,您将积累更多的经验,而从一开始就拥有它会非常方便。我知道很难不重访所有内容并运用所学知识。但要记住:

完美是善的敌人。

对于客户而言,拥有一款永远不会发布的完美软件总比拥有一款优秀的软件好。

这只是您的第一个项目。将来会有更多项目,您可以一开始就应用所学到的一切。


15

我读了叔叔的鲍勃干净代码。

我一直坚持认为我必须重写整个项目。

本书的一节非常恰当地命名为“空中重新设计”。

不要尝试重写所有内容,因为在极有可能发生的情况下,无论如何您都会面临同样的问题。完成重新设计后,您将学到新知识,并且会意识到它的第一部分是非常专业的,因此您将需要重新编写它。

重新设计和重写是好的,但前提是必须在工作系统上逐步完成它们。正如另一位用户指出的那样,请遵循童子军规则,在处理代码时会一点一点地对其进行重构。


6
确实如此。十年来,我一直在迭代同一个代码库的设计,但我仍然认为我去年所做的体系结构很糟糕。您永不停止学习。
Joeri Sebrechts 2014年

1
需要澄清的是,使增量改进可行的原因是,您进行了大量测试,使您确信自己没有破坏现有功能。如果您发现自己想“我无法改变”,那么您就已经确定了需要测试覆盖的地方。
PhilDin

9

你做得很好。

您说您的代码有效,并且几乎可以交付了,对吧?而且您认为您的代码可能会大大改进。好。

您的困境使我想起了我的自由职业经历(我在uni的第二年就被聘用来创建一个多语言的POS系统)。我经历了无休止的询问,因为我从未对代码感到满意,想要可伸缩性,想要重新发明更好的轮子……但是我只是推迟了该项目(例如,大约延迟了12个月),……又是什么呢?一旦部署了东西,它仍然需要大量的证明,测试,修补等。

您是否有使用专业代码库的经验?许多代码库充满了古怪,难以维护的代码。通过尝试自己构建一个大型程序来发现软件复杂性的另一种方法是维护/扩展其他人编写的同样混乱的代码。

我看到完全重写的唯一好处是,团队同时采用了新的工具链/框架。

如果基本逻辑(程序的功能,而不是函数,类的布局方式等)是合理的,则它的效果也一样好,因此,您认为它是意大利面条式代码并不意味着它不应该部署。

您需要让客户拥有可以使用的东西。然后,当他们要求您进行改进/添加功能时,您可以决定是否需要进行重构,并且可以让客户知道“集成所述新功能需要一些技术工作”。他们将由此了解到,这将使他们付出更多的钱,并且他们将不得不等待更长的时间。他们会理解(或者您可以退出)。

重写所有内容的更好时机是当另一个客户要求您创建类似内容时。

简而言之,除非您能证明部署完成后整个过程都会浮出水面,否则延迟部署将是不专业的,不会使您或您的客户受益。学会在修复错误或添加新功能时进行小的重构,这对您来说将是宝贵的经验。


7

在回答您的问题时,我所说的大部分内容都是别人说的。阅读Joel Spolsky撰写的“您不应该做的事情,第一部分”(以及他有关“建筑宇航员”的其他一些文章)。记住“完美是善的敌人”。学习逐步重构。运输很重要,等等。

我要补充的是:您要承担的任务是,只有一个刚毕业的毕业生使用少量的启动预算/时间框架就可以做到。除了良好的,结构化的过程编程之外,您不需要任何更复杂的东西。(而且,仅供参考,“过程编程”并不是一个坏词。在大多数情况下,这在一定程度上是必要的,并且对于许多整个项目而言,这是完全足够的。)

只要确保您确实进行了结构化的程序编程即可。代码中的重复不一定表示您需要宏大的多态结构。这可能只是一个信号,表明您需要使用重复的代码并将其放入子例程中。“意大利面”控制流可能只是摆脱全球化的机会。

如果项目的某些方面合理地要求多态性,实现继承等,那么我建议也许项目的规模被低估了。


4
我要补充一点的是,意大利面条代码不仅限于程序代码。不正确地使用多态性和继承性会导致混乱,这比许多复杂的程序片断更难理解。使用定义不正确的过程或在复杂的类层次结构中进行继承,控制流是否会遍及整个位置都无关紧要;它仍然到处跳跃,很难跟随。
Jan Hudec

4

如果您真的对自己所面临的困境感兴趣,则还应该阅读“精益创业”。如果您读过这本书,这里给您的许多建议都会引起您的共鸣。基本上,资源消耗率是您最大的敌人,对您和您的组织而言,没有什么比最终用户/客户反馈更有价值。因此,将您的产品设置为可行状态(最低可行产品-或MVP),然后将其发货(与代码的实际外观无关)。让您的客户决定您将来的变更集和版本,而不是相反。如果您专注于这种方法,从长远来看,您和您的老板都会更快乐。


4

出于其他人已充分解释的原因,现在该结束并交付该项目了,这可能会很痛苦。

我只想强调,测试应用程序也是“完成”它的一部分。如果尚未彻底行使重要的功能并确认正确的结果,那么您有理由担心在部署此应用程序时,人们会遇到麻烦。

单元测试和自动化的更高级别的测试非常棒,在尝试重构(或重写)此应用程序之前,应尽可能多地进行这些工作。但是,即使您必须“手动”运行每个测试并“目测”确认正确的功能,现在您仍然主要需要对其进行测试。如果您以后能弄清楚如何使这些测试自动化,那么这将在下一个版本的产品开始工作时有所帮助。

有些人有技巧要以alpha测试用户的身份坐在新软件项目的前面,并使事情出错。也就是说,他们擅长破坏事物。如果您有幸与这样的才华横溢的人一起工作,请让他们首先试用该应用程序,这样您就有机会及早修复所有明显的错误。如果您必须自己执行此任务,则:

  • 有条理。
  • 尝试所有功能。
  • 假设您是您的应用程序缺乏经验的用户。做出愚蠢的错误,并查看软件如何处理它们。
  • 写下您正在做的事情,这样您就可以在解决问题后再次尝试。

我完全同意这一点。也不要忘记在生产中进行手动测试。无论您在开发环境中进行了多少测试,每次部署之后,始终需要在实时环境中进行完整性测试。您可以请同事帮忙。
Will Sheppard 2015年

1

您的问题是:“开始错误,我应该重新开始”,而其他文字实际上是“完成的项目,但是做错了,我应该重新开始”。仅对于标题问题:如果您完成的编程工作量与所需的总工作量相比很小,那么重新开始就很有意义。当问题很复杂且理解不充分时,会发生很多事情,并且花了很多时间弄清楚问题的实质。毫无意义的继续进行不好的开始,如果丢掉它并重新开始,这一次对问题有充分的了解,这意味着您实际上会更快地完成。


0

这是我个人要做的:

  1. 辞职,找个借口,放弃(你甚至可以还掉一部分薪水,这样你就不会看起来很糟)
  2. 尽可能清理您的代码
  3. 记录工作中所有好的方面,例如好的设计,好的想法等。

为什么我建议所有这些?

因为考虑未来。将来会有一段时间某些人会掌握此代码。他们将对您和您的能力做出各种假设和判断。他们不在乎你写的时候,他们不在乎情况。他们只想在其中看到想要确认的内容即可。

您会被贴上任何不好的名字的烙印,他们会想出对您造成负面影响的术语。即使将来的您在技术能力,技能,知识,风格和情况方面可能完全不同,但此代码将以各种可能的方式对您不利。就像法院一样,他们可以说出关于您以及您的代码和设计的所有坏消息,而您甚至不知道它,因此您可以自己解释和辩护。(而且您可能经常会发现他们反复犯错),所以不要这样做。放弃。

相信我,有些人对您有很多假设,因为您在任何时候出于任何目的都做了一些事情。对他们来说,如果您在情况A中这样做,您将在情况B中这样做。他们认为非常简单。


0

还有两个建议,我敢打赌,至少有一个您没有做过。

1)放置一个错误跟踪器,并教您的老板使用它。这可能是关于如何精打细算,学得更好并且将有计划地修复它的对话的一部分

2)开始使用版本控制,尽管希望您已经这样做了。

那里有大量托管系统,这些托管系统可以在小型帐户上免费提供上述两种服务。我特别喜欢FogBugz,它还有一个出色的估算和任务完成系统,它将使您的老板更加确定自己以一种管理良好的方式处理问题。

编辑

哇,有人真的不喜欢这样-降票和删除标志吗?为什么?

我从事软件开发已经三十多年了,其中包括大量的咨询工作和继承他人的代码。我见过的很多问题系统都是人们在这里挖坑的,没有详细说明他们如何到达那里,也没有版本控制。


-2

回答您的问题:正如许多其他人所说,不。运送它,并在修复错误的过程中一点一点地清理它。

此外,尽管book / StackExchange / webforums是很好的学习资源,但您可能会发现,没有什么可以比得上与其他程序员一起工作(甚至只是讨论工作)所学到的知识。找到并参加您正在使用或想要学习的技术的本地团队是您宝贵的时间投入。除了要获得的技术知识外,这也是一种轻松的人际网络方式,在您期待未来的演出时,这是无价的。


-2

您的老板雇用您时就知道您的经验水平。只需表达您的担忧,并让他知道您对此感到紧张。还让他知道您学到了多少,以及可以做下一个项目有多好。


-2

您是一个刚开始的Web开发人员,没有好的开发人员可以为您提供建议,您的老板雇用了您对此非常了解。我认为您的表现与任何人期望的一样好。实际上,您具有这样的洞察力:工作本可以做得更好,并且您实际学到了可以做得更好的事情,这意味着您比大多数人都做得更好。请记住,出于您的理智,开始工作的您的版本不可能做得更好。更有经验的人(因此报酬更高),或者您拥有一个项目的经验值,可能会做得更好。

现在要做的事情:很高兴自己比一年前做的更好。下一个项目会做得更好(最后,您将再次变得经验丰富,对所做的工作不满意;这是正常的)。更改或重写最后一个项目将使业务从成本中受益甚少。您所要做的就是在需要进行更改时以良好的代码替换不良的代码。这是有道理的,因为修改可维护性差的代码比用好的代码替换它更难。而且,如果您有经验不足的新开发人员来帮助您,请告诉他们代码不是他们应复制的示例。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.