前言
确实,这是一项艰巨的任务,并且有很多方面需要解决。因此,我谨以此建议为您的团队提供一些全面的指导,并提供指向适当工具和教材的指南。
请记住:这些是准则,因此应根据情况采用,改编或删除。
当心:一次将所有这些都丢给一个团队很可能会失败。您应该尝试挑选那些可以为您带来最佳效果的元素,然后一次缓慢地引入它们。
注意:并非所有这些都直接适用于像G2这样的可视编程系统。有关如何处理这些错误的更多详细信息,请参阅末尾的附录部分。
不耐烦的执行摘要
- 使用以下内容定义一个刚性项目结构:
- 项目模板,
- 编码约定,
- 熟悉的构建系统,
- 以及针对您的基础架构和工具的使用指南集。
- 安装良好的SCM,并确保他们知道如何使用它。
- 为他们的技术指点优秀的IDE,并确保他们知道如何使用它们。
- 在构建系统中实施代码质量检查器和自动报告。
- 将构建系统耦合到持续集成和持续检查系统。
- 在上述帮助下,确定代码质量“热点”并进行重构。
现在是长版本...小心,请自行准备!
刚性(通常)是好的
这是一个有争议的观点,因为僵化通常被视为对您不利的力量。在某些项目的某些阶段确实如此。但是,一旦您将其视为结构性的支持,即消除了猜测的框架,它就会大大减少浪费的时间和精力。让它为您服务,而不是对您不利。
刚性 = 过程 / 程序。
出于与化工厂或工厂具有手册,程序,演习和紧急指导的完全相同的原因,软件开发需要良好的过程和程序:防止不良后果,提高可预测性,最大化生产率...
刚度要适度!
项目结构的刚性
如果每个项目都有其自己的结构,那么您(和新手)会迷路,并且每次打开它们时都需要从头开始。您不希望在专业的软件商店中使用它,也不想在实验室中使用它。
建造系统的刚性
如果每个项目看起来都不同,则很有可能它们的构建方式也
不同。一个构建不需要太多的研究或太多的猜测。你要能够做到规范的事情,而不是需要担心的细节:configure; make install
,ant
,
mvn install
,等...
重复使用相同的构建系统并使其随时间变化也可以确保质量始终如一。
您确实需要快速README
指出项目的细节,并优雅地指导用户/开发人员/研究人员(如果有)。
这也极大地促进了构建基础结构的其他部分,即:
因此,请保持您的构建(例如您的项目)为最新,但随着时间的流逝使它变得更加严格,并在报告违规和不良做法时更加有效。
不要重新发明轮子,而要重复使用已经完成的工作。
推荐读物:
- 持续集成:提高软件质量并降低风险(Duval,Matyas,Glover,2007年)
- 持续交付:通过构建,测试和部署自动化发布软件发布(Humble,Farley,2010年)
编程语言选择中的刚性
您不能期望,尤其是在研究环境中,所有团队(甚至更少的所有开发人员)都使用相同的语言和技术堆栈。但是,您可以确定一组“官方支持”的工具,并鼓励使用它们。其余的,如果没有充分的理由,则不应被允许(除了原型之外)。
使您的技术堆栈简单,并使所需技能的维护和广度降至最低:坚固的核心。
编码公约和准则的严格性
编码约定和准则使您可以发展团队身份和共享术语。你不想犯错进入未知领域每次打开源文件的时间。
愚蠢的规则使生活变得更加艰苦或禁止采取明确的行动,以至于仅仅基于一次简单的违反就拒绝了提交,这是一种负担。然而:
个人方法:在编码约定方面,我很激进,有些人甚至说纳粹,因为我确实相信拥有
通用语言,这对我的团队来说是一种公认的风格。签入废话代码时,它像好莱坞明星脸上的唇疱疹一样突出:它会自动触发审阅并采取行动。实际上,我有时甚至提倡使用pre-commit钩子拒绝不合格的提交。如前所述,它不应该太疯狂而妨碍生产力:它应该推动生产力。慢慢地介绍这些内容,尤其是在开始时。但这比花费大量时间修复错误代码以致于无法处理实际问题更可取。
有些语言甚至是设计使然的:
确保代码腐烂无法通过。代码惯例,持续集成和持续检查,结对编程和代码审查是您抵御此恶魔的武器。
另外,正如您将在下面看到的那样,代码是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 |
+-----------------+ +-----------------+
一旦您掌握了一些优质的工具,即可:
使用代码质量检查器分析您的代码。
短绒,静态分析仪或您拥有的东西。
确定您的关键热点和低落的果实。
违规具有严重性级别,具有大量高严重级别的大型类是一个大的危险信号:因此,它们在散热器/热图类型的视图中显示为“热点”。
首先修复热点。
由于它们具有最高的业务价值,因此可以在短时间内最大程度地发挥您的影响力。理想情况下,严重违规应在可能出现的安全漏洞或崩溃原因中尽快处理,并具有引发责任的高风险(在您的情况下,这会对实验室造成不良影响)。
使用自动代码库清除功能清除低级冲突。
它提高了信噪比,因此您可以在雷达上看到明显的违规现象。如果一开始就经常有大量的轻微违规事件发生,即使他们从来没有得到照顾,并且您的代码库在野外也很松懈。它们不会带来真正的“风险”,但是会损害代码的可读性和可维护性。当您在执行任务时遇到它们时,或通过自动代码清除的大型清理任务(如果可能)来修复它们。如果您没有好的测试套件和集成系统,请小心使用大型自动扫描功能。确保与同事商定合适的时间运行他们,以最大程度地减少烦恼。
重复直到满意为止。
理想情况下,如果它仍然是一种活跃的产品,那么您绝对不应该这样做:它会不断发展。
保持家务的快速提示
只是不要在一个文件到一个文件上花费一周的时间,而最终会花费数千个修复程序(涉及多个功能和模块)的巨大变更集-这就使将来的跟踪变得困难。代码中的一个问题=跟踪器中的一张票。有时,变更集可能会影响多个票证。但是,如果发生的次数过多,则可能是您做错了什么。
附录:管理可视化编程环境
定制编程系统的围墙花园
像OP的G2这样的多种编程系统是不同的野兽...
没有源“代码”
通常,它们使您无法访问源“代码”的文本表示形式:它可能以专有的二进制格式存储,或者可能以文本格式存储内容,但对您隐藏了。定制的图形编程系统实际上在研究实验室中并不罕见,因为它们简化了重复数据处理工作流程的自动化。
没有工具
除了自己,就是这样。您经常受到他们的编程环境,他们自己的调试器,他们自己的解释器,他们自己的文档工具和格式的束缚。它们是
围墙花园,除非它们最终吸引了足够动力来反向格式化其格式并构建外部工具(如果许可证允许)的人的兴趣。
缺乏文件证明
通常,这些是利基编程系统,用于相当封闭的环境中。使用它们的人经常签署保密协议,从不谈论自己的工作。为他们编程的社区很少。因此资源稀缺。您只能使用官方参考资料,仅此而已。
具有讽刺意味的(常常令人沮丧的)一点是,这些系统所做的所有事情显然都可以通过使用主流和通用编程语言来实现,而且效率可能更高。但这需要更深入的编程知识,而您不能指望生物学家,化学家或物理学家(仅举几例)对编程有足够的了解,甚至没有更多的时间(和愿望)来实现(和维护)编程复杂的系统,可能会长期存在,也可能不会长期存在。出于相同的原因,我们使用DSL,所以我们有这些定制的编程系统。
个人轶事2:实际上,我本人就是其中之一。我没有按照OP的请求进行链接,但是我的项目是一组相互连接的大型数据处理和数据存储软件(主要用于生物信息学,医疗保健和化妆品,也用于商业)情报或任何暗示跟踪大量研究数据以及准备数据处理工作流和ETL的领域)。这些应用程序之一就是一个简单的可视化IDE,它使用了常见的功能:拖放界面,版本化的项目工作区(使用文本和XML文件进行元数据存储),大量可插拔的异构数据源驱动程序以及可视化程序。设计画布以设计管道以处理来自N个数据源的数据,最后生成M个转换后的输出,以及可能的闪亮可视化效果和复杂(和交互式)的在线报告。您典型的定制视觉编程系统,会在设计适合用户需求的系统的幌子下患上NIH综合症。
而且,正如您所期望的那样,它是一个不错的系统,尽管有时有些过头,但可以灵活地满足其需求,因此您想知道“为什么不使用命令行工具呢?”,不幸的是,它总是处于中等规模团队在大型项目上工作,以许多不同的人以不同的“最佳”实践来使用它。
太好了,我们注定了!-我们该怎么做?
好吧,最后,以上所有内容仍然成立。如果您不能从该系统中提取大部分程序来使用更多主流工具和语言,那么您“只是”需要使其适应系统的约束即可。
关于版本控制和存储
最后,即使在最受限制和围墙的环境中,您几乎都可以对事物进行版本控制。大多数情况下,这些系统仍然带有自己的版本控制(不幸的是,这通常是相当基本的,并且提供了还原到以前版本的功能,但没有太多可见性,只是保留了以前的快照)。它并没有像您选择的SCM那样完全使用差异变更集,并且可能不适合同时提交变更的多个用户使用。
但是,如果它们确实提供了这样的功能,那么也许您的解决方案是遵循上面我们广受欢迎的行业标准准则,并将其转换为该编程系统!
如果存储系统是数据库,则它可能具有导出功能,或者可以在文件系统级别进行备份。如果使用的是自定义二进制格式,则可以简单地尝试使用对二进制数据有良好支持的VCS对它进行版本控制。您将无法进行细粒度的控制,但是至少您可以避免灾难的发生,并且一定程度地符合灾难恢复要求。
关于测试
在平台本身中实施测试,并使用外部工具和后台作业来设置常规备份。很可能,您启动这些测试的方式与启动使用该编程系统开发的程序的方式相同。
当然,这是一项艰巨的工作,并且绝对不符合“常规”编程的通用标准,但其思想是在尝试保持专业软件开发过程的外观的同时适应系统。
道路漫长而陡峭...
像在利基环境和定制的编程系统中一样,就像我们上面所暴露的那样,您处理的是奇怪的格式,只有数量有限(或完全不存在)的可能笨拙的工具,以及代替社区的空白。
建议:尽量在定制的编程系统之外实施上述准则。这样可以确保您可以依赖具有适当支持和社区推动力的“通用”工具。
解决方法:如果这不是一种选择,请尝试将该全局框架改造为“盒子”。这个想法是将行业标准最佳实践的蓝图叠加在您的编程系统之上,并加以利用。该建议仍然适用:定义结构和最佳做法,鼓励合规。
不幸的是,这意味着您可能需要潜入水中并进行大量的腿部锻炼。所以...
著名的遗言和谦卑的要求:
- 记录您所做的一切。
- 分享您的经验。
- 开源您编写的任何工具。
通过完成所有这些操作,您将:
- 不仅增加了您在类似情况下获得支持的机会,
- 而且还可以为其他人提供帮助,并促进围绕技术堆栈的讨论。
谁知道,您可能是一个新兴的,晦涩难懂的语言X社区的开始。如果没有,则开始一个!
里面也许很漂亮,但是到目前为止没人知道,所以请帮忙拆除这堵丑陋的墙,让其他人看看!