我已经继承了20万行意大利面条代码-现在怎么办?


470

我希望这不是一个普遍的问题。我真的可以使用一些经验丰富的建议。

我刚刚在一家规模很小的科学家商店中担任唯一的“软件工程师”,他们在过去的10到20年中花了很多时间编写了庞大的代码库。(它是用一种几乎过时的语言编写的:G2-用图形来思考Pascal)。该程序本身是复杂的化学加工厂的物理模型。编写该程序的团队具有难以置信的深厚知识,但是很少或没有正式的编程基础培训。他们最近学到了一些关于不存在的配置管理的后果的艰难教训。代码本身中大量未记录的“污泥”的积累也极大地阻碍了他们的维护工作。我会避免给您这种情况的“政治”(总是 政治!),但足以说,就未来的道路需要什么没有达成共识。

他们要求我开始向团队介绍现代软件开发的一些原理。他们希望我介绍一些有关编码约定,生命周期管理,高级设计模式和源代码控制的行业标准实践和策略。坦白地说,这是一项艰巨的任务,我不确定从哪里开始。

最初,我倾向于在The Pragmatic Programmer或Fowler's Refactoring(“代码气味”等)的一些中心概念中对它们进行辅导。我也希望介绍一些敏捷方法。但最终,要想发挥作用,我认为我需要磨练5-7个核心基础知识。换句话说,他们可以实际开始实施的最重要的原则或实践是什么,这将使他们获得最大的“收益”。

因此,这就是我的问题:将在最有效的策略列表中包括哪些内容,以帮助理顺意大利面(并在以后防止出现这种情况)?


124
迈克尔·费瑟(Michael Feather)的书有效处理遗留代码
MarkJ

13
由于G2就像不是代码,而是由某些恶作剧的GUI编写的自动化代码,因此我认为您需要指定您实际上是在G2中重构还是以明智的方式重做整个该死的事情。
埃里克·雷彭

101
无论您做什么,都不要从头开始重写。这将是一个严重的错误。20年的化学知识:它是您永远无法再现的东西。而且,您理所当然会失去科学家的尊重。
Francesco

13
@Francesco的评论中添加Joel Spolsky关于不重写的合理建议:joelonsoftware.com/articles/fog0000000069.html
Govert,2012年

16
我最近读到的一句话很不错:“软件是唯一将原型组合在一起然后尝试将其作为交付品出售的工程领域”
Chris S

Answers:


466

前言

确实,这是一项艰巨的任务,并且有很多方面需要解决。因此,我谨以此建议为您的团队提供一些全面的指导,并提供指向适当工具和教材的指南。

请记住:这些是准则,因此应根据情况采用,改编或删除。

当心:一次将所有这些都丢给一个团队很可能会失败。您应该尝试挑选那些可以为您带来最佳效果的元素,然后一次缓慢地引入它们。

注意:并非所有这些都直接适用于像G2这样的可视编程系统。有关如何处理这些错误的更多详细信息,请参阅末尾的附录部分。


不耐烦的执行摘要

  • 使用以下内容定义一个刚性项目结构
    • 项目模板
    • 编码约定
    • 熟悉的构建系统
    • 以及针对您的基础架构和工具的使用指南集。
  • 安装良好的SCM,并确保他们知道如何使用它。
  • 为他们的技术指点优秀的IDE,并确保他们知道如何使用它们。
  • 在构建系统中实施代码质量检查器自动报告
  • 将构建系统耦合到持续集成持续检查系统。
  • 在上述帮助下,确定代码质量“热点”并进行重构

现在是长版本...小心,请自行准备!


刚性(通常)是好的

这是一个有争议的观点,因为僵化通常被视为对您不利的力量。在某些项目的某些阶段确实如此。但是,一旦您将其视为结构性的支持,即消除了猜测的框架,它就会大大减少浪费的时间和精力。让它为您服务,而不是对您不利。

刚性 = 过程 / 程序

出于与化工厂或工厂具有手册,程序,演习和紧急指导的完全相同的原因,软件开发需要良好的过程和程序:防止不良后果,提高可预测性,最大化生产率...

刚度要适度!

项目结构的刚性

如果每个项目都有其自己的结构,那么您(和新手)会迷路,并且每次打开它们时都需要从头开始。您不希望在专业的软件商店中使用它,也不想在实验室中使用它。

建造系统的刚性

如果每个项目看起来都不同,则很有可能它们的构建方式不同。一个构建不需要太多的研究或太多的猜测。你要能够做到规范的事情,而不是需要担心的细节:configure; make installantmvn install,等...

重复使用相同的构建系统并使其随时间变化也可以确保质量始终如一。

您确实需要快速README指出项目的细节,并优雅地指导​​用户/开发人员/研究人员(如果有)。

这也极大地促进了构建基础结构的其他部分,即:

因此,请保持您的构建(例如您的项目)为最新,但随着时间的流逝使它变得更加严格,并在报告违规和不良做法时更加有效。

不要重新发明轮子,而要重复使用已经完成的工作。

推荐读物:

编程语言选择中的刚性

您不能期望,尤其是在研究环境中,所有团队(甚至更少的所有开发人员)都使用相同的语言和技术堆栈。但是,您可以确定一组“官方支持”的工具,并鼓励使用它们。其余的,如果没有充分的理由,则不应被允许(除了原型之外)。

使您的技术堆栈简单,并使所需技能的维护和广度降至最低:坚固的核心。

编码公约和准则的严格性

编码约定和准则使您可以发展团队身份和共享术语。你不想犯错进入未知领域每次打开源文件的时间。

愚蠢的规则使生活变得更加艰苦或禁止采取明确的行动,以至于仅仅基于一次简单的违反就拒绝了提交,这是一种负担。然而:

  • 一个经过深思熟虑的基本规则集消除了很多抱怨和思考:在任何情况下,任何都不应打破。

  • 一组建议的规则可提供其他指导。

个人方法:在编码约定方面,我很激进,有些人甚至说纳粹,因为我确实相信拥有 通用语言,这对我的团队来说是一种公认​​的风格。签入废话代码时,它像好莱坞明星脸上的唇疱疹一样突出:它会自动触发审阅并采取行动。实际上,我有时甚至提倡使用pre-commit钩子拒绝不合格的提交。如前所述,它不应​​该太疯狂而妨碍生产力:它应该推动生产力。慢慢地介绍这些内容,尤其是在开始时。但这比花费大量时间修复错误代码以致于无法处理实际问题更可取。

有些语言甚至是设计使然的:

  • Java的目的是减少您可以用它编写的无聊的废话的数量(尽管毫无疑问,许多人都做到了)。
  • 从这个意义上说,Python通过缩进的块结构是另一个想法。

  • 使用其gofmt工具Go,可以完全消除样式固有的任何辩论和努力(以及自我!!):gofmt在提交之前就运行。

确保代码腐烂无法通过。代码惯例持续集成持续检查,结对编程代码审查是您抵御此恶魔的武器。

