我从高级编码员那里听到了一些故事,而我自己也看到了一些。似乎有许多以上的程序员在编写无意义的代码。我会看到类似的东西:
- 没有价值的方法或函数调用。
- 在单独的类文件,对象或方法中进行的冗余检查。
if始终为true的语句。- 分离的线程不执行任何操作。
仅举几个。有人告诉我,这是因为程序员想要故意使代码混乱,以至于给组织增加自己的价值,或者确保在进行承包或外包工作时要重复业务。
我的问题是。其他人看到过这样的代码吗?您的结论是为什么存在该代码?
如果有人写过这样的代码,可以分享原因吗?
我从高级编码员那里听到了一些故事,而我自己也看到了一些。似乎有许多以上的程序员在编写无意义的代码。我会看到类似的东西:
- 没有价值的方法或函数调用。
- 在单独的类文件,对象或方法中进行的冗余检查。
if始终为true的语句。- 分离的线程不执行任何操作。
仅举几个。有人告诉我,这是因为程序员想要故意使代码混乱,以至于给组织增加自己的价值,或者确保在进行承包或外包工作时要重复业务。
我的问题是。其他人看到过这样的代码吗?您的结论是为什么存在该代码?
如果有人写过这样的代码,可以分享原因吗?
Answers:
我听说开发人员试图使他们的编码成就听起来比实际情况复杂。我从未听说过有人承认这一点,但是我看到符合您标准的代码是出于匆忙或不良做法而不是蓄意破坏而故意创建的。恶意代码周围的代码可能已更改为特定功能不再有用的地步。
在得出只有该开发人员才能管理复杂性的结论之前,实际上必须有人亲自看一下此代码。大多数经理和其他业务人员之所以得出这个结论,是因为他们不懂任何代码,也不想填补这个职位。
我没有看到这样的代码,但是由于其他原因,我看到了看起来毫无意义或毫无意义的代码:
向后兼容。您发现了做事的更好方法,但是您必须保留旧的(至今为止不是很有用)的API /功能,因为那里的某些第三方模块可能正在使用此API /功能。即使该函数没有做任何有用的事情,缺少该函数也可能会破坏某些代码。
防御性编码。您知道此代码中的检查毫无意义,因为已经在其他地方进行了检查。但是,如果有人在其他地方更改此代码并删除或更改检查以使它们不再符合您的先决条件怎么办?
有机增长。在大型项目中,这些年来许多事情发生了变化,结果证明以前使用过的某些方法不再使用,但是没有人愿意删除它们,因为没有人跟踪是否使用了这种特定方法,因此只是重构了他们的代码段,碰巧发生了,他们都停下来使用此方法。或曾经具有意义但在其他地方重构了应用程序的条件,因此条件始终变为真实,但没有人愿意删除它。
过度设计。人们可能会编写某些东西“以防万一我们需要它”,而实际上并不需要。就像“让我们生成线程以防万一我们必须离线进行一些工作”,然后没有人要求离线进行任何操作,程序员忘记了它并转到其他项目(甚至可能是另一家公司),并且代码仍然存在永远,因为没人知道它在那里的原因或删除它的安全性。
因此,尽管我从未见过它是出于恶意或误导性的工作安全方法来完成的,但我已经看到无数次它是软件开发的自然结果。
我的问题是。其他人看到过这样的代码吗?您的结论是为什么存在该代码?
1)是的。
2)在我所看到的情况下,我将其归类为:
现在,也许我对此很慈善,但是我的一般做法是,对这些事情宽容/不打架比指责并坚持低劣的质量更好。显然,事情可能会变得很糟,必须执行某些操作,但是通常只需朝正确的方向轻推即可。
当然,如果质量/错误会严重影响“业务”,则您不能采取这种放任自流的方法。但是在这种情况下,您需要对所有内容进行强制性和勤奋的代码审查,并结合全面的测试程序。
以我的经验,人们倾向于(至少部分)对质量差的代码“保持警惕”,因为它违反了他们的个人标准。(个人)追求完美是一件非常好的事情,但是将您的个人标准投射给其他人则有点不合理。根据事物的声音(例如,根据示例的性质),这就是您正在做的事情。
海事组织,这没有生产力,也不利于与您的同事建立良好的工作关系。
所有这些通常都是项目如何老化的症状。
1.没有任何价值的方法或函数调用。很多时候,一些代码仍然保持原样(希望有一个大大的不推荐使用的警告,但是由于大多数语言都没有该警告,因此并不总是遵循该警告...),因为在某一时刻它可以为某些代码服务真正的目的,没人知道如果删除违规行将发生什么。
我似乎从Dailywtf记得这一点:
@deprecated // he might have been crazy enough to use reflection...
boolean getTrue() {
return false;
}
2.在单独的类文件,对象或方法中进行的冗余检查。沟通的层次也不完美(曾经读过《神话人月》?否则,您在计算机上正在做什么!通常,一个人会从事某项工作,然后离开项目,然后下一个家伙发现一些奇怪的错误,在这里和那里抛出额外的检查以试图消除它。删除错误后,检查不是因为,如果它没有损坏,就不要修复它。
3. if语句始终评估为true。哦,我已经做到了。我曾经有一个项目,它有一系列大约10-15个if / else块。要更改行为,我只需将a true||放在第一行。直到几个月(几年?)之后,我才回来说:“哦,哇,这条代码本来应该被销毁了,但从未被销毁。”
4.分离的线程不做任何注意。我可以想象一条思路是这样的:
bar线程看起来好像没有做任何事情,我们可以删除它吗?” “最好不要,它已经存在很多年了……”大多数答案可以归结为以下两个简单事实:
[1]代码反映了代码的历史,
[2]代码反映了代码的预期未来。
鉴于当前的规格,在当前的应用程序环境中,我编写的函数没有任何价值,但是将来可能需要。
我已经写过if陈述,目前它总是评估为true。但也许过去可能是错误的。
至于冗余检查,嘿,我不信任其他代码,甚至不信任自己的代码。如果一个模块依赖于N为1或2或3,则最好弄清楚这一点,如果不是,则进行有意义的崩溃。模块B爆炸是非法的,因为模块A拧紧了。模块B抱怨模块A搞砸了是完全合法的。请记住,下个月,该参数可能来自尚未编写的模块C。
- 没有价值的方法或函数调用。
不一定坏。基类中的方法通常调用空方法,这些方法被用作子类的覆盖点。示例:Cocoa Touch的UIView具有一种-didAddSubview:方法,在默认版本中该方法被记录为不执行任何操作。UIView的-addSubview:方法-didAddSubview:即使不执行任何操作也必须调用,因为子类可以实现它以执行某些操作。当然,不做任何事情的方法及其原因都应记录在案。
如果出于历史原因显然存在空的或无用的功能/方法,则应将其切除。如果不确定,请查看源代码存储库中代码的早期版本。
- 在单独的类文件,对象或方法中进行的冗余检查。
很难说,没有上下文就可以了。如果出于相同的原因明确地进行了检查,则可能意味着没有明确的职责分离,需要进行一些重构,尤其是当两个检查都导致采取相同的操作时。如果两次检查的结果都不相同,那么即使条件相同,两次检查也可能出于不同的原因而进行,这可能还可以。
- if语句始终评估为true。
之间有很大的区别:
if (1) {
// ...
}
和:
if (foo() == true) {
// ...
}
哪里foo()总是回来true。
人们调试时,第一种情况经常发生。if (0) {...在尝试隔离错误时,可以使用和临时删除一部分代码,然后将更0改为1来恢复该代码。在if一旦你完成,当然,应该被删除,但它很容易忘记这一步,或错过一个或两个,如果你已经在几个地方做了。(最好是在注释中标识这些条件,以便以后搜索。)唯一的危害是将来可能引起的混乱。如果编译器可以在编译时确定条件的值,则会将其完全删除。
第二种情况是可以接受的。如果foo()需要从代码中的多个位置测试所代表的条件,则将其分解为单独的函数或方法通常是正确的选择,即使foo()现在总是正确。如果可以想到foo()最终可能会返回false,那么在方法或函数中隔离该条件是识别代码依赖于该条件的所有位置的一种方法。但是,这样做确实会带来一些风险,那就是该foo() == false条件将未经测试,并可能在以后导致问题。解决方案是确保添加显式测试false案例的单元测试。
- 分离的线程不执行任何操作。
这听起来像是历史的人工产物,可以在代码审查期间或通过软件的定期分析来识别。我想它可能是有意创建的,但是我很难想象有人会故意这样做。
我反对将if true语句随意分类为“无意义代码”。
if (1) { ... }在C代码中使用一个块的合理情况是,要么希望与坚持将变量定义放在函数的开始的C标准兼容,要么只是希望将局部变量定义为尽可能地局部。
switch (i) {
case 23:
if (1) {
/* I can declare a local var here! */
}
break;
}
if,while或类似的结构。它不太可能很干净,但是根据语言规范,它肯定是允许的。
if (false) {...}块非常适合注释代码!</