我已经工作了大约一年了。我主要在GUI界面中工作,该界面使用C后端的方法,但是除了返回值外,我通常不必处理它们。考虑到我们的限制,我们的GUI的结构相当合理。

我的任务是向程序的命令行部分添加功能。这些功能大多数都长达300行,难以使用。我正在尝试收集其中的一些信息以获取特定的警报信息,但在保持井井有条的过程中遇到了麻烦。我知道我要通过单个长函数来使测试变得更加复杂。

我应该按照现有函数的样式将所有内容都保留在一个巨大的函数中,还是应该封装我不能确定警报是否适合自己的功能?

我不确定它是否适合违反当前的编码约定,或者我是否应该硬着头皮让代码更容易混淆自己。




总而言之,我在比较

 showAlarms(){
    // tons of code
}
 


反击

 showAlarms(){
   alarm1();
   alarm2();
   return;
}

alarm1(){
    ...
    printf(...);
    return;
}
 


编辑:谢谢大家的建议,我决定要设计分解的代码,然后问他们想要什么,如果他们想要全部融合在一起,我可以从分解的代码中切出来,然后将其变成1个大函数。即使他们希望所有代码都在一个定义中,这也应该允许我编写它并更轻松地对其进行测试。

UPDATE:他们最终对分解后的代码感到满意,并且不止一个人感谢我提出这个先例。

评论

您所工作的公司是否认为您的职能应该长达300行是非常令人怀疑的,因为“这就是我们一直这样做的方式”。那不是“编码样式约定”;这只是坏风格。

您应该与团队中的其他成员讨论这种事情,以弄清您看到的惯例是他们认为对每个人都重要的惯例,以及某人仅做过一次而您没有做过的事情需要模仿。毫无疑问,两者都有一定数量。

@beginnerBinx取决于您的表达方式。不要这样说:“ X做的事情确实很愚蠢,我是否也必须做那个愚蠢的事情。”但是,就像“我注意到X正在做这件事,是否有一个特定的原因说明它这样做的原因;如果我在编写Y时没有做同样的事情会不会有问题呢?”然后,这是他们决定是否破坏旧代码或解释为什么必须这样做的决定(无论是勉强还是热情)。

好的或坏的风格经常被争论并且很少被商定。大学的教学是功能应该简短一些,但是如果这模糊了含义,那就不要这样做。该测试应该清晰明了,而不是无意识地遵循一系列规则。

互联网上的随机人不介意阅读您的队友,因此,您在此处获得的所有答案都只是人们的个人喜好。您应该与您的团队交谈。长功能是故意设计的原则吗?他们是希望您继续使用长函数样式还是要您写出您认为最干净的东西?

#1 楼

这确实是在您和您的队友之间。没有人能告诉您正确的答案。但是,如果我不敢在这两行之间读一读,那么您称这种样式为“不良”的事实可以提供一些信息,表明最好慢慢来。实际上,很少有编码样式是“不好的”。我自己有些东西我不会用,但是它们总是带有韵律或理由。对我而言,这表明故事的意义远不止您所看到的。问周围将是一个非常明智的选择。

我第一次尝试实时关键任务编码时就遇到了这个问题。我看到了这样的代码:



 lockMutex(&mutex);
int rval;
if (...)
{
    ...
    rval = foo();
}
else
{
    ...
    rval = bar();
}
unlockMutex(&mutex);
return rval;
 


我是一位聪明又有光泽的OO C ++开发人员,我立即通过手动锁定和解锁互斥锁(而不是使用RAII)了解它们存在的错误风险。我坚持认为这样做会更好:当编译器可以为您提供帮助时,为什么要求开发人员记住在所有控制流路径上解锁其互斥锁!

我后来发现这是程序上的原因。我们必须确认,是的,软件确实可以正常工作,并且允许使用的工具数量有限。在不同的环境中,我的方法可能会更好,但是在我所使用的环境中,我的方法很容易将验证算法所需的工作量增加了十倍,因为我只是将C ++ RAII概念引入了一段代码中