另外,正如您将在下面看到的那样,代码是document,这是约定鼓励可读性和清晰度的另一个领域。

文件的刚性

文档与代码齐头并进。代码本身就是文档。但是必须有关于如何构建,使用和维护事物的明确说明。

对文档(例如WikiWiki或DMS)使用单点控制是一件好事。为项目创建空间,为更多随机玩笑和实验创建空间。让所有空间重复使用通用规则和约定。尝试使其成为团队合作精神的一部分。

适用于代码和工具的大多数建议也适用于文档。

代码注释中的刚性

如上所述,代码注释也是文档。开发人员喜欢表达自己对代码的感受(如果您要问我,主要是骄傲和沮丧)。因此,当更正式的一段文字可以用较少的粗俗或戏剧性传达相同的含义时,对于他们来说,在注释(甚至代码)中用不确定的术语来表达它们并不稀奇。出于趣味和历史原因,可以让一些人溜走:这也是发展团队文化的一部分。但是,每个人都知道什么是可以接受的,什么不是,这很重要,并且评论的声音就是: noise

提交日志中的刚性

提交日志并不是SCM生命周期中烦人且无用的“步骤”:您不要跳过日志以按时回家或继续执行下一个任务,也不赶上那些要去吃午餐的伙伴。它们很重要,就像(大多数)好酒一样,时间越长,它们就越有价值。所以做对了。当我看到同事们为巨型提交或非显而易见的黑客编写单行代码时,我感到非常惊讶。

提交是有原因的,因此,您的代码和输入的提交日志的一行都不会清楚地表示ISN。不仅如此。

每行代码都有一个故事和一个历史。差异可以说明其历史,但是您必须编写其故事。

为什么我要更新此行?->因为界面改变了。

为什么界面发生了变化?->因为定义它的库L1已更新。

为什么要更新库?->因为功能F需要的库L2取决于库L1。

X的功能是什么?->请参阅问题跟踪器中的任务3456。

这不是我的SCM选择,也可能不是您实验室的最佳选择。但是Git正确无误,并试图通过使用short logs和 迫使您编写比大多数其他SCM系统更好的日志long logs。链接任务ID(是,您需要一个),然后为留下通用摘要shortlog,然后在长日志中展开:写变更集的故事

这是一条日志:在这里可以跟踪和记录更新。

经验法则:如果您稍后要搜索有关此更改的信息,您的日志是否有可能回答您的问题?

项目,文档和代码都还活着

使它们保持同步,否则它们将不再形成该共生实体。当您拥有时,它会产生奇迹:

  • 清除SCM中的提交日志,带有指向问题跟踪器中任务ID的链接,
  • 该跟踪器的票证本身链接到SCM中的变更集(并可能链接到CI系统中的内部版本),
  • 以及链接到所有这些文件的文档系统。

代码和文档必须具有凝聚力

测试的刚性

经验法则:

  • 任何新代码都应(至少)包含单元测试。
  • 任何重构的遗留代码都应随单元测试一起提供。

当然,这些需要:

  • 实际测试一些有价值的东西(否则会浪费时间和精力),
  • 编写得很好并且带有注释(就像您签入的任何其他代码一样)。

它们也是文档,它们有助于概述代码的约定。特别是如果您使用TDD。即使您没有,也需要它们以使您安心。当您合并新的代码(维护或功能)时,它们是您的安全网,并且您的watch望塔可以防止代码腐烂和环境故障。

当然,您应该走得更远,并针对要修复的每个可复制错误进行集成测试回归测试

工具使用的刚性

对于偶尔的开发人员/科学家来说,可以尝试在源代码上使用一些新的静态检查器,或者使用另一个生成图形或模型,或者使用DSL实现新模块,这是可以的。但是最好是所有团队成员都应该知道并使用一套规范的工具。

除此之外,只要成员都是会员,就可以使用他们想要的东西:

  • 生产
  • 不定期需要帮助
  • 没有定期适应您的一般基础架构
  • 不会破坏您的基础架构(通过修改通用区域,例如代码,构建系统,文档...),
  • 不影响他人的工作
  • 能够及时执行任何要求的任务

如果不是这种情况,则强制其回退到默认值。


刚性与多功能性,适应性,原型设计和紧急情况

灵活性可以很好。偶尔让某人使用黑客,快速n肮脏的方法或喜欢的宠物工具来完成工作 是很好的。永远不要让它成为一种习惯,也永远不要让这种代码成为要支持的实际代码库。


团队精神很重要

在您的代码库中培养一种自豪感

  • 培养对代码的自豪感

避免责备游戏

  • 一定要使用持续集成/持续检查游戏:它可以促进良好的行为和富有成效的竞争
  • 务必跟踪缺陷:这只是良好的内务处理。
  • 一定要确定根本原因:这只是面向未来的过程。
  • 但不要指责:它适得其反。

这是关于代码,而不是关于开发人员

使开发人员意识到其代码的质量,但使他们将代码视为独立的实体,而不是自身的扩展,这不能被批评。

这是一个自相矛盾的问题:您需要鼓励无自我的程序设计,以实现健康的工作场所,而要依靠自我来达到激励目的。


从科学家到程序员

不重视并为代码感到骄傲的人不会产生好的代码。为了使此属性浮出水面,他们需要发现它的价值和乐趣。仅凭专业精神和对做事的渴望还不够:它需要激情。因此,您需要将您的科学家变成 程序员(从广义上讲)。

有人在评论中辩称,在一个项目及其代码10到20年后,任何人都会感到执着。也许我错了,但我认为他们为代码的结果,工作及其遗产感到骄傲,而不是为代码本身或编写行为感到自豪。

根据经验,大多数研究人员认为编码是必要的,或充其量只是一种有趣的干扰。他们只是想要它工作。那些已经精通该程序并且对编程感兴趣的人更容易说服采用最佳实践和转换技术。您需要将它们放到一半。


代码维护是研究工作的一部分

没有人看烂的研究论文。这就是为什么要反复对它们进行同行评审,校对,细化,重写和批准,直到它们准备发布。论文和代码库也是如此!

明确指出,不断重构和刷新代码库可防止代码腐烂并减少技术负担,并有助于将来重用和适应其他项目的工作。


为什么所有这一切?!

我们为什么要为上述所有事情烦恼?为了代码质量。还是 质量代码 ...?

这些准则旨在推动您的团队朝着这个目标前进。有些方面是通过简单地向他们展示方式并让他们做到这一点来做到的(这要好得多),而另一些方面则是通过手牵着手来做到的(但这就是您教育人们和养成习惯的方式)。

您如何知道何时可以实现目标?

质量可衡量

并非总是定量的,而是可以测量的。如前所述,您需要对团队感到自豪,展现进步和良好成绩是关键。定期测量代码质量,并显示间隔之间的进度及其重要性。进行回顾以反思所做的事情,以及它如何使事情变好或变坏。

