我们应该鼓励编码风格来支持开发人员的自治,还是不鼓励编码风格来实现一致性?


15

开发人员if/else使用单行代码语句编写块,例如:

if (condition)
   // Do this one-line code
else
   // Do this one-line code

另一个使用大括号:

if (condition) 
{
   // Do this one-line code
}
else
{
   // Do this one-line code
}

开发人员首先实例化一个对象,然后使用它:

HelperClass helper = new HelperClass();
helper.DoSomething();

另一位开发人员实例化并在一行中使用该对象:

new HelperClass().DoSomething();

开发人员更容易使用数组和for循环:

string[] ordinals = new string[] {'First', 'Second', 'Third'};
for (i = 0; i < ordinals.Length; i++)
{
    // Do something
}

另一个写道:

List<string> ordinals = new List<string>() {'First', 'Second', 'Third'};
foreach (string ordinal in ordinals)
{
    // Do something
}

我确定您知道我在说什么。我称它为编码风格(因为我不知道它叫什么)。但是,无论我们称它为好是坏?鼓励这样做会提高开发人员的生产力吗?我们是否应该要求开发人员尝试按照告诉他们的方式编写代码,以使整个系统变得风格一致?


1
我刚才实际上是来这里问一个非常类似的问题的-当自动代码格式化工具可用且方便时,不运行那些工具(并保留不一致的个人样式)或强制使用一种样式是否更重要?
蓬松的

一致的样式使阅读代码更容易,因此请使用一致的样式。在您的示例中,最容易阅读的是2、1、2,尽管最后一种情况有所不同。在对性能有严格要求的应用程序中,遍历列表时for循环更快。遍历数组的性能是相同的。并且在所有情况下,请使用var而不是完全限定的类型名称。
斯蒂芬,

Answers:


19

编码标准文档很有用。当它足够短时,任何人都可以记住整件事而没有太多麻烦,并且当它不会给任何人带来太多痛苦时,这是有用的。

您选择缩进组织中的代码,大写名称,实现循环或注释代码的方式都无关紧要;有用的部分是让所有人都编写与他人几乎相同的代码。

  • 它避免了花一分钟时间重新调整对花括号应该在哪里的期望,而每次您查看别人的代码时,都不必花时间。
  • 它避免了在同一文件中全部包含几种不同样式的代码。
  • 也许最重要的是,制定书面标准可以避免在代码审查期间就编码实践产生争论。

同样,标准是什么,与拥有某种简单,直接的标准无关紧要。因此,请将所有开发人员放在一个房间里,让他们争论标准应该是什么。该会议可以无限期进行,因此规则是:

  • 会议结束之前未决定的任何事项将由经理决定。
  • 会议将在两个小时后结束,或者当有人开始喊叫或哭泣时(以先到者为准),会议结束。
  • 整个标准将适合(以合理的字体大小!)在一张或两张纸上,仅在绝对必要的情况下才双面。

考虑采用某人 | 别人的 | 这些标准既可以作为您自己的编码标准会议的起点,也可以作为完全避免开会的一种方式。

一旦达成协议,开发人员应该能够(并且应该期望)自行监管。偶尔偏离标准不是什么大问题(甚至可能是有道理的),但是仅凭cur弃拒绝放弃某些偏爱的个人风格来支持标准,应立即导致因漏水的水管或任何其他原因而立即搬迁至办公室。

Demian Brecht指出了皮棉工具。这些是对编码标准文档的完美补充。坚持编码风格标准只是一件好事;这是重要的坚持编码,涉及到危险的行为标准。除了作者之外,没有人会检查每一行代码是否都符合样式标准,但是您当然应该考虑在团队的工作流程中构建一个lint工具,以自动捕获可能的错误。另外,该工具本身可以将公认的惯例整理成代码,这样您就不必在编码标准中单独列出所有惯例。只需指定工具的配置即可。

注意: “编码标准”思想并非编程所独有。“编码标准”用于许多领域,有时在组织内,更经常用于整个行业或专业。一些例子:

在每种情况下(和许多其他情况下),有能力的从业人员都可以轻松理解不符合预期标准的“代码”。为什么这么多行业坚持编写甚至不需要编译器解析的文档的详细要求?因为风格很重要。以标准样式显示信息可以使读者完全专注于内容,可以加快阅读速度并有助于理解,并减少错误。


1
如果您在帖子中添加了棉绒工具的用法,我将删除我的工具,并为您的+1 :)
Demian Brecht

@DemianBrecht,很好的建议,谢谢。添加了棉绒工具来改善我的答案,但我认为您也应该离开。
Caleb

那很好。无论如何+1 :)
Demian Brecht

也给你!
Caleb

+1表示“ ...立即搬迁...”,根据我的经验,这种行为与社交行为和/或自恋倾向一致,与软件开发团队不兼容。
mattnz 2011年

16

风格无所谓。

在那里,我说了。

经过30年的发展,拥有数百个客户站点,并且在这些年中(估计)了500名(或更多)团队成员的代码,我发现风格并不重要。

首先让它工作。

得到它以使用最佳的资源量(即正确的数据结构,正确的算法)。

在解决所有其他问题之后,对“样式”大惊小怪。只能通过工具来实现“风格”的混乱,绝不能手动进行。


2
阿们!编码标准需要根据实际利益来证明,而一致性不是真正的好处,而是奢侈的事情。
JohnFx 2011年

12
但是风格很少与风格有关。这是关于避免常见错误。
马丁·约克

6
但这确实有助于避免使用'='而不是'=='(不要在条件内使用赋值)。它有助于避免if (t) { x;y;}而不是if (t) x;y;(始终在if之后使用'{}')。最好使用const正确代码(在编写代码后很难在代码中添加const正确性。使用std :: cout / std :: cin而不是fprintf / scanf,前者更有可能导致错误。请使用向量而不是数组(以帮助防止溢出)。
马丁纽约

5
使它正常工作显然至关重要。但是仅仅因为它起作用并不意味着它就已经完成了。它还需要进行测试。然后审查。那可能要花几天时间。然后,多年之后,必须阅读,理解和维护它。有用的代码(为什么写任何其他类型?)会被读取很多次,比它的编写,因此使其易于阅读和理解提高生产力遥远的未来。在整个组织中使用一致的样式是在这方面提供帮助的一种方法。
Caleb

1
强制使用自动格式设置工具怎么办?Eclipse和XCode使得保持代码格式非常容易-但是,如果有人自动格式化“他的”(即公司的)代码以使其与其余代码库保持一致,那么我与一位合作的工程师会感到非常沮丧。格式化只是样式的一小部分,但它也是重要的样式,尤其是对于诸如if / else嵌套和整体代码流(更不用说可读性)之类的问题。
蓬松的

4

有编码样式,有编码气味。我不是一次发现:

    if(debugCondition)
//         printf("DEBUG: state:%s at debugCondition\n",dbg_state());

    for(i=0; i<MAX;i++)
    {
       //some essential business logic
    }

我以前的雇主严格禁止使用if()不带大括号的多行。它被认为是“再做一次,您就被解雇了”类型的错误。允许的结构是

     if(condition) break; 
     if(condition) continue; 
     if(condition) return; 
     if(condition) for()...; 

这是因为出现了一个错误,就像我在上面显示的那样,该错误花了几个小时才能找到使门户网站的主页停止的地方。

有些事情你应该总是做。像switch()

     case 1:
         something();
     break;
     case 2:
         something();
     return;
     case 3:
         something();
     continue;
     case 4:
     case 5:
         something();
     break;
     case 6:
         something();
     //fallthrough;
     case 7:
     ...

同时,键入:

     case 1:
         something();
     case 2:
         something();
     break;

不关闭casewith //fallthrough则被视为错误。

通常,有一个编码标准,它是可以被忽略,创造性地解释或针对给定需求进行修改的指南。还有“气味”部分,必须严格遵守。


3

通过良好的前期设计创建一致性。您在问题中描述的内容无非就是微观管理。我做了很多Web开发。因此,我赞成将RESTful和CRUD开发作为服务公开。这确保了可以以多种方式使用的简单,定义明确的实体。

这种设计还使我可以将实现细节委托给其他开发人员。这样,他们填补了空白,而不是创建整个系统的设计。

缺乏整体设计会导致系统不一致。对基本迭代和循环结构的批判对改善系统设计没有多大作用。可以通过手动方法StyleCop更好地解决这类问题

您可以绘制一个相对简单的总体系统设计图吗?一种向新团队开发者描述涉及的元素/实体的设计。如果不能,或者参与程度很高,则说明缺少设计。


3

恕我直言,这取决于...

您的前两个示例对我来说不仅仅是个人品味的问题。

if (condition)
   // Do this one-line code
else
   // Do this one-line code

(不带括号)=更多易出错,如果稍后添加更多代码:

if (condition)
   // Do this one-line code
else
   // Do this one-line code
   // ...and this line as well... oops! this will actually execute either way

而且这样调试起来不太方便:

new HelperClass().DoSomething(GetSomeData()); // etc.

您不能简单地在需要的地方设置断点。如果这是一次性的-足够公平,但是我们将其作为风格进行讨论,并且一旦您到处都有这样的东西,调试就会变得比原来更加令人不快。

至于您的第三个示例(对于vs foreach),我认为这只是一个品味问题。


2

都不行 我会避免使用苛刻的编码规则,以避免繁琐,挑剔,微观管理和最浪费时间。您的自主意识是您自己的问题。如果我想让自己感觉更好,我将为您买一轮您最喜欢的饮料。除此之外,做点什么。


2

使用约定,变量名,类名等是一种好习惯。但是像您提供的示例这样的编码样式相当琐碎,并且对代码的可读性或效率均没有影响。另一方面,强制执行给定样式与开发人员遵循该样式所产生的开销将导致问题。


2

使用行业标准的整理工具(对于C#,显然是FxCop)。尽管不是最终的,但总的来说,一致性在有很多人在工作的大型项目中重要。

如果您只是在自己的项目或小型团队中工作,许多人会认为这太过分了。我相信否则(即使在我的个人开发人员项目中,我也将PEP8用于Python)。

但是,您给出的大多数示例很可能都不会被棉绒工具抓住,因为它们根本无关紧要。


1

强制采用统一的编码风格总是很困难。理想情况下,这种平凡的任务应该留给工具来处理。我为Go语言社区为此鼓掌。


1

两者兼而有之。仅仅因为它是一个标准并不能使其可读性和可维护性。如果还没有灌输的标准,或者它存在错误和难以理解的方面,则应进行修订。


1

归根结底,是由程序员来驱动程序。存在样式问题,但这些问题仅次于发布程序。

为程序员提供一些样式指导很有帮助。这可以/应该在程序员投入工作之前完成,特别是如果他们是环境或编程本身的初学者。在给出指导的情况下,一些程序员将非常注重样式,而其他程序员则不太。在项目开始时给出的指导将帮助第一批程序员,从而使总体任务更容易。对于第二组来说,这可能没什么用,这将(希望)弥补创造力,弥补他们缺乏的整合能力。


1

我认为这取决于项目的规模以及有多少人在从事该项目。熟练的程序员可以查看这两种不同的格式样式,并了解这两种样式中发生了什么,但是需要保持一定的吸引力,以使眼睛可以轻松抓住它。如果您要在不使用大括号的情况下执行单行if语句,则该项目不应该使用它们。领导该项目的人应该有这种选择。我喜欢东西看起来清晰,而且也很紧凑,因为我能买得到。如果您要统计一行,那么最好看起来像这样

if() {}
else() {}

甚至:

if() {} else () {}

但是,单行if不应该使用多行距if的间距。这就是我做事的方式。我不介意该对象的调用方式,这取决于其调用的次数。如果它被调用了几次,那么我宁愿启动该对象,并取决于它是否具有构造函数,什么也没有。因为如果您有一个构造函数,然后调用:

Object.method();
Object.method2();

然后,您可以通过完全实例化对象来避免两次调用对象构造方法。

关于foreach和for循环在foreach循环中查看数组时,它还会涉及到lanauuge,它们为您提供了更好的控制,因此您可以在temp数组中拥有键和值。而且我知道有些lanagues进行了某种优化,因为他们可以查看循环并确切知道将调用多少次。


1

尽管您的第一个示例并不出色(有关在修改后更易于出错的说法具有一定的重要性),但总的来说,我实际上已经开始偏向于开发人员使用略有不同的编码样式。

在与其他团队成员的代码一起工作之后(有时短短几个月),它实际上开始以内联方式工作git blame。在我公司工作了10年以上之后,我可能会以80%以上的准确率告诉您谁在我们的50万行代码中的任意位置编写了任何给定的类,只需查看一下即可。

当您开始查看使用不同风格的代码时,虽然会有一些“斜坡时间”,但是您当时真正在说的是“哦,这看起来像约翰·多伊的代码(因为他使用样式X,但不使用样式Y,依此类推)”。这带来了一大堆上下文。大致来说,您知道John的代码会带来什么-他很了解代码库的其他部分,而他不了解哪些部分,无论他是SQL专家还是GUI新手,等等。

通过格式化程序运行每个人的代码实际上会剥离此信息,将其隐藏在后面git blame,您可能不必费心运行。


0

这实际上很大程度上取决于组织的类型。

如果您是一小群超级英雄,那么任何类型的样式都可以。如果每个人都有自己的风格,并且既好又内在一致,那么这就是您所需要的全部过程。超级英雄会说:“简(Jane)有方括号,所以这就是她的意思”或“杰克(Jack)将camelCase用作变量”。

通用标准最适合使每个人成为B +参与者。您的超级英雄将因此而失望。但是,如果您希望一个A玩家,六个B玩家和六个C玩家平均达到B +,则您需要一致的标准。在这种情况下,您希望每个人都做相同的事情,以便一个A玩家可以尽快浏览每个人的代码。

你们中的许多人都这样说:“但是等等,为什么不放弃B和C玩家呢?”

现实是超级英雄并不多。尽管在Google上查找和培养他们可能需要付费,但为后者添加新的帐单系统可能对后者更合算。(如果您真的有超级英雄,那么其中的4或5个将是十几个初级辈的两倍)

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.