我几乎没有一年的编码经验。开始工作后,大多数时候我都会处理别人的代码,或者在现有功能上添加新功能,或者修改现有功能。编写实际代码的人在我公司不再工作。我很难理解他的代码并完成任务。每当我尝试修改代码时,我都会以某种方式弄乱正常工作的功能。在处理别人的代码时,我应该牢记什么?
我几乎没有一年的编码经验。开始工作后,大多数时候我都会处理别人的代码,或者在现有功能上添加新功能,或者修改现有功能。编写实际代码的人在我公司不再工作。我很难理解他的代码并完成任务。每当我尝试修改代码时,我都会以某种方式弄乱正常工作的功能。在处理别人的代码时,我应该牢记什么?
Answers:
代码中是否包含单元测试?如果没有,我强烈建议您开始添加它们。这样,您可以将新功能/错误修复编写为失败的测试,然后修改测试通过的代码。您构建的代码越多,您对所添加的代码不会破坏其他内容的信心就越大。
为您不完全理解的代码编写单元测试将有助于您理解所说的代码。当然,如果尚不存在功能测试,则应添加它们。我的印象是,OP问题已经存在这些问题。如果我在这一点上错了,那么这些功能测试应该是您的第一步。
Eagle76dk使一个伟大的一点关于让你的经理在船上做这项工作-更多细节Eagle76dk的职位。
另外,在编写这些测试时,我鼓励您尝试编写测试,以便它们验证该方法可能试图完成的业务行为,而不是代码行为。另外,请不要完全假设您在代码中看到的业务行为是正确的-如果有人可以告诉您应用程序应该做什么,那么在许多情况下,这些行为比代码可以告诉您的价值更大。
除了提到单元测试的另一个答案之外,我建议您确保所有内容都在版本控制中,以便能够轻松还原所做的更改。并进行少量更改以使代码更易于维护。
我认为,学习别人代码的最快方法(尤其是当更改触发您所描述的异常行为时)是使用调试器逐步遍历代码。
首先逐步完成程序的主要循环/主要方法。使用单步执行和单步执行功能可以查看不同方法的作用。这将教您代码的一般结构。
之后,逐步学习并深入了解程序的不同部分,从而分而治之。在大多数调试器中,您可以研究变量及其当前值。研究它们如何改变以及何时改变。
在触发与您有关的行为的方法上设置断点。例如,如果您尝试更改程序中的文本,并且文本不断更改回原始值,请在更改文本的所有位置上设置断点,或尝试将所有这些更改移动到一个方法中。使用调用堆栈查看从何处调用此方法,等等。
如果更改一行代码导致其他地方发生意外更改,请在该行上放置一个断点,然后查看发生的情况,例如,通过检查作用域中当前变量的值,使用step into或调用堆栈来查看从何处来电来了。
通过大量这样做,您将开始以惊人的速度学习代码的结构。我就像您刚开始从事编程工作时一样,一开始就是用很多代码编写的,这些代码是很多年前编写的,并且许多人多年来一直在修改它们。该代码不是我的代码,因为那里有其他人同时在工作。那时候我无法全部重写。为所有这些代码编写测试将花费我几个月甚至几年的时间。调试器真的救了我,不知道如果没有它我将如何学习代码...
不要太快假设其他人的代码很臭。
但请始终保持可疑。
但是,是的,了解其他开发人员的代码需要花费时间。系统的多个部分使用的功能或对象越多,则需要格外小心。如果您可以更接近症状地解决问题,那有时会有所帮助。例如,在数据交付后但在其他任何事情发生之前,对来自围栏问题对象一侧的另一个对象的传入数据进行规范化。
当更改一件事意外破坏另一件事时,这是一个不好的信号。如果您还有其他经验更丰富的开发人员,可以依靠您寻求帮助,我建议您让他们研究引起您问题的内容。至少您可能会看到一些调试它们的内容。
在理想的情况下,将使用自动工具(例如单元测试)和用户运行的用例脚本来检查给定开发人员编写的所有代码,并对其进行全面的测试,以检查您是否获得了预期的结果。
但是,您首先要了解的是我们没有生活在理想的世界中!
许多开发人员没有正确记录其代码,或者根本没有将业务逻辑与不相关的代码混合在一起,而他们所做的唯一测试就是快速浏览他们期望的正常用例。
当使用这样的代码时,您要做的第一件事就是确定它的意图。如果有任何评论,他们可能会为您提供线索,但不要指望它。我的经验是,许多编码员都不善于自我解释,即使他们留下评论,也可能毫无意义。但是,除非您是公司中唯一的编码人员,否则肯定有人必须至少对代码的用途和用途有一个基本的了解。问问周围!
如果您有单元测试,那么它们将使您的生活变得轻松许多。如果您不这样做,那么学习代码库的一部分可能涉及为已经存在的代码编写单元测试。通常,这不是一个好习惯,因为如果您编写单元测试以适合现有代码,那么您最终将获得认为该代码按原样工作的单元测试(它们将被编写为假定实际上是一个错误的行为是是正确的),但至少它为您提供了基线。如果以后发现您认为正确的某些行为实际上是错误的,则可以更改单元测试以测试预期结果是什么,而不是代码现在给出的结果。进行单元测试后,您可以进行更改并评估所做的任何更改的副作用。
最后,在处理未记录的代码时,最好的资源是询问最终用户。他们可能对代码一无所知,但是他们知道他们想要应用程序做什么。需求收集是任何项目的第一步,与要开发的系统的潜在用户进行交谈始终是其中的重要部分。可以将其视为刚好已经完成的新项目的需求捕获阶段。
请记住,即使局外人也难以理解即使编写良好且文档齐全的代码。代码本质上是表达编写该代码的人当时的思维方式的表达,每个人都有自己独特的思维过程。您将必须学会变得耐心,成为一名侦探。能够进入他人的思维过程很困难,但这对于程序员进行现有代码维护是一项必不可少的技能。由于大多数编码(大约70%)与维护现有代码有关,因此这是学习的一项重要技能。
哦,既然您已经看到了文档编写不当,未经测试且混乱的代码可能造成的痛苦,那么您将不会再遇到下一个可怜的开发人员,对吧?:)从前任的错误中吸取教训,对代码进行很好的注释,确保每个模块都有明确定义的职责,并确保您拥有一套完整的单元测试,这些单元测试要么首先编写(针对TDD方法),要么编写至少与正在开发的代码一起。
请记住,读取尚未编写的代码的能力是一项非常有价值的技能,可能比编写代码更有价值。不幸的是,这在学校普遍被低估和教导。
我要说的是,在第一次阅读时并不总是理解代码是很正常的(就像第一次不编写完美的代码是正常的一样)。如果您接受获取外部代码需要花费时间,那么您不介意付出额外的努力。一个小总结:
单元测试将是理想的,但并不总是现实的;尤其是当您在官僚机构繁重的大型组织中工作时。
学习正确使用版本控制系统;您将永远不会破坏现有的(不是真的不会,但这是一个很好的安全网)。
不要仅仅因为您不立即了解它就认为它很糟糕。不要仅仅因为它起作用就认为它很好。重要的是,您应该了解以前的维护者的代码风格,并使添加的行适应他的风格。维护人员会在您之后感谢您。
不幸的是,在某些公司中,阅读代码的难度可能会被低估。这在具有严格流程的大型公司中很常见。他们经常(隐式地)喜欢您推送可快速工作的代码,而不是花时间来编写干净的东西。我将由您来决定您的团队在这一点上的立场。
最后,永远不要忘记阅读代码是一种技巧。您做得越多,就会越好。另一种说法是,要善于练习,唯一的方法就是要练习多次。就像上面提到的,与编写相比,阅读代码现在是而且将在您的工作中占更大的比重。
从您无意间破坏东西的问题来看,我将假设该代码未包含在自动化测试中。步骤#0是立即订购并阅读Michael Feathers的《有效处理旧版代码》。这简直是无价之宝。
我建议的基本步骤:
我特意省略了指定测试风格的内容(单元,集成等),只是获得了某种自动化的测试范围。
(是的,在布局和命名方面遵循编码风格)
如前所述:欢迎来到现实世界。我只能同意较早的答案。我只希望通过我的时间估算工作经验来扩展答案。
一个很好的建议是使您的老板清楚,这将需要时间来学习其他开发人员的想法。通常,您会发现当前的解决方案通常取决于开发人员的年龄和经验。
如果幸运的话,必须分析当前的任务,了解文档将对您有很大帮助(但事实并非如此)。
我的经验是,在修改其他代码时,请尽量不要更改不涉及您当前任务的代码。您可能知道更好的解决方案,或者可以以更直观的方式编写它,但是更改它通常会导致诸如以下的问题:
但是,请不要犹豫告诉老板,如果您发现自己认为应该有所不同的事物(只是表明您可以思考)。
最后,请确保您有足够的时间来制定解决方案。经验带来了更快的解决方案。但是很少有快速的解决方案,因为这是错误和代码无法维护的首要原因。
可以将其视为对一个人执行操作。
您在内部寻找需要修复的问题,并注意到大多数动脉等未按照您的设置方式进行布置-因此您将它们切开并砍成碎片,直到看起来对您来说再解决。
令人惊讶的是,您的患者几乎立即死亡。
旧版应用程序是相同的。他们已经有了一种工作方式-您需要了解软件中的各个组件以及它们之间的相互关系,然后进行更改,使其工作方式相同。让您的创造力疯狂起来并不令人兴奋,但是您可以在个人项目上做到这一点。
我会请一个高级工程师在每个星期一和您一起坐一个小时左右,并解释系统的另一个方面。记下他说的话,然后将其通过电子邮件发送给他和您的经理,以查看您的经理是否有任何要补充的内容。您应该以这种方式快速起步。
至于如何不破坏事物,首先要确保您了解系统的功能。先测试-进行更改-之后再测试。没有神奇的公式。随着经验的积累,您会变得更好-否则就会被炒鱿鱼!
我没有真正看到的一件事触及到这里- 不要在岛上工作。
除非您是唯一的程序员,否则肯定会有一些人的经验超过您,并且很可能有很多人可以依靠。
问问题。其中很多。
不必担心(在合理范围内)“烦恼”别人-我宁愿有人在正常的开发周期中因一两个问题而打扰我,而不必稍后在生产环境中开火。
当您准备好办理登机手续时,请与导师一起检查。他们不仅应该告诉您某些东西是否会破坏其他东西,而且更重要的是,为什么。审查代码还将使指导者成为更好的程序员,使他/她对系统的看法是,他们可能不会经常查看。
记住-您不仅在学习新员工需要做的系统,而且还在学习如何成为一名程序员。
五年后,鼓励下一个新家伙来使用您作为导师。
无论是在可能的情况下编写单元测试,还是编写涉及要修改的代码的小型应用程序,您都必须查看,理解并记录逻辑。
如果代码大部分都起作用(听起来像是一样),那么我将保留该模块的代码格式设置样式,无论您使用的是不是这种样式。它使事情保持一致。但是,好的评论永远不会过时。
我建议使用一个测试系统和测试平台,您可以在其中修改和测试此代码,而不会中断生产。
如果可以将代码的元素删除到库中,除非您正在使用库,否则我会这样做。
随着时间的流逝,一旦您了解了逻辑,就可以重写和测试。
该建议取决于您使用的语言,获得测试平台的能力以及您所遇到的其他限制。
上面已经指出,您需要了解系统的目的,而不仅仅是代码的细节。具有足够的经验来编写订单输入系统的程序员通常会喜欢“前进”部分,该部分涉及选择产品,格式化发票和处理付款。当用户决定“不介意”并开始撤消交易时,或者当他们在付款处理中出错并点击“后退”按钮时,它们就会卡住。到那时,许多程序员感到困惑,因为他们看到代码“无处不在”,并且不知道为什么存在。
简而言之,您不仅需要了解“正常流程”,还必须了解如果有人犯了错误或改变了主意,则必须进行的所有回溯。对于主管覆盖,情况变得更糟,在某些情况下,某些代码只能使用某些帐户特权才能运行。
如果某人每年编写10,000行代码,而一个应用程序有十年的“生命”,那么负责接管他人工作的程序员可能必须理解100,000行代码。用每页50行除以2000页。如果将程序编写为一种设计模式,则程序员将发现对一个“块”的理解至少可以对其余大部分进行一般性的理解。如果不是,那么有必要阅读每条该死的行。
一些程序员“只是按照他们的要求去做”并写意粉。他们从不理解“大局”-当用户抱怨时,他们只是简单地进行修复。在这种情况下,最好将所有可能的方法迁移到适当的模式。最终,这可能意味着重新编码未损坏的内容。不用担心,只要确保它是您的项目,它就可以逐步维护。
这里有一些非常好的答案。但是我认为值得一提的是,熟悉良好的设计模式可以帮助您阅读(编写良好的)现有代码并编写可读的代码。
当然,当您SomethingFactory
在现有代码中遇到实际上并不遵循工厂模式的代码时,可能会非常混乱。但是,在您的团队和框架允许的范围内,将此类案件的发生率降至最低可能是有益的。
遵循设计模式(在业务需求允许的情况下)还可以大大减少代码重复,从而减少以后修改的错误。
有关设计模式的一些很好的资料是
http://sourcemaking.com/design_patterns
当然还有书
http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612
跟踪方法之间的控制流对于开发业务逻辑思维图非常重要。
我们的解决方案基于以下认识:运行遗留系统时,为数不多的几条值得信赖的信息之一就是运行系统本身。我们的方法改进了执行轨迹,并使用逻辑编程对它们进行测试。
生成工作流数据模型是分析所有代码路径的最佳方法:
在实践中,代码审查在传统的科学工作流程中变得笨拙。这种工作流程的起源意味着在开发过程中可能尚未应用软件工程实践,从而导致代码库被有效地混淆了。尽管静态分析具有完善的数据流分析技术,但它们无法支持现实工作流中的行为。例如,何时必须加载配置文件以确定应如何处理数据,或何时使用动态代码评估。
可视化工作流程是理想的:
有助于视觉开发的常见主题是将工作流程表示为图形。这使用户免受资源和执行的潜在复杂性影响
参考文献