有很棒的工具可以进行连续检查Sonar在Java世界中很流行,但是它可以适应任何技术。还有很多其他的 将您的代码放在显微镜下,寻找这些讨厌的令人讨厌的错误和微生物。


但是,如果我的代码已被废话怎么办?

上面所有这些都很有趣,而且很可爱,就像去Never Land一样,但是当您已经有了(一堆又热又臭的)废话,并且一个团队不愿改变时,这并不是那么容易。

这就是秘密:您需要从某个地方开始

个人轶事:在一个项目中,我们使用的代码库最初的权重为650,000+ Java LOC,200,000 +行JSP,40,000 + JavaScript LOC和400+ MB二进制依赖项。

大约18个月后,它是500,000 Java LOC (MOSTLY CLEAN),150,000行JSP和38,000 JavaScript LOC,并且依赖关系低至仅100MB(而这些不再在我们的SCM中了!)。

我们是怎么做的? 我们只是完成了以上所有操作。还是努力了。

这是一个团队的努力,但我们慢慢地注入我们的流程规定和工具来监视我们的产品的心脏速率,而贸然削减掉的“肥肉”:垃圾代码,无用的依赖......我们并没有停止所有发展这样做:我们偶尔会在相对平静的环境中自由地对代码库疯狂,然后将其拆散,但是大多数情况下,我们都会通过默认使用“查看和重构”模式来做到这一点:在构建期间,午餐期间,错误修复Sprint期间,星期五下午...

其中有一些很大的“工作” ...将我们的构建系统从8500+ XML LOC的巨型Ant构建切换到多模块Maven构建就是其中之一。然后,我们有:

  • 清晰的模块(或者至少它已经好很多了,而且我们对未来还有很大的计划),
  • 自动依赖性管理(便于维护和更新,并删除无用的dep),
  • 更快,更容易和可复制的版本,
  • 每日质量报告。

另一个是的“实用工具带”的注入,即使我们试图减少依赖关系:谷歌番石榴和Apache共享瘦下来你的代码,并降低表面在错误代码了很多。

我们还说服我们的IT部门,也许使用我们的新工具(JIRA,Fisheye,Crucible,Confluence,Jenkins)比现有工具更好。我们仍然需要处理我们鄙视的一些问题(QC,Sharepoint和SupportWorks ...),但这是一种整体改进的体验,还有更多空间。

现在,每天都有一到十个提交的细流,这些提交仅用于修复和重构问题。我们偶尔会破坏一些东西(您需要单元测试,最好重构它们之前编写它们),但是总体上,我们的士气和产品的利益是巨大的。我们一次达到了代码质量百分比的一小部分。看到它增加很有趣!!!

注意:同样,刚性也需要动摇,以腾出空间容纳新的更好的东西。在我的轶事中,我们的IT部门在向我们强加某些东西方面是对的,而对另一些东西则是错的。或者也许他们曾经是对的。事情会改变的。证明它们是提高生产力的更好方法。试运行和原型在这里。


超级绝妙的增量意大利面条式代码重构周期,可提供出色的质量

       +-----------------+      +-----------------+
       |  A N A L Y Z E  +----->| I D E N T I F Y |
       +-----------------+      +---------+-------+
                ^                           |
                |                           v
       +--------+--------+      +-----------------+
       |    C L E A N    +<-----|      F I X      |
       +-----------------+      +-----------------+

一旦您掌握了一些优质的工具,即可:

  1. 使用代码质量检查器分析您的代码。

    短绒,静态分析仪或您拥有的东西。

  2. 确定您的关键热点和低落的果实

    违规具有严重性级别,具有大量高严重级别的大型类是一个大的危险信号:因此,它们在散热器/热图类型的视图中显示为“热点”。

  3. 首先修复热点。

    由于它们具有最高的业务价值,因此可以在短时间内最大程度地发挥您的影响力。理想情况下,严重违规应在可能出现的安全漏洞或崩溃原因中尽快处理,并具有引发责任的高风险(在您的情况下,这会对实验室造成不良影响)。

  4. 使用自动代码库清除功能清除低级冲突。

    它提高了信噪比,因此您可以在雷达上看到明显的违规现象。如果一开始就经常有大量的轻微违规事件发生,即使他们从来没有得到照顾,并且您的代码库在野外也很松懈。它们不会带来真正的“风险”,但是会损害代码的可读性和可维护性。当您在执行任务时遇到它们时,或通过自动代码清除的大型清理任务(如果可能)来修复它们。如果您没有好的测试套件和集成系统,请小心使用大型自动扫描功能。确保与同事商定合适的时间运行他们,以最大程度地减少烦恼。

  5. 重复直到满意为止。

    理想情况下,如果它仍然是一种活跃的产品,那么您绝对不应该这样做:它会不断发展。

保持家务的快速提示

  • 处于hotfix-mode时,根据客户支持请求:

    • 它通常是一个最好的做法不是去周围固定等问题,因为你可能不情愿地引进新的。
    • SEAL风格进行:进入,杀死bug,退出并发布补丁。这是外科手术和战术打击。
  • 但是,对于所有其他情况,如果您打开文件,则有责任执行以下操作:

    • 绝对: 查看它(做笔记,文件问题报告),
    • 也许: 清理它(样式清理和轻微违规),
    • 理想情况下: 重构它(重组大块及其近邻)。

只是不要在一个文件到一个文件上花费一周的时间,而最终会花费数千个修复程序(涉及多个功能和模块)的巨大变更集-这就使将来的跟踪变得困难。代码中的一个问题=跟踪器中的一张票。有时,变更集可能会影响多个票证。但是,如果发生的次数过多,则可能是您做错了什么。


附录:管理可视化编程环境

定制编程系统的围墙花园

像OP的G2这样的多种编程系统是不同的野兽...

  • 没有源“代码”

    通常,它们使您无法访问源“代码”的文本表示形式:它可能以专有的二进制格式存储,或者可能以文本格式存储内容,但对您隐藏了。定制的图形编程系统实际上在研究实验室中并不罕见,因为它们简化了重复数据处理工作流程的自动化。

  • 没有工具

    除了自己,就是这样。您经常受到他们的编程环境,他们自己的调试器,他们自己的解释器,他们自己的文档工具和格式的束缚。它们是 围墙花园,除非它们最终吸引了足够动力来反向格式化其格式并构建外部工具(如果许可证允许)的人的兴趣。

  • 缺乏文件证明

    通常,这些是利基编程系统,用于相当封闭的环境中。使用它们的人经常签署保密协议,从不谈论自己的工作。为他们编程的社区很少。因此资源稀缺。您只能使用官方参考资料,仅此而已。

具有讽刺意味的(常常令人沮丧的)一点是,这些系统所做的所有事情显然都可以通过使用主流和通用编程语言来实现,而且效率可能更高。但这需要更深入的编程知识,而您不能指望生物学家,化学家或物理学家(仅举几例)对编程有足够的了解,甚至没有更多的时间(和愿望)来实现(和维护)编程复杂的系统,可能会长期存在,也可能不会长期存在。出于相同的原因,我们使用DSL,所以我们有这些定制的编程系统。

