我是一名初学者Web开发人员(一年的经验)。
毕业后几周,我被提供一份工作来为一家所有者不是公司的公司构建Web应用程序很多技术人员。他招募我是为了避免他的想法被盗用,服务公司收取高昂的开发成本,并希望他有一个年轻的人来长期维护该项目(我被聘用很久以后才得出这些结论) )。
我当时很自负,拥有计算机科学文凭,我接受了这个提议,认为我可以构建任何东西。
我在做主。经过一些研究,我选择了PHP,并从纯PHP开始,没有对象,只有丑陋的过程代码。两个月后,一切都变得混乱了,很难取得任何进展。 Web应用程序非常庞大。因此,我决定检查一个MVC框架,这将使我的生活更轻松。那就是我偶然发现PHP社区中一个很酷的孩子的地方:Laravel。我喜欢它,它很容易学习,因此我立即开始编码。我的代码看起来更整洁,更有条理。看起来非常好。
但是Web应用程序仍然很大。该公司向我施加压力,迫使他们交付显然要部署的第一个版本,并开始寻求客户。
因为Laravel很有趣,所以让我记得为什么我选择了这个行业。首先-我在糟糕的教育系统中忘记了一些事情。
所以我晚上开始从事小型项目,了解方法和最佳实践。我重新审视了OOP,着手进行面向对象的设计和分析,并阅读了Bob叔叔的书Clean Code。
这使我意识到我真的一无所知。我不知道如何正确地构建软件。但是到现在为止为时已晚,现在我快完成了。我的代码根本不是干净的,只是意大利面条式的代码,修复错误的真正痛苦,所有逻辑都在控制器中,并且几乎没有面向对象的设计。
我拥有这种持久性以为我必须重写整个项目。但是,我做不到……他们一直在问什么时候才能完成。
我无法想象将这段代码部署在服务器上。另外,我仍然对代码效率和Web应用程序的性能一无所知。
一方面,公司正在等待产品,不能再等待了。另一方面,我看不到自己对实际代码有任何进一步的了解。我可以完成,包装和部署,但是上帝只知道人们开始使用它时会发生什么。
我重写还是继续尝试发货,还是我有其他选择?错过了吗?
#1 楼
您偶然发现了大多数CS教育的致命弱点:他们教给您工具和技术,但不教您交易。构建软件是一种技巧,只有通过多年的实践和使用软件的经验才能获得(用户比老师更严厉的批评家)。构建软件通常也是一项业务,业务目标可能会超越技术野心。首先,交付。如果您向企业主显示该软件,并且他们认为该软件已准备好发布,则可以发布。如果不是那个时候,但是结束,完成它。唯一重要的软件是实际使用的软件。唯一赚钱的软件业务就是拥有产品的业务。
其次,您已经学到了很多有价值的东西,因此您应该感谢它所教给您的经验:
没有计划或架构的代码吊销是灾难的根源
编程之外,编写代码要比编写代码要多得多。
非技术企业主通常不理解技术的影响决定(例如聘请谁),并由开发人员向他们解释。
在现有框架中,大多数问题已经比您解决问题要好得多。知道存在的框架以及何时使用它们是值得的。
刚从学校毕业的人们在没有任何指导的情况下被分配到一个大型项目中,往往会产生一碗意大利面条式的代码。这很正常。
这里还有一些关于如何进行的建议:
沟通,交流,沟通。即使您不确定并看到多条路径,您也必须非常坦诚,坦诚地了解项目的状态以及如何进行的想法。这使企业所有者可以选择做什么。如果您对自己保留知识,则会剥夺他们的选择权。
抵制完全重写的诱惑。重写时,该业务没有产品。另外,重写很少能像您想象的那样好。而是选择一种体系结构并将代码库逐渐迁移到该体系结构。即使是可怕的代码库也可以通过这种方式来挽救。阅读有关重构的书籍以帮助您。
了解有关自动化测试/单元测试的信息。您必须建立对代码的信心,而这样做的方法就是使用自动测试来覆盖它。这与重构息息相关。只要您没有测试,就可以手动进行全面测试(尝试破坏您的代码,因为您的用户会这样做)。记录发现的所有错误,以便可以对它们进行优先级排序和修复(您将没有时间修复所有错误,在现实世界中没有任何软件可以免费发布错误)。
了解如何部署Web应用程序和保持运行。 《 Web操作:保持数据准时》这本书是一个不错的开始。
评论
非技术商人要牢记自己的想法,无论如何也不会理解技术。由开发人员决定向他们提供具有成本和收益的技术上可行的选择(这涉及到众所周知的困难和普遍讨厌的事情,例如学习估计任务将花费多长时间)。
– Jan Hudec
2014年7月15日在7:50
在这种情况下,完全重写可能是合适的-如果他基本上将第一个版本用作培训工具,则第二个版本将是“他应该写的一个版本”。我认为在所有其他情况下,重写都是不好的建议,但这里不是。不适用于编写代码的人,他实际上并不知道自己在做什么。请注意,修复它应该是另一个绝佳的培训机会!
– gbjbaanb
2014年7月15日14:56
我有一个可行的理论,即“每条生产代码至少要重写一次”。到目前为止,以我的专业经验来看,无论是从宏观(架构)还是从微观(方法)层面来讲,这都是非常真实的。诀窍是学习何时适当使用这些重构。
–zourtney
2014年7月15日在17:55
+1为第一点。记住大家,运输也是一项功能。
– Thegrinner
2014年7月17日在11:59
如果您的嘘声喜欢该网站,那就完成了。你的老板便宜了,并雇用了一个新的大学毕业生。他要么知道自己会得到什么,要么应该接受教育。您的软件存在错误。忍受它。大家都这样做。您比一年前聪明。要求加薪,或找到新工作(都不错)。如果您正在寻找新工作,请务必选择一个可以从中学习良好习惯的团队的雇主。
–西雅图Cplusplus
2014年8月23日在18:42
#2 楼
这听起来像是要扔给我修复的所有其他系统。放松一下,很多人都会遇到这种情况。没有经验,没有帮助,没有支持,没有指导的初级人员并不是成功的秘诀。雇用并期望初级程序员从头开始构建一个全新的系统,该系统运行良好,性能良好并且可维护,这是不现实的。如果所有这些事情都发生在高级程序员身上,那真是太幸运了。
在我看来,你必须变得整洁。这不会很有趣。告诉他们您已经尽力了,它可以工作(大多数情况下),但是您担心它可能无法很好地执行,并且会出现很多错误(总是存在错误)。需要高级程序员对其进行审查,并且他们应该能够很快解决所有明显的性能/安全性问题。或者他们可以部署它并交叉手指。会变好,或冒烟。也许您可以在问题出现时解决问题。如果您拥有庞大的用户群,则可能没有。
或者您可以在这种情况下做大多数人所做的事情:拿走钱,消失并让他们整理。我将由您自己决定什么是道德选择。
编辑(由于这个问题有很多票,我不妨再增加一些内容)
成为程序员的部分乐趣在于,非技术人员(可能是您的经理,当然还有其他业务人员)根本不知道您做什么。这是好是坏。不好的部分原因是您必须不断解释软件开发项目的工作方式。计划,需求,代码审查,测试,部署和错误修复。解释测试的重要性并预留时间进行测试是您的工作。你必须在这里站稳脚跟。人们不会理解其重要性(“难道我们不能开始使用它吗?”),但是一旦他们开始进行测试(不在实时环境中!),他们将很快理解其好处。他们之所以雇用您的原因之一是因为他们对软件开发一无所知,因此,由您来教育他们。您需要在此处强调测试和错误修复的重要性-请记住,他们不是程序员,他们不知道被零除和损坏的html标签之间的区别。
通常很多出现的问题实际上并不是错误。它们将是可用性问题,遗漏的需求,已更改的需求,用户期望(为什么我不能在手机上使用它?),然后是实际的实际错误。在上线之前,您需要解决这些问题-几天后通常可以解决或修复许多错误。如果人们期望一个完美的系统,那么他们将遭受很多痛苦。如果他们希望发现错误,那么在接下来的几周内您的生活将变得更加轻松。
不要将用户测试与单元测试或系统测试混为一谈。
单元测试-我的代码功能返回正确的值吗?
系统测试-单击X时是否抛出错误
用户接受测试(UAT) -程序是否符合要求?它会按照他们要求您执行的操作吗?它可以上线吗?
如果您没有写下他们要求您做的要求,那么UAT将会困难得多。这是很多人倒下的地方。将他们希望系统完成的工作写下来,将使您的生活变得更加轻松。他们会说“为什么不做X?”您可以说“您告诉我让它做Y”。如果程序错误,请修复它。如果要求有误,请修复文档,再花一两天的时间(不,坚持这样做),进行更改,更新文档并重新测试。
通过几次该过程,您可以开始研究敏捷。.但这是另一个世界:)
测试很好
评论
真实而典型。我要说的是,离开公司显然是合乎道德的,管理该项目的劳动力不是新手初级的问题,因此我绝对会理解是否有人因此而离开。
–CsBalazs匈牙利
2014年7月15日13:55
+1表示大多数人会拿走钱然后消失。这种事情使顾问保持工作。
–James_pic
14年7月17日在12:33
这里不是很好的测试定义。单元测试验证单元的技术规范,集成测试验证端对端系统的技术规范,验收测试(带有或不带有“用户”)验证产品的业务规范。 “系统测试”可能意味着除单元测试以外的几乎所有其他内容。验证返回值在单元测试中并不总是必需或有帮助的,很少有好的自动UI测试只有在系统“抛出错误”时才会失败。
– Aaronaught
2014年7月21日在5:44
“解释测试的重要性并留出时间进行测试是您的工作。”我不是一个“真正的”程序员,但是我能解释的最好方法是,车床操作员的机器上没有一套卡尺。他唯一知道自己做坏事的方法是当QC检查并告诉他错了时。如果您没有质量控制,也没有单元测试,那就像盲目地加工零件并将其发送出去。就像其他任何行业一样,如果您无法测试产品,就无法知道所运送的产品是否还能工作。
–user2785724
2014年7月21日在12:48
@ user2785724-如果您正在编写代码,那么您就是一个真正的程序员。也许您经验不足,但这并不会减少您成为一名编码人员的经验。
–罗克兰
2014年7月21日23:37
#3 楼
每当您从头开始时,由于Second System Syndromme,您几乎肯定会犯相同或更多的错误。您的新错误将有所不同,但调试所需的时间将相似,因此对它的不合适方式将感到绝望。如果部署了第一个版本,还将延迟部署到生产中或新功能的部署,这将给公司带来严重麻烦。乔尔·斯波斯基(Joel Spolsky)称其为任何公司或开发人员都可能犯的“最严重的战略错误”。推荐的方法是在维护过程中一点一点地清理初始混乱。并且甚至不要仅仅为了它而尝试重构它。此外,管理人员通常认为这是浪费金钱(通常是浪费金钱),并且带来了引入新错误的不必要风险。一旦您痛苦地调试了代码,它可能看起来并不漂亮,但是它将起作用。因此,让它成为现实,直到您出于其他原因需要触摸它(是错误修复,新功能或仅仅是市场要求的更改)。然后清理最难调整的零件。这通常被称为童子军规则。
此时,您不必与管理者争辩。只需在请求的估算中包括最小的期望重构即可。您将通过经验中学到东西,当您可能会因为公司确实处于修复状态而负担得起一些费用时,以及当您不想在将来再制造问题并且只是不承认有可能很快被黑客入侵时。 >
最后,再推荐一本:泥浆大球。
评论
c2.com/cgi/wiki的+ long.MaxValue我喜欢那个网站,尽管它似乎已经死了。
–另一个用户
14年7月15日在12:01
我从未听说过Joel Spolsky,但是我花了一个小时阅读了他的一些博客文章。他绝对好笑,而且知识渊博。
–亚当·约翰斯(Adam Johns)
2014年7月15日在20:38
@AdamJohns:但是您正在使用他的软件。马上。他是该网站背后的主要人物。
– Jan Hudec
2014年7月15日在20:49
@JanHudec他和阿特伍德。
– jpmc26
14年7月16日在5:01
最终,其他人在访问此站点之前从未听说过Spolsky。通过阅读这里,您会认为他是第二位。
– MDMoore313
2014年7月17日下午13:41
#4 楼
我忘记了我第一次读的地方,但我只是想以更有力的呼应别人说的话:运输是一种功能。
没有什么比让一个人继续“清理”现有的(可能是hacky,丑陋,肮脏的)代码效果更好,引入新的bug等更糟糕的了。在现实世界中,重要的是要完成工作。你已经做到了。船。即使项目看起来很丑陋,也不要因为它的完美设计而迷失了方向。修复它时,请逐步进行改进,并使自己成为一个好的测试套件,以使回归尽可能少。
评论
不确定它是否是真正的原始书,但是这篇文章是Google的第一本热门文章。当然,作者是Joel(他在该主题上写了很多文章,并且写得很好)。
– Jan Hudec
2014年7月17日14:14
#5 楼
每个项目都使您比以前更聪明。在完成每个项目之后,您将积累更多的经验,而从一开始就拥有它会非常方便。我知道很难不重访所有内容并运用所学知识。但是请记住:完美是善良的敌人。
对于客户来说,现在拥有一个好的软件总是比一个永远不会发布的完美软件更好。
这只是您的第一个项目。将来会有更多项目,您可以一开始就应用所学到的一切。
#6 楼
我[...]阅读了叔叔的Bob干净代码。
我一直坚持认为自己有重写整个项目。
本书的一节非常恰当地命名为“空中重新设计”。
不要尝试重写所有内容,因为在极有可能的情况下,如果您有时间去编写它,那么您将同样面临同样的问题。完成重新设计后,您将学到新知识,并且会意识到它的第一部分非常不专业,因此您将希望再次进行重写。
重新设计和重写是好的,但是如果它们是在工作系统上逐步完成的。正如另一位用户指出的那样,请遵循Boy Scout规则,在处理代码时逐步对其进行重构。
评论
确实如此。十年来,我一直在迭代同一个代码库的设计,但我仍然认为,去年我所做的体系结构是废话。您永远都不会停止学习。
– Joeri Sebrechts
14年7月15日在16:50
需要澄清的是,使增量改进可行的原因是,您进行了一系列测试,使您确信自己没有破坏现有功能。如果您发现自己认为“我无法改变”,则说明您已经确定了需要测试的地方。
– PhilDin
14年7月18日在8:54
#7 楼
您做得很好。您说您的代码有效,并且几乎可以交付了,对吧?
您认为您的代码可能会得到极大的改进。很好。
您的困境让我想起了我的自由职业经历(在大学第二年就被聘用以创建多语言的POS系统)。
我经历了无休止的提问从未对代码感到满意,想要可扩展性,想要重新发明更好的轮子...但是我只是推迟了该项目(例如,大约延迟了12个月),...呢?一旦部署了东西,它仍然需要大量的证明,测试,修补等...
您是否有使用专业代码库的经验?许多代码库充满了古怪,难以维护的代码。通过尝试自己构建一个大型程序来发现软件复杂性的另一种方法是维护/扩展其他人编写的同样凌乱的代码。
我看到完全重写的唯一情况是非常有用的是团队同时采用新的工具链/框架的时候。
如果合理的逻辑(程序做什么,而不是函数,类等的布局方式)是合理的,它将同样有效,因此,您认为这是意大利面条式代码并不意味着不应该部署它。
您需要让客户拥有可以使用的东西。然后,当他们要求您进行改进/添加功能时,您可以决定是否需要进行重构,并且可以让客户知道“集成所述新功能需要一些技术工作”。他们将由此了解到,这将使他们付出更多的钱,并且他们将不得不等待更长的时间。他们会理解(或者您可以退出)。
重写其他内容的更好时机是,当另一个客户要求您创建类似内容时。
简而言之,除非您能证明部署完成后整个过程都会浮出水面,否则延迟部署将是不专业的,不会使您或您的客户受益。学会在修复错误或添加新功能时进行小的重构,这对您来说将是宝贵的经验。
#8 楼
在回答您的问题时,我想说的大部分内容都是别人说的。阅读Joel Spolsky撰写的“您不应该做的事情,第一部分”(以及他的其他一些有关“建筑宇航员”的文章)。记住“完美是善的敌人”。学习逐步重构。运送很重要,等等。我要补充的是:您要承担的任务是,只有一个刚毕业的毕业生用少量的启动预算/时间框架就可以做到的事情。除了良好的,结构化的过程编程之外,您不需要任何更复杂的东西。 (而且,仅供参考,“过程编程”不是一个坏词。在大多数情况下,这在一定程度上是必要的,并且对于许多整个项目来说都是完全足够的。)
只需确保您确实进行了结构化,过程编程。代码中的重复不一定表示您需要宏大的多态结构。这可能只是一个信号,表明您需要使用重复的代码并将其放入子例程中。 “ Spaghetti”控制流可能只是摆脱全局性的机会。
如果项目的某些方面合法地要求多态性,实现继承等,我建议也许该项目的规模被低估了。
评论
我要补充一点的是,意大利面条代码不仅限于程序代码。不正确地使用多态性和继承性会导致混乱,这比许多复杂的程序片断更难理解。使用定义不正确的过程或在复杂的类层次结构中进行继承,控制流是否会遍及整个位置都无关紧要;它仍然到处跳跃,很难跟随。
– Jan Hudec
2014年7月17日14:25
#9 楼
如果您真的对自己所面临的困境感兴趣,则还应该阅读“精益创业”。如果您阅读这本书,那么这里给您的许多建议都会引起您的共鸣。基本上,资源消耗率是您最大的敌人,对您和您的组织而言,没有什么比最终用户/客户反馈更有价值。因此,使您的产品处于可行状态(最低可行产品-或MVP),然后将其发货(与代码的实际外观无关)。让您的客户决定您将来的变更集和版本,而不是相反。如果您专注于这种方法,从长远来看,您和您的老板都会更快乐。#10 楼
出于其他人已充分解释的原因,现在该完成并交付该项目了,可能会很痛苦。我只想强调一下,测试应用程序也是“完成”的一部分
如果尚未充分行使重要功能并确认正确
结果,那么您有理由担心人们会在部署此应用程序时遇到问题
。
单元测试和自动化的更高级别的测试非常棒,在尝试重构(或重写)此应用程序之前,应该拥有尽可能多的东西。但是,即使您必须“手动”运行每个测试并“目测”确认正确的功能,现在您仍然主要需要对其进行测试。如果您以后能弄清楚如何使这些测试自动化,那么当该开始着手开发该产品的下一个版本时,这将有所帮助。
有些人对于坐在新产品前非常了解。作为Alpha测试用户的软件项目,使事情出错。也就是说,他们擅长破坏事物。如果您有幸与这样的才华横溢的人一起工作,请让他们首先试用该应用程序,以便您有机会及早修复所有明显的错误。
如果必须自己完成此任务,则:
要有条不紊。
尝试每一个功能。
假装您是对应用程序不熟悉的用户。犯下愚蠢的错误并查看软件如何处理它们。
写下您的操作,以便在您认为已解决问题后可以再次尝试。
评论
我完全同意这一点。也不要忘记在生产中进行手动测试。无论您在开发环境中进行了多少测试,每次部署之后,始终需要在实时环境中进行完整性测试。您可以请同事帮忙。
–威尔·谢泼德(Will Sheppard)
2015年9月14日上午10:30
#11 楼
您的问题是:“开始错误,我应该重新开始”,而其他文字实际上是“完成的项目,但是做错了,我应该重新开始”。仅对于标题问题:如果您完成的编程工作量与所需的总工作量相比很小,那么从头开始就很有意义。当问题很复杂且理解不充分时,会发生很多事情,并且花了相当多的时间来弄清问题的实质。毫无意义的继续进行不好的开始,如果丢掉它并重新开始,这一次对问题有很好的理解,这意味着您实际上会更快地完成。#12 楼
这是我个人要做的事情:退出,找个借口并放弃(你甚至可以还掉一部分薪水,这样你就不会看起来很糟)
尽可能清理代码
为您的工作的所有良好部分制作文档,例如好的设计,好的想法等...
为什么我建议所有这些都给您?
因为考虑未来。将来会有一段时间某些人会掌握此代码。他们将对您和您的能力做出各种假设和判断。他们不在乎你写的时候,他们不在乎情况。他们只想在其中看到想要确认的内容即可。
您会被贴上任何不好的名字的烙印,这是他们可能会给您带来负面影响的术语。即使将来的您在技术能力,技能,知识,风格和情况方面可能完全不同,但此代码将以各种可能的方式对您不利。就像法院一样,他们可以说出关于您以及您的代码和设计的所有坏消息,而您甚至不知道它,因此您可以自己解释和辩护。 (而且您可能经常会发现他们反复犯错),所以不要这样做。放弃。
相信我,有些人对您有很多假设,因为您在任何时候出于任何目的都做了一些事情。对于他们来说,如果您在情况A中这样做了,那么您将在情况B中这样做。他们认为非常简单。
#13 楼
还有两个建议,我敢打赌,至少还有一个您没有做过。1)放置一个错误跟踪器,并教您的老板使用它。这可能是关于如何精打细算,学得更好并且将以计划的方式进行修复的对话的一部分。
2)开始使用版本控制,尽管希望您已经这样做了。 br />
那里有许多托管系统,可以通过小型帐户免费提供上述两种服务。我特别喜欢FogBugz,它还具有出色的估算和任务完成系统,可以使您的老板更加确定自己以一种管理良好的方式处理问题。
edit
哇,有人真的不喜欢这样-降票和删除标志吗?为什么?
我已经开发软件三十多年了,其中包括大量的咨询工作和继承他人的代码。我见过的很多问题系统都是人们在这里挖坑的,没有详细的注释说明如何到达那里,也没有版本控制。
#14 楼
回答您的问题:正如许多其他人所说,不。运送它,并在修复错误的过程中一点一点地清理它。另外,尽管books / StackExchange / webforums是很好的学习资源,但您可能会发现没有什么可以与您的学习相匹配的从其他程序员的工作中(甚至只是讨论工作中)将获得收益。找到并参加您正在使用或想要学习的技术的本地团队是您宝贵的时间投入。除了要获得的技术知识外,它还是一种轻松的人脉网络,在您期待未来的演出时非常宝贵。
#15 楼
您的老板雇用您时就知道您的经验水平。只需表达您的担忧,并让他知道您对此感到紧张。还让他知道您学到了多少,以及可以做下一个项目有多好。#16 楼
您是一个刚开始的Web开发人员,没有优秀的开发人员可以为您提供建议,您的老板雇用了您对此非常了解。我认为您的表现和任何人都可以期望的一样。实际上,您拥有这样的洞察力:工作本可以做得更好,并且您实际学到了可以做得更好的事情,这意味着您比大多数人都做得更好。请记住,出于您的理智,开始工作的您的版本不可能做得更好。更有经验的人(因此报酬更高),或者您拥有一个项目的经验值,可能会做得更好。现在该怎么做:很高兴自己比一年前做的更好。下一个项目将做得更好(最后,您将再次变得经验丰富,对所做的事情不满意;这是正常的)。更改或重写上一个项目将使业务从成本中受益甚少。您所要做的就是在需要进行更改时以良好的代码替换不良的代码。这是有道理的,因为修改可维护性差的代码比用好的代码替换它更难。而且,如果您有新手没有经验的开发人员来帮助您,请告诉他们该代码不是他们应复制的示例。
评论
按照开始的方式完成操作,并清理下一版本中的技术债务(如果有)。你的老板不知道有什么区别。请确保您测试良好。“但是上帝只知道人们开始使用它时会发生什么。”…这就是软件开发的乐趣。更好地习惯它;)
这将是您构建的每个系统。
软件永远不会完成,一旦您关闭它,您将始终拥有洞察力,这使您希望将整个代码库丢到窗外。别。交付一个有效的产品,然后掌握重构的技巧。这将是一个宝贵的教训。
我父亲曾经告诉我:“有时您必须射击工程师并运送。”