所以对我来说看起来很糟糕,很危险的编码风格实际上是经过深思熟虑的,而我的“好”解决方案是实际上是危险的东西,会在以后引起问题。

所以问一下。肯定会有一位高级开发人员可以与您合作,以了解他们为什么这样做。或者,有一位高级开发人员可以帮助您了解代码这一部分中重构的成本和收益。无论哪种方式,问一问!

评论


可以说互斥锁示例中最危险的部分是显然缺少代码注释,无法解释为什么不能使用RAII。当然,如果此显式锁定/解锁遍及整个代码库,则为每个实例添加注释可能很麻烦。在这种情况下,也许应该写一份入门文档,要求新开发人员熟悉。

–开尔文
16年12月13日在21:15

当然,与高年级交谈总是很好,并且重构必须谨慎(并经过测试)。当然,并发/互斥体本身就是一种特殊的野兽。但是,当看到功能大于300行的功能时,我不会花太多时间寻找这些功能太大的“隐藏技术原因”。函数变得太冗长的原因始终是相同的,并且不是技术性的。

–布朗博士
16/12/14在6:41



@DocBrown仅仅因为它们不是技术性的并不意味着它们不是原因。对于开发人员来说,重要的是要记住它们是大型计算机的一部分。 (我无法数出必须重新学习该课程的次数)

–Cort Ammon
16年12月14日在14:50

无论哪种方式,应该与高级开发人员进行交流。我之所以选择该示例,是因为它很容易找到无数参数来说明为什么愚蠢的代码是愚蠢的。找出为什么看起来愚蠢的代码实际上并不愚蠢的论据就很难了。

–Cort Ammon
16年12月14日在15:08

@DocBrown从您的评论和答案中,我想我可以说出我们的观点的不同之处在于,您是基于您所提供的证据,假设该代码已经是“错误的”,而我希望采取探究代码是否“错误”的路径。

–Cort Ammon
16 Dec 14'在15:12

#2 楼

老实说,您认为拥有300行难于使用的功能仅仅是样式问题吗?因此,遵循一致的错误示例可以使整个程序保持更好的状态,因为它具有一致性吗?我猜你不相信,否则你不会在这里问这个问题。

我的猜测是这些功能太长了,因为在我们的业务中,有许多平庸的程序员只是将功能堆在功能之上,而不关心可读性,代码质量,正确的命名,单元测试,重构,而且他们从未学会创建正确的抽象。您必须自己决定是否要追随那群人,还是想成为一个更好的程序员。

附录,由于注释:“ 300行”和“难于使用”是恕我直言,错误代码的强烈迹象。以我的经验,很可能没有某种“隐藏的技术原因”,使得这种代码无法以更具可读性的方式实现,这与Cort Ammon的答案示例相当。但是,我同意Cort的观点,您应该与团队中的负责人进行讨论-不是找出无法更改代码或这种“样式”的晦涩原因,而是要找到如何安全地重构代码而又不会破坏事情的原因。 。

评论


在紧迫的期限内,即使是有能力的程序员也会犯下这些罪行。

– Gardenhead
16 Dec 13'3:54

@gardenhead,我可以理解不重构300行函数可以节省时间,但是编写300行函数无法节省时间。

–Dangph
16年12月13日在5:15

@gardenhead:当我因为需要紧急帮助而去找外科医生时,我仍然希望他花时间在他开始对我表演之前先洗手。这是很多人在我们的业务中必须学习的才能获得真正的能力:始终将代码保持在比以前更好的状态,并且这还将提高保留截止日期的能力。 300行功能通常由无关紧要的人每天增加,他们将始终以“截止日期”为借口。

–布朗博士
16/12/13在7:39



@Dangph仅在您向函数添加5行而不是对其进行重构时可以节省时间。当初始函数很长(超过30行)并且下一个程序员认为“这不是我的代码,我不会重构不破坏它,只需在这里和那里添加几行”时,这些通常会增加。

–Džuris
16 Dec 13'9:34

据我了解,@ Juris的问题是关于创建新功能,而不是重构现有功能。如果您正在编写新功能,则不能通过将其变成单个怪物功能来节省时间。