个人轶事2:实际上,我本人就是其中之一。我没有按照OP的请求进行链接,但是我的项目是一组相互连接的大型数据处理和数据存储软件(主要用于生物信息学,医疗保健和化妆品,也用于商业)情报或任何暗示跟踪大量研究数据以及准备数据处理工作流和ETL的领域)。这些应用程序之一就是一个简单的可视化IDE,它使用了常见的功能:拖放界面,版本化的项目工作区(使用文本和XML文件进行元数据存储),大量可插拔的异构数据源驱动程序以及可视化程序。设计画布以设计管道以处理来自N个数据源的数据,最后生成M个转换后的输出,以及可能的闪亮可视化效果和复杂(和交互式)的在线报告。您典型的定制视觉编程系统,会在设计适合用户需求的系统的幌子下患上NIH综合症。

而且,正如您所期望的那样,它是一个不错的系统,尽管有时有些过头,但可以灵活地满足其需求,因此您想知道“为什么不使用命令行工具呢?”,不幸的是,它总是处于中等规模团队在大型项目上工作,以许多不同的人以不同的“最佳”实践来使用它。

太好了,我们注定了!-我们该怎么做?

好吧,最后,以上所有内容仍然成立。如果您不能从该系统中提取大部分程序来使用更多主流工具和语言,那么您“只是”需要使其适应系统的约束即可。

关于版本控制和存储

最后,即使在最受限制和围墙的环境中,您几乎都可以对事物进行版本控制。大多数情况下,这些系统仍然带有自己的版本控制(不幸的是,这通常是相当基本的,并且提供了还原到以前版本的功能,但没有太多可见性,只是保留了以前的快照)。它并没有像您选择的SCM那样完全使用差异变更集,并且可能不适合同时提交变更的多个用户使用。

但是,如果它们确实提供了这样的功能,那么也许您的解决方案是遵循上面我们广受欢迎的行业标准准则,并将其转换为该编程系统!

如果存储系统是数据库,则它可能具有导出功能,或者可以在文件系统级别进行备份。如果使用的是自定义二进制格式,则可以简单地尝试使用对二进制数据有良好支持的VCS对它进行版本控制。您将无法进行细粒度的控制,但是至少您可以避免灾难的发生,并且一定程度地符合灾难恢复要求。

关于测试

在平台本身中实施测试,并使用外部工具和后台作业来设置常规备份。很可能,您启动这些测试的方式与启动使用该编程系统开发的程序的方式相同。

当然,这是一项艰巨的工作,并且绝对不符合“常规”编程的通用标准,但其思想是在尝试保持专业软件开发过程的外观的同时适应系统。

道路漫长而陡峭...

像在利基环境和定制的编程系统中一样,就像我们上面所暴露的那样,您处理的是奇怪的格式,只有数量有限(或完全不存在)的可能笨拙的工具,以及代替社区的空白。

建议:尽量在定制的编程系统之外实施上述准则。这样可以确保您可以依赖具有适当支持和社区推动力的“通用”工具。

解决方法:如果这不是一种选择,请尝试将该全局框架改造为“盒子”。这个想法是将行业标准最佳实践的蓝图叠加在您的编程系统之上,并加以利用。该建议仍然适用:定义结构和最佳做法,鼓励合规。

不幸的是,这意味着您可能需要潜入水中并进行大量的腿部锻炼。所以...

著名的遗言和谦卑的要求:

  • 记录您所做的一切。
  • 分享您的经验。
  • 开源您编写的任何工具。

通过完成所有这些操作,您将:

  • 不仅增加了您在类似情况下获得支持的机会,
  • 而且还可以为其他人提供帮助,并促进围绕技术堆栈的讨论。

谁知道,您可能是一个新兴的,晦涩难懂的语言X社区的开始。如果没有,则开始一个!

  • Stack Overflow上提出问题,
  • 甚至可能为在51区建立一个新的StackExchange网站撰写提案 。

里面也许很漂亮,但是到目前为止没人知道,所以请帮忙拆除这堵丑陋的墙让其他人看看!


22
注意:关于此注释的注释已失去控制,已被清理。Haylem已将最相关和最有用的答案纳入答案。另外-答案非常接近帖子的30,000个字符的限制。请谨慎编辑。
克里斯·

3
Continuous Integration只有一个遗漏,这是一个重要的区别:不要责怪人们签入不当,不要责怪他们没有及时清理。可以犯错。错误可以帮助您学习,但是让同事遭受错误的困扰会浪费时间,精力,在最坏的情况下还会引起怨恨。
杰森2012年

96
我什么时候可以购买精装本答案?
LarsH 2012年

5
最初,我被这个答案关闭了。我不太确定为什么,但是这个措词使我误解了,觉得有点太高级了。但是,在逐节阅读该指南(而不是一次开会)后,我发现它非常有帮助。如果您发现此答案令人生畏,并已在未阅读本评论的情况下做出了评论,请返回并阅读其中一部分。
sdasdadas

5
太僵硬,曲折,说明明显。如果这是您的议程/策略,那么一个月左右之后,没有人会再听您的话。
2013年

101

非常第一步介绍一个版本控制系统的(SVN,GIT中,水银,TFS等)。对于具有重构功能的项目,必须具有此功能。

编辑:关于VSC-每个源代码管理程序包都可以管理二进制文件,尽管有一些限制。市场上的大多数工具都具有使用自定义差异查看器和编辑器的能力,并使用此功能。二进制源文件不是不使用版本控制的借口

关于如何处理遗留代码也有类似的帖子,可能是一个很好的参考- 有关使用遗留代码的建议


19
不幸的是,G2语言的缺点之一是源文件不是人类可读的(它基本上是一种图形语言,类似于LabView),因此实现版本控制充其量是不平凡的。实际上,这是我们目前最大的障碍之一(IMO)。
kmote 2012年

4
@kmote:G2的制造商是否有自己的特殊工具来帮助进行版本控制?还有其他人做过这样的工具吗?
FrustratedWithFormsDesigner 2012年

39
每个源代码管理程序包都可以管理二进制文件,尽管有一些限制。我知道的每个工具都可以使用自定义差异查看器和编辑器,请使用此功能。二进制源文件不是不使用版本控制的借口。
mattnz

11
您可以对G2文件格式进行反向工程,并创建实用程序以diff友好文本格式转储它。这看似令人生畏,但是对于这么大的代码库,值得付出努力(在我看来是天真的)。
乔伊·亚当斯

6
@Erik:仅将版本控制用作“回滚”工具,有点像购买保时捷来进行杂货店购物-它可以完成其他任何事情,但是它可以为您做更多。
mattnz

43

当我必须处理意大利面条式代码时,我要做的第一件事就是模块化。查找可以画线并提取(或多或少)代码库独立片段的地方。由于高度的互连性和耦合性,它们可能不会很小,但是如果您寻找它们,则会出现一些模块线。

一旦有了模块,就不再面临清理整个凌乱程序的艰巨任务。现在,您需要清理几个较小的独立凌乱模块。现在选择一个模块,并以较小的比例重复。找到可以将大型函数提取为较小的函数甚至类的地方(如果G2支持的话)。

如果语言具有足够强大的类型系统,这一切都将变得容易得多,因为您可以让编译器为您完成很多繁重的工作。您在某个地方进行了更改,这将(有意地)破坏兼容性,然后尝试进行编译。编译错误将直接把您带到需要更改的地方,而当您停止获取它们时,您已经找到了一切。 然后运行程序并测试所有内容! 重构时,连续测试至关重要。


17
有效使用旧版代码可能是必须阅读的内容。
奥德

3
更好的是..不仅仅是测试程序,还需要对新模块进行单元测试:)
Demian Brecht

1
这是最好的方法(以及使整个批次进入版本控制的显而易见的步骤)。大答案中的所有内容都过于笼统,太大,无法一口气应用。宝贝一步,直到您对整体事物有了一些了解。我一次继承了一个50k项目(实际上是四个基本相同的50k版本)。一个月后,我有了一个版本,并通过基本的重构/重组消除了大约1万行。1将其粘贴在存储库中,2确保可以构建它,3进行重构/重组,重复3直到完成。

22

我不知道这是否是您的选择,但我会开始尝试说服他们雇用更多的专业开发人员。这样,他们可以集中精力解决领域问题(我敢肯定他们在那里有足够的知识)。

我相信他们是非常聪明的人,但是要成为一名优秀的开发人员需要很多时间。他们准备在不是主要业务的活动中花费很多时间吗?恕我直言,这不是获得最佳结果的方法。


16
OP是第一个专业开发人员。OP希望他们说服更多人的最佳方法是OP在头6到12个月内提供一些明显的额外价值。如果能够做到这一点,OP将具有信誉,并可能雇用更多人。
MarkJ 2012年

20

哇。听起来您面临巨大的挑战!我会按照以下方式做一些事情:

  • 首先:确定优先级。您首先要实现什么?对于项目的当前状态,最重要的是什么?您将从中获得最大的收益以及到达那里所需的时间。
  • 确保您具有版本控制系统。例如GitMercurial
  • 启动并运行某种持续集成系统(例如Jenkins)。
  • 启动错误跟踪系统并运行。我认为螳螂很好。
  • 研究静态代码分析(如果您当前使用的语言可用)。
  • 从变量的命名到通用的代码约定以及代码库中的准则,在任何方面都应力求达到最大的一致性
  • 获取被测系统。我认为,这对于像这样的大型遗留系统极为重要。使用测试用例来记录现有行为,而不管行为是否怪异(通常,为什么代码看起来确定为什么是好还是不好,或两者兼有,通常是有原因的; P)。迈克尔·费瑟斯(Michael Feathers)有效地使用遗留代码是为此的绝佳资源。

10

他们说解决问题的第一步就是承认自己有一个。考虑到这一点,您可能首先要生成一个依赖关系图,该图说明当前代码库的巨大纠结。生成依赖关系图的好工具?已有数年历史,但其中包含一些指向可以帮助创建此类图形的工具的指针。我会用一张巨大的,丑陋的大图来显示尽可能多的线索。讨论由于过多的相互依赖性而产生的问题,或者可能会引起Buckaroo Banzai的指责

您可以随意检查自己的解剖结构,即使可能存在正常的变异,当它下降到头部时,它在头部的深处看起来也一样。不,不,不,不要拉扯。您永远都不知道它可能会附加到什么。

从那里开始,引入一个计划以理顺混乱。将代码分成尽可能独立的模块。对如何做到这一点持开放态度-与您交谈的人们比您更了解代码的历史和功能。但是,目标是解决一个大问题并将其转变为一些较小的问题,然后可以对其进行优先级排序并开始进行清理。

需要注意的一些事情:

  • 在模块之间创建干净的接口并开始使用它们。旧代码可能有必要继续在一段时间内不使用那些好的新接口-这就是您要解决的问题。但是,请大家同意只使用新的接口。如果接口中有他们需要的东西,请修复接口,不要绕开它们。

  • 寻找重复相同功能的情况。努力实现统一。

  • 时不时提醒所有人,这些改变旨在使生活更轻松,而不是更困难。过渡可能会很痛苦,但这是出于良好的目的,所有人参与的人越多,收益就会越快。


1
@kmote如果他们不认识到他们需要帮助并希望做得更好,他们将不会雇用您。困难的部分可能是帮助他们记住您的工作不是解决问题,而是帮助他们解决问题。巴卡鲁·班扎伊(Buckaroo Banzai)在某个年龄段的科学类型中非常受欢迎-也许他可以帮助您保持轻巧。
卡勒布(Caleb)2012年

9

在深入研究Gensym G2之后,似乎解决此问题的方法将高度依赖于代码量的多少,如下所示:

在此处输入图片说明

或这个:

在此处输入图片说明

与此相对,由99瓶啤酒提供

beer-bottles()

i:integer =99;
j:integer;
constant:integer =-1;

begin
for i=99 down to 1
    do
    j = (i+constant);
        if (i=1) then begin
            post"[i] bottle of beer on the wall";
            post" [i] bottle of beer";
            post" Take one down and pass it around ";
            post" No bottle of beer on the wall"; 
        end 
        else begin
            post"[i] bottles of beer on the wall";
            post" [i] bottles of beer";
            post" Take one down and pass it around ";
            if (i=2) then 
                post" [j] bottle of beer on the wall"
           else
                post" [j] bottles of beer on the wall"; 
           end
    end
end

对于后者,您正在使用的源代码实际上是已知的数量,而其他一些答案则为处理它提供了一些非常明智的建议

如果大多数代码库是后者,或者即使有相当大的块,那么您将遇到一个有趣的问题,即由于过于专业化,或更糟糕的是,看起来像它可能是可移动的,但是除非对其进行了适当的记录,否则您不知道是否要删除看上去乍一看并非如此的关键代码(按照scram操作的思路进行思考)。

正如ElYusubov指出的那样,尽管显然您的首要任务是在线进行某种版本控制,但从8.3版本开始,确实已经支持版本控制。由于G2是几种不同语言方法的组合,因此您可能会发现使用G2随附的版本控制是最有效的方法,而不是尝试查找其他内容并使它工作。

接下来,尽管有些人可能会提倡进行重构,但我坚决主张在开始接触任何代码之前,请确保您完全了解要使用的系统,尤其是在处理由以下人员开发的代码和可视化图时:未经软件工程方法方面的正式培训(或背景)的开发人员。这样做有多种原因,但是最明显的原因是您正在使用的应用程序可能要投入100多人年的工作量,因此您确实需要确保您知道它在做什么以及需要多少工作。其中有文档。您没有说系统部署到哪个行业,根据我对G2的了解,可以肯定地认为它很可能是一项关键任务应用程序,甚至具有潜在的生命安全隐患。因此,准确地了解它在做什么将非常重要。它有未记录在案的代码,无法与团队中的其他人一起工作,以确保已建立文件以确保人们可以确定代码的作用。

接下来,开始围绕尽可能多的代码库和可视化图包装单元测试。我必须承认对于如何使用G2做到这一点有些无知,但是几乎值得创建自己的测试框架来实现这一点。这也是开始介绍团队的其他成员,以使他们使用与代码质量相关的一些更严格的工程实践(即,所有代码必须具有单元测试和文档)的理想时机。

一旦对相当数量的代码进行了单元测试,就可以按照haylem建议的方式开始进行重构。但是,请记住要记住,您正在处理的问题是开发专家系统并进行重构,这可能是艰巨的战斗。实际上,在这种环境下,有些事情是有时编写通用代码的。

最后,请确保您密切注意其他团队成员所说的话,仅仅是因为代码和图表的质量不是最好的,也不一定会对他们产生不良影响。最终,他们暂时可能比您更了解应用程序的功能,这就是为什么让您坐下来并确保在进行全面更改之前了解应用程序的作用更为重要。


1
@haylem-不知道,应用程序中可能完全有200,000 LOC加n个流程图和图表。因此,200,000 LOC可能会大大低估应用程序的复杂性。
rjzii 2012年

9

通常,您预先听到的投诉与重要问题无关。毕竟,在任何软件项目中听到这些抱怨都是很正常的。

难以理解的代码?校验。大量的代码库?校验。

真正的问题是人们离开了,而当新人加入该组织时,就会出现一种典型的迷失方向。此外,还有一个不切实际的期望和代码质量问题。

以下是我要解决的问题:

  1. 服务器和本地版本的备份
  2. 设置错误跟踪器
  3. 设置版本控制系统
  4. 设置常见问题解答/ Wiki
  5. 所有科学家/程序员的第一次汇报
    • 提醒他们80/20规则。20%的错误负责80%的问题。
    • 关注最大的问题,并保留增强请求等。
    • 这样做的目的不是要吓people一大堆人,而是要列出一小部分可以实现的胜利。毕竟,您还必须证明自己的价值。
  6. 设置构建系统
    • 开始致力于获得可靠的版本(这可能需要一段时间)
    • 识别并命名每个项目
    • 识别循环依赖
    • 如果有来自某些开源项目的二进制文件,请尝试获取源代码
  7. 确定如何将G2代码模块化,例如API,服务
  8. 确定如何测试和记录G2代码。
  9. 设置代码审查系统
  10. 第二次汇报
  11. 找出一支由更好的程序员组成的精干团队,并与他们一起包装模块。
  12. 在此阶段进行代码审查以改善沟通和文档编制。在此阶段保持简单。整理任何过程问题。
  13. 向其他程序员推广该系统。让精明的团队成员成为其他团队的同伴导师。请记住,缩放是这里的问题。您实际上是担任管理角色。

9

诸如此类的问题是Software Carpentry项目存在的全部原因。

在过去的14年中,我们一直在教科学家和工程师基本的软件开发技能:版本控制,测试,如何模块化代码等等。我们所有的资料都可以通过知识共享(Creative Commons)许可免费获得,并且我们每年举办几十个为期两天的免费研讨会,以帮助人们入门。

基于此,我认为最好的出发点可能是罗伯特·格拉斯(Robert Glass)出色的(简短的)软件工程的事实和谬论:基于证据的方法是一种使科学家信服我们告诉他们的良好编程习惯的好方法。不仅仅是意见。
对于特定的实践,人们最愿意采用的两个是版本控制和单元测试。一旦这些就绪,他们就可以解决Michael Feathers在“有效地使用旧版代码”中描述的那种系统重构。
我不再推荐The Pragmatic Programmer(很多建议,新手很难付诸实践),而且我认为McConnell的代码完整 一开始的内容太多了(尽管一旦他们掌握了基础知识,给他们六个月或一年的时间是一件很棒的事情)。

我还要强烈推荐Paul Dubois的出色论文“在科学程序中保持正确性”科学与工程计算, 2005年5月至6月),该论文描述了一种“深度防御”方法,该方法结合了十几种不同的实践,形成了逻辑,连贯的方式。


有趣的建议。我会检查出来的。(注意:Dubois纸上的链接断开)
kmote 2012年

7

我认为首先您必须清除您的情况。他们想从你那里得到什么?

  • 他们极不可能让您学习一门古老的语言,因为这似乎是一个死胡同:发现或知道学习G2的人的机会越来越少,因此,当您将知识隐藏在崩溃的代码堆中时,当前的科学家离开或全部修补的代码越来越失败。
  • 科学家(或其中的一些科学家)是否准备好学习一种新的语言和许多编程范例?还是他们希望从长远来看将编程和科学活动区分开来,并且如果需要的话,也许还有更多的程序员?这似乎是专业知识的合理,有效的分离。

我认为这里的核心要求是“在系统中保存知识”,因此您必须去挖掘它!

第一个任务是编写文档。

分析结构和需求,就好像这是一项新任务一样,但是要借助现有系统。他们会很高兴,因为您先问而不是示教,您很快就会获得足够的知识,但是从程序员的角度来看,它是更有组织的背景知识:“这是怎么回事?” 这些文档(系统静态结构,工作流,组件,问题)对他们而言将立即有价值,并且可能会向您显示比您更多的相关信息(某些人可能拥有“ AHA!”并立即开始修复一些代码)...

然后,您应该开始询问他们想去哪里?

如果他们准备离开G2,他们想看到什么系统(平台,语言,界面,总体结构)?您可能会尽可能在系统周围编写具有目标结构但保留原始组件的外部包装程序,从而慢慢启动一种框架,该框架允许在此目标环境中实现新组件。您必须找到核心服务(持久数据连接和“工具包”:核心计算,图形,...库),然后以新平台和语言为它们提供熟悉的环境,从而可以由您或它们:将旧代码一一处理,并在新环境中重新实现(并清洁!)。准备就绪后,他们就会知道新的语言。服务层(大多数情况下由您自己制作,很抱歉)已准备好托管新组件。

如果他们不动,那么您必须学习G2,并在那里创建模块化框架,您或者他们应该将组件移入其中(清洁)。无论如何,该语言只是数据和算法树的序列化...

在分析和编写文档时,请阅读,使用和宣传GoF设计模式!:-)

...我的2美分


我同意第一步是要弄清楚他们想要从您那里得到什么,但是下一步应该是这样做,并且如果下一步不是要记录事态,则不要做太多事情。如果您这样做,他们将不胜感激。
2012年

@bill:问题说:“关于前进道路需要什么,没有达成共识”。他们不知道!我假设存在认真辩论,而对系统的真实见解必须“以某种方式”保存。在这种情况下,程序员的任务是显而易见的(至少对我而言):从技术角度进行正确的分析以帮助做出合理的决定。
Lorand Kedves

当然,他们不知道自己想要什么,那是“解决问题”的部分,这与仅选择文档和模式之类的东西并说出要做的事情不同。那些东西是好东西,但必须要有一个与团队相关的过程,如果您从一开始他们没有看到价值的东西开始,那么您将很难买到东西。-干杯!
2012年

@Bill:我想您说的与我写的内容和文档
完全相同

4

我刚刚为我的同事做了一系列关于Robert Martin的SOLID原则的演讲。我不知道这些原则如何很好地转化为G2,但是由于您正在寻找5-7个核心基础知识,因此这些似乎是一门非常完善的工具。如果要将其四舍五入到7,则可以从DRY开始并抛出Fail-Fast。


1
哦,很好的建议!让我想起了这个不错的概述以及这个免费的电子书摘要
kmote 2012年

3

唯一的生产问题听起来像是变更管理问题。如果是这样,并且软件执行了其他目的,那么我要提出的第一条建议就是抵制过快地执行太多操作的冲动。

源代码控制,重构,训练有素的开发人员都是不错的建议,但是,如果这是您第一次不得不处理此类问题,那么此举将缓慢地进行,并且不能充分强调进行受控的更改。

有时,切碎碎片的欲望会很大,但是在您对它进行足够的反向工程之前,您知道可以充分测试替代版本,因此需要非常小心。


3

在这种情况下工作的最重要原则是:

  1. 耐心一点。一个需要花20年时间挖的洞不会在几周内被填满。

  2. 要乐观。抵制抱怨和抱怨的诱惑。

  3. 务实。看看您一天可以完成的积极变化,今天就可以做到。有版本控制系统了吗?实施并培训人员。然后查看是否可以自动化测试(单元测试或类似测试)。冲洗。重复。

  4. 做个模特。通过敏捷向人们展示(而不是仅仅告诉)敏捷如何工作。上面的前三点是成为好人的关键,而好人是成为有效的敏捷人的前身。在我看来,令人钦佩的开发人员不仅聪明,而且还很好,可以模范员工和同事。

  5. 绘制您的领土。我有一种映射巨型遗留代码库的技术。我克隆了仓库,制作了工作副本,然后尝试更改某些内容,看看还有什么坏处。通过调查耦合(通过全局状态,或损坏的API,或缺少一致的API或要针对其编程的任何抽象或接口),并通过阅读在更改事物时会中断的代码,我发现了问题,提出了一些问题团队其他成员的见解(哦,我们补充说,因为5年前的Boss X要求这样做,但它永远行不通!)。随着时间的流逝,您将获得该地区的思维导图。知道它的大小后,您将足以制作地图并回家。鼓励其他人映射您的巨型代码库的范围,并建立团队的技术知识。有人不愿接受“文档” 因为它不敏捷。随你。我也在科学环境中工作,文档对我来说是最重要的,敏捷的宣言是该死的。

  6. 构建小应用程序。当使用遗留代码库时,我发现我陷入了困境。我通过构建小助手应用程序使我恢复了精神。也许这些应用程序将帮助您阅读,理解和修改庞大的G2代码库。也许您可以制作一个迷你IDE或解析器工具,以帮助您在环境中工作。在许多情况下,元编程和工具构建不仅可以帮助您摆脱旧代码库强加给您的巨大僵局,还可以使您的大脑不受G2语言限制地飞行。用您可以最快和最好的语言来编写工具和帮助程序。对我而言,这些语言包括Python和Delphi。如果您是Perl的人,或者您实际上喜欢C ++或C#编程,请使用该语言编写帮助工具。


3
  1. 修订控制:向域专家展示可以还原,查看谁更改了内容等的好处。(对于全二进制文件,这更难,但是如果内容确实是代码,则肯定存在某种G2-to-可以启用差异的文本转换器。)

  2. 持续集成和测试:让领域专家参与创建端到端测试(更容易,因为他们必须已经在某处输入和预期输出)和小型单元测试(更困难,因为意大利面条代码可能涉及很多全局变量),涵盖几乎所有功能和用例。

  3. 将通用代码重构为可重用的例程和组件。没有修订控制权的非软件人员可能一次复制并粘贴100行以创建例程。找到它们并对其进行重构,表明所有测试都通过了,代码变得更短了。这也将帮助您学习其体系结构。如果您幸运的时候不得不开始做出艰难的架构决策,那么您可能会损失100KLOC。

从政治上讲,如果您在此过程中遇到了旧计时器带来的阻力,请聘请顾问来介绍良好的软件方法。确保找到一个您同意的意见的好人,并让管理者对顾问的必要性予以回购,即使领域专家不同意。(他们应该同意-毕竟,他们雇用了您,所以很显然他们意识到他们需要软件工程专业知识。)当然,这是一种浪费金钱的把戏,但是原因是,如果您-新的热门年轻人程序员-告诉您他们需要做某事,他们可能会忽略它。但是,如果管理层向一名顾问支付5000美元进场并告诉他们他们需要做什么,他们就会对此更加信任。奖励积分:让顾问为您提供两倍于您真正想要的更改的建议,那么您可以成为“好人”,并与领域专家一起,妥协更改的幅度仅为顾问建议的一半。


3

“该程序本身是复杂化学加工厂的物理模型……”

“因为G2就像不是代码,而是由某些恶作剧的GUI编写的自动化代码...” – Erik Reppen

假设您软件的主要目标是模拟(或优化,对其中的一部分)复杂的化工厂进行分析,那么我想提出一个截然不同的建议:

您可能会考虑使用高级数学建模语言手工编码的软件中提取本质(即核心数学模型),这很不错。

建模语言的作用是将问题的描述与用于解决问题的算法脱钩。这些算法通常适用于给定类别的大多数模拟/优化(例如化学过程),在这种情况下,实际上不应重新发明和维护它们。

在您的行业中广泛使用的三个商业软件包是:gPROMS,Aspen Custom Modeller,以及(如果您的模型不包括沿空间域分布的现象)则有基于Modelica的软件包,例如Dymola。

所有这些软件包都以一种或另一种方式支持“扩展”,因此,如果模型的某些部分需要自定义编程,则可以将它们封装到一个对象(例如.DLL)中,该对象可以由模型。同时,您的模型的大部分内容仍然简洁明了,以科学家容易直接理解的形式进行了描述。这是捕获公司知识和IP的更好的方法。

这些程序中的大多数还应允许您通过从外部调用来“开始较小”并将整体代码的较小部分(子模型)移植为它们的格式。这可能是维护工作系统并一次验证一个系统的好方法。

完全免责声明:我在gPROMS背后的公司工作了8年,担任软件工程师。在那段时间里,我看到了(有时是并入了)自定义软件(例如来自学术界)的示例,这些示例开始时小而整洁,实现了一些聪明的解决方案或算法,但随后几年又进行了扩展和修改,在没有保持软件清洁的软件工程师。(我是多学科团队的忠实拥护者。)

因此,我可以凭经验说,某些在软件开发初期做得不好的键选择(例如语言或键库)往往会长期存在并引起痛苦……他们已经“塑造”了他们周围的软件。在我看来,您可能会在这里面临很多年的纯代码清理。(我不愿意使用数字,但我想使用10人以上的年,如果您无法将代码从G2移植到支持良好的自动重构工具(例如Eclipse / Java快速智能工具)的情况下,可能会更多。

虽然我的默认状态是“重构并保持正常工作的系统”,但我也认为,一旦问题变得“太大”,那么更彻底的更改/重写总体上将变得更快。(并且可能带来其他好处,例如,跳到更先进的技术。)我说,虽然有一些移植到新软件平台的经验,但是从我收集的经验来看,移植到数学建模程序包会更加生动。

为了提供一些观点,您可能会对尺寸减小感到惊讶。例如,实际上200,000个LoC可以用大约5,000行方程式表示(好的,我想在这里,但我可以尝试从企业朋友那里获得真实的证明);加上一些用C编写的相对较小的功能模块(例如,物理属性计算-尽管根据您的化学过程,可能还会有现成的包装)。这是因为您实际上只是丢弃了算法解决方案代码,而是让通用的“堆栈”数学求解器完成了艰苦的工作。运行模拟后,您可以使用它们做更多的事情,例如优化流程-无需更改代码行。

最后我要说:如果各种数学模型(和算法)的唯一可靠文档是代码本身,那么您将需要科学家和原始作者的帮助,尽快地将那些模型提取出来,其中一些人可能已经继续前进。他们应该发现数学建模语言是捕获这些模型的非常自然的方式-他们甚至可能(震惊)喜欢(重写)它。


最后,由于我的答案可能不合时宜,所以我想再增加一本书到已经在这里引用的好书列表中:Robert Martin编写的Clean Code。充满了简单(合理)的技巧,这些技巧易于学习和应用,但对于在公司中开发新代码的人们来说可能会大为不同。


2

我会拒绝以下内容:

  1. 这里有一个程序员。搞政治。他们知道自己的交易。你知道你的。标记该领土,即使您必须在上面撒尿。他们是科学家。他们可以尊重或应该尊重这种事情,因为他们自己经常不断地做同样的事情。尽您所能,立即标记边界。这就是我要解决的问题。这是我不能负责的。

  2. 科学家编写/测试算法。想要用1-3种语言编写自己的算法的科学家,每个人都可以同意您将其转换为核心代码。这样就可以测试他们的东西了。除此之外,他们将不得不帮助您隔离重要的科学知识和良好的知识-他们对建筑所做的工作。代码库已连接。需要进行大量的削减和烧伤。为他们提供选择权,让他们使用他们最了解的东西来工作,以便您可以做自己最擅长的事情。将他们的知识放在他们负责但可以合作的盒子中。

  3. 如果可以,请使用具有一流事件处理功能的事件驱动友好语言。当所有其他方法都失败时,如果您深陷于毫无血腥意义的代码中,那么触发实际上是有意义的接口或状态机制触发事件或将回调扔给某个对象可能会节省大量的时间将。科学家似乎喜欢Python。用它来粘合低级数学密集型C东西并不难。只是在说'

  4. 寻找解决了这个问题或类似问题的人。花一些时间研究。这些人从某人那里听说过G2。

  5. 设计模式。适配器。使用它们。在这种情况下经常使用'em。

  6. 了解科学知识。您知道的越多,就越能确定代码中的意图。


13
永远不要与科学家并肩作战永远不要。他们会让您的生活变成地狱。:)
haylem

2

首先进行分析。

在决定教什么之前,我会做一些分析。找出最大的痛点在哪里。使用这些优先级确定要采取的措施。

一次只介绍一些更改(在类似情况下,我每2周进行2-3次练习)

根据SDLC编程风格的变化程度,我将实践限制为〜3;直到他们开始对他们感到满意为止(我会推动每1至2周引入1个新更改,因为他们对学习新方法的想法会更加满意)。确定成功的标准是一个好主意。练习应该完成什么(即使是像团队士气这样的软目标)。这样,您可以显示它是否有效。

  • 为什么要限制更改数量?

即使您假设这些人希望成为更好的程序员并乐于学习,人们学习新概念并应用它们的程度和速度仍然受到限制。尤其是如果他们没有CS基础或以前参加过软件开发生命周期。

添加每周总结会议,讨论这些做法如何影响他们。

会议应被用来讨论进展顺利和需要开展的工作。让他们发表意见并保持合作。讨论并制定计划以解决他们遇到的问题,并预览即将发生的下一个更改。使会议集中在实践及其应用上。宣传他们从实践中应该看到的好处。

某些做法优先。

正确使用版本控制系统(IMO)胜过其他一切。紧随其后的是模块化,耦合/内聚和功能/错误单跟踪的课程。

删除无效的做法。

不要害怕摆脱无效的做法。如果成本高昂,却几乎没有收益,请取消该做法。

改善是一个过程。

表示持续不断的改进是一个过程。确定最大的痛点,应用解决方案,等待/指导,然后重复。最初,您会感到非常痛苦,直到您建立起一定的动力为止。让每个人都专注于即将到来的改进和已经成功的改进。


0

听起来您的第一步是将需要购买新软件方法的资金卖给团队。根据您的陈述,团队中没有共识,您将需要它能够缓慢地“升级”代码。

我将(如果可以的话)亲自吸取教训,并介绍您要解决的每个关键概念,以解决软件行业中的问题。

例如,两个开发人员拥有不同的副本,并最终部署了一个未经测试的混合发行版本->引入了版本控制,分支和测试。

有人删除了几行他们不理解的代码,造成了中断->介绍DDD。

如果没有与您足够详尽地分享艰苦的课程,请仅显示您自己的示例,说明在不遵守该学科的情况下情况如何出错。


0

如前所述,源代码控制是步骤1。虽然您与之共事的人可能不是专业的开发人员,并且他们不会对许多企业或敏捷的大型企业做出回应。它们也不是低级代码猴子,而是通过强迫它们“按自己的方式”做事,试图像对待猴子那样对待它们。

您必须调查那里的情况。如果他们还没有使用源代码控制,那么仅仅确定代码的正确版本(如果可能)以及所有可能的交付结果将花费很长时间。然后,您将承担着教您的同事如何使用源代码控制并说服他们相信自己的时间值得的任务。从好处开始!

在执行此操作时,请找到其他低挂的水果并解决这些问题。

最重要的是,倾听他们的意见,并努力改善他们的处境。不必担心尝试在他们的工作上打上烙印。

祝好运!

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.