–Dangph
16年12月13日在9:41

#3 楼

否。

在《实用程序员》一书中,作者谈到了“破窗理论”。

该理论状态:


考虑一个有几个破窗户的建筑。如果不修理窗户,则有可能破坏者破坏更多窗户。最终,他们甚至可能闯入建筑物,如果空置,可能会成为棚户区居民或内部起火。一些垃圾堆积。不久,更多的垃圾堆积。最终,人们甚至开始从那里的外卖餐厅丢下垃圾袋,甚至闯进汽车。


在书中,作者在这一理论和法规之间写了一条相似之处。找到这样的代码后,您将停止并向自己问同样的问题。

答案是:否。

一旦您离开这个破损的窗口-就我们而言,糟糕的代码-这会造成所有人留下破碎的窗户的后果。

有一天代码会崩溃。

给所有人一份Clean Code和Clean Coder的副本。

当您在学习主题时,TDD的副本也是不错的选择。

评论


如果代码库是一个只有破窗的温室,该怎么办?

–艾伦·舒特科(Alan Shutko)
16年12月13日在2:56

@AlanShutko然后确保您的简历是最新的?立即找到其他雇主。

–大卫·蒙哥马利(David Montgomery)
16 Dec 13'3:31

代码很少“崩溃”。添加新功能变得越来越困难,花费越来越多的时间,并且清理代码的估计将增加-这意味着获取任何时间预算以进行必要清理的难度越来越大。

–布朗博士
16年12月13日在8:28

哇,“破窗”理论似乎是个任意类推。

– Samthere
16 Dec 13'在12:15

TDD与之无关。无论您要进行的业务/域/测试/虚无驱动程序设计,都不会改变任何事情,请遵循干净代码的基础。抱歉,看到“ TDD”到处都引人注目甚至在主题中都没有

–沃尔夫特
16年12月13日在12:24



#4 楼

是的,去吧。结构!=样式

您在说的是结构,而不是样式。样式指南通常不会规定结构,因为通常选择结构是出于对特定问题的适当性,而不是对组织的适当性。

要小心

确保您不会对您未曾发生的其他领域造成负面影响。例如,


请确保您没有使差异变得复杂或代码合并,因为您消除了与现有代码的任何相似之处。
确保异常流正确冒泡,并且堆栈痕迹不会被一大堆难以辨认的废话污染。
确保您不会意外暴露会直接导致问题的公共入口点(不要将它们放在地图中和/或不导出它们。)
不要弄乱全局名称空间,例如如果您所有较小的函数都需要以前在函数局部范围内声明过的某种全局上下文。
请确保查看任何日志,并问自己是否在支持团队中,是否由代码生成日志当看到与您未触及的任何代码的日志交织在一起时,会造成混乱。
请确保您遵守现有样式,例如即使他们使用的是老式的匈牙利符号,并且使您流血,也要与通用代码库保持一致。唯一比阅读匈牙利符号更痛苦的是,阅读代码使用了十二种不同类型的符号,具体取决于谁写了什么。

要谦虚

请记住,您是匈牙利人的一部分团队,尽管良好的代码很重要,但是团队成员能够维护您在度假时编写的内容也很重要。尝试坚持对习惯旧样式的人有意义的流程。仅仅因为您是会议室中最聪明的人,并不意味着您应该在每个人的头上讲话!

评论


“尝试坚持对习惯了旧样式的人有意义的流程。” -那么,您的编程建议是否与以前无能的小丑一样?添加300行功能将使其变得不那么容易。

–BЈовић
16年12月13日在8:47

我并不是说要坚持类似的流程。我说要坚持他们会理解的流程。

–吴宗宪
16年12月13日在8:50

好建议。当我在此答案中将单个命令重构为5个函数时,我通过预先计算最初仅是有条件地计算的逻辑表达式内的值来巧妙地更改了语义。审稿人虽然抓住了;-)。认真的建议是彻底检查和测试。每次更改都会带来错误,这可能是没人犯错误的主要原因。

–彼得-恢复莫妮卡
16 Dec 13'在15:53

#5 楼

我不认为这是一种代码约定。我将其视为不了解如何编写易于理解的可维护代码的人。我会按照您的建议将您的代码分解为不同的功能,并对您的团队进行此操作的好处进行教育,同时尝试理解为什么他们认为300行功能可以接受。我很想听听他们的推理。

评论


“没有理由,这只是我们的政策。”

–user251748
16年12月13日在15:05

#6 楼

答案在代码审查中。

真正的问题是,如果您上交合理的代码,您将是唯一愿意使用它的人吗?像这里的大多数人一样,相信300个行功能是可憎的。但是,将Windex带到垃圾填埋场并不会带来多大好处。问题不在于代码,而在于编码员。

仅靠正确还不够。您需要以这种风格推销人员。至少在阅读时。如果您不这样做,您最终会像个可怜的家伙一样:被开除,因为您的技能远远超出了您的同事。

从小做起。询问周围,找出是否还有其他人喜欢较小的功能。更好地窥探一下代码库,看看是否可以找出谁编写的代码最少(您可能会发现最丑的代码是最早的代码,而当前的编码人员正在编写更好的代码)。与他们交谈,看看您是否有盟友。询问他们是否认识其他有同样想法的人。询问他们是否认识到讨厌小功能的人。

聚在一起,讨论如何进行更改。向他们展示您想要编写的代码类型。确保他们可以阅读。认真对待任何异议。进行更改。批准您的代码。您现在可以在自己身后举行会议。其中的更多内容,您可以生成一个一页纸的文档,该文档明确接受您所引入的新样式。

会议是令人惊讶的强大功能。他们可以产生影响力。影响力是您用来对抗反对这一运动的人的东西。这就是这一点。运动。您正在争取改善现状的权利。人们害怕改变。您将需要甜言蜜语,哄哄和刺耳。但是幸运的话,您将变成被接受的权利。

评论


如果花费大量的社交时间和多次会议才能说服开发人员300行方法太长,那么我认为谈话不会有所帮助。上面方法的问题是,如果您请求编写好的代码的权限,那您就处于防御状态。但是,如果您只是编写出色的代码并花时间重构现有代码,那么任何反对的人都在防御性地解释为什么300行方法是好的,并花时间将其放回去是合理的。

–布兰登
16 Dec 13'3:27

我可以告诉你,如果邀请我参加一系列会议,讨论每个功能限制的代码行,我将找到逃避此类会议的方法。没有正确的数字,您将永远不会让人同意。有时,需要向人们展示更好的方法。

–布兰登
16 Dec 13'3:31

有时,拆分一个巨大的功能(更好地命名并添加注释和文档,正如我认为的那样)是保存更改之前必不可少的第一步。

–JDługosz
16 Dec 13'在8:41

@Brandon您可能不是想这样听起来,但我听到的是您是对的,其他所有人都可以解决。只要您的代码有效,团队其他成员是否不理解它就无关紧要。当然,不值得您花时间去教他们任何东西。您很高兴看到他们以自己的方式编写代码时继续创建300行功能。

–candied_orange
16年12月13日在13:46

@CandiedOrange我当然不是要反对球队。我的意思是,通过在行动中看到某些主题可以最好地学习它们,但是试图让团队就风格做出民主决策将不会有成果。我已经看到一致性被用作编写不可读代码的借口。结果?更多不可读的代码。我可以召开一系列会议来讨论它,或者我可以解决它,然后向人们展示结果。

–布兰登
16 Dec 14'2:29

#7 楼

在声明这些做法不好之前,我首先要迈出一步,以了解大方法和其他可能会不好的做法的原因。
然后,您需要确保测试覆盖率非常高或非常高(在不进行重大重构的情况下就可以做到)。如果不是这样,即使您没有编写代码,我也会努力提高覆盖率。这有助于建立融洽的关系,而您的新团队将更加重视您。

一旦您拥有了这些基础,他们中就不会有任何人会挑战您。作为奖励,做一些微基准测试,这确实会增加您的案子。

通常,您所说的方式对改变代码文化大有帮助。以身作则。甚至更好的是,等待一段您可以编写的代码-对它进行重构和单元测试,并对中提琴进行测试-

评论


我没有重构当前代码,我只是在编写一个新函数,不确定是否应该按照“惯例”并将其编码为300多行代码,或者像我通常那样将其分解为逻辑块,但是在代码库的这一部分中没有完成。

–贾斯汀
16 Dec 13'在17:44

他们有规则来确保您用300多个行编写新方法吗?如果没有,我会用正确的方式写出来。但是我绝对会尽力确保我对它们(包括分支)进行测试。我经历过类似的经历,通常您确实会赢得他们。技巧是随着时间的流逝并建立融洽的关系。

–斯基皮
16 Dec 15'在10:38

#8 楼

这种类型的问题基本上是“请仔细阅读我的队友”。互联网上的随机人无法做到这一点,因此您获得的所有答案都只是人们对编码风格的个人看法。共识是较短的方法是更可取的,但您自己似乎已经这样认为,因此无需重申。

因此,当前的代码库似乎使用了与您喜欢的编码样式不同的编码样式。你该怎么办?首先,您需要弄清楚:


这是您当前团队支持的故意设计决策吗?
他们是否希望您遵循这种风格?

/>只有一种方法可以找出答案。问。

长功能可能有多种原因。这可能是因为该团队认为长功能优于多个短功能。也可能是因为它是遗留代码,并且团队更喜欢新代码遵循更简洁的设计。因此,如果您不与团队交谈并了解他们的推理,那么任何一种选择都可能给您带来开发人员麻烦。

评论


我完全同意并补充说:“您可能会因为不关注他人的工作而被炒鱿鱼或遇到其他麻烦?”那么答案是肯定的!跟踪公司的每件坏事,都需要您去处理。

–Rob
16 Dec 13'在10:54

#9 楼

有时您必须顺其自然。

就像您说过的那样,您被赋予在现有工作代码库中实现功能的任务。很想清理它。但是在商业世界中,您并非总是有机会重构代码。

我想说的就是按照您的要求去做并继续前进。

如果您认为值得重构或重写,而不需要与团队讨论进行讨论。

评论


如果您在每一个小的重构请求许可,您将永远拥有无法维护的代码,这对企业来说是危险的。管理人员只考虑变更的成本,而很少考虑不变更的成本。

–布兰登
16 Dec 13'3:34

已要求OP编写不修改数百行代码的函数

–美达
16 Dec 13'4:46

完全是@meda!我的处境大致相同。我正在为公司内部网开发新的模块,并且发现了所谓的“多年无法修复的疏忽”,服务器软件和库自2006年以来就没有更新过。 ,但是由于这些限制,我花了更长的时间编写代码。 (想象一下MySQl 5.2,MySQL 5.0)。我无法更新任何内容,因为由于不推荐使用的代码,现有的代码可能无法在较新的版本上运行。

–roetnig
16年12月13日在14:28

“如果它没有损坏,请不要修复它。”我有一辆20岁的旧车,漏了一点油。值得花钱吗?不可靠吗?是。

–user251748
16 Dec 13 '15:01

#10 楼

有不同级别的“样式”。

在一个级别上,通常是编码约定的一部分,这意味着在哪里放置空格,空白行,方括号以及如何命名事物(混合大小写,下划线等)。 >
在另一个层次上是编程模型,有时诸如避免静态操作或在抽象类上使用接口,如何公开依赖项甚至可能避免某些深奥的语言功能之类的东西。

那么该项目正在使用的库和框架。

有时功能的大小会有最大限制。但是很少有最低限额!因此,您应该找出哪些功能最重要,然后再予以尊重。

您需要确定团队是否不利于重构现有代码,这应该与可能的情况下独立于添加新代码而独立进行。

但是,即使他们不这样做也是如此。不想重构现有代码,您可以为添加的新代码引入一些抽象层,这意味着随着时间的推移,您可以开发更好的代码库,并可能在维护旧代码时迁移旧代码。