使用多个不同的库时的编码样式


9

我正在研究一些使用多个库(包括一些C库)的C ++代码,它们都具有不同的编码样式。一旦达到可用阶段,它将开源。对于签出代码以修复一个错误或添加一个功能的短期贡献者,这将给他们带来最少的混乱?

  • 即使整个应用程序偶尔与所使用的库的典型编码风格都不匹配,在整个应用程序中也要具有一种一致的编码风格。
  • 当某个模块中大量使用某个库时,请遵循该模块中该库的典型编码样式(即该库自己的代码和文档中使用的编码样式)。

我的想法是,后者将使该特定库中的专家更容易做出一次性贡献,并使得在开发过程中合并教程/示例代码更加容易。但是,这也使整个应用程序中的编码样式不一致。每种方法的优缺点是什么?


4
通过将所有库包装在您自己的自定义抽象中,可以避免此问题吗?然后,您自己的代码和抽象可以遵循一种编码风格。
MetaFight 2013年

我正在做的很多事情都是抽象那些库。问题是在抽象内部使用哪种编码样式。
Karl Bielefeldt

6
啊。我在这里不是专家,但看来您最好使用库本身的约定。使用不匹配的约定听起来像一场维护噩梦。只要将库的样式包含在抽象类的类/模块中,我就认为可以。再说一次,我不是专业人士,但这似乎是一个很好的平衡点,可以使您更轻松地进行抽象维护,还可以使应用程序的其余部分具有自己的样式。
MetaFight 2013年

1
有时,这样的抽象可能会有些丑陋,无论使用哪种约定,都应尽力保持其干净,但最重要的是,请确保从抽象中提供的API具有足够的质量,无需回退进入抽象干预,消费者将能够轻松地与您的抽象保持一致,以确保代码不会像抽象中那样变得一团糟。简而言之,没有好的答案,但是只要您的抽象提供了不错的API,至少您就可以阻止问题扩散到它们上面。
吉米霍法2013年

1
“编码样式”到底是什么意思-简单的东西(例如using_underscores / camelCase / PascalCase和大括号位置),或更复杂的东西(例如类/方法/函数布局和命令式/函数样式)?
2013年

Answers:


10

我认为这取决于整个项目的最终规模。

在一个极端情况下,假设您有一个1 Mloc项目。对于这么大的项目,在所有涉及的领域中不可能只有一个人成为“专家”。因此,在这种情况下,我将坚持使用每个主要组件的现有代码样式。新的开发人员会选择一个领域,并从中学到这一点,他们不太可能看到许多其他具有不同代码风格的组件。

如果项目是小了很多,它可能有个人了解整个代码库,那么我会选择一个主要的代码风格,并坚持这一点。在这种情况下,我认为整个项目的一致性更有意义,因为新开发人员很可能会在项目的所有领域工作。

中型项目可能是最难做出此决定的项目。在这种情况下,您必须权衡每种方法的成本,并确定您认为长期最便宜的方法。挑战在于,中型项目通常已经增长到足以使完整的样式重构看起来过于昂贵的地步。您可能需要再看一下代码树结构,以查看是否可以安排将特定代码样式组合在一起的事情。

无论哪种方式,最终的决定权都应由您所在的团队来决定,这是将这个计划打包在一起的原因。


一些离群值可能使我的推理从上往下偏离:

  • 如果一个或多个模块具有令人讨厌的风格,那么即使在较大的项目中也无法保持这种风格。是的,风格是主观的,但是如果您和您的项目参与者确实非常不喜欢特定区域的流动方式,那么请破坏旧风格并为其提供更好的风格。

  • 如果所有样式都相当接近,那么声明“这是新方法”并将其用于所有新代码和重要的重构可能同样容易。这可能会使评论有些痛苦,但是以我的经验,大多数人都很有能力适应这种方法。它还提供了旧代码在哪里的告示标记。

  • 有时,样式会根据添加到语言中的新功能而改变。多年来,C ++拥有许多功能。可以根据需要将旧样式重构为利用这些功能的新样式。

  • 一些库可能具有特别的惯用方法或风格。如果是这样,即使该库可能与项目的其余部分发生冲突,我也会坚持使用该库的样式。这样做的目的是增加frobnosticators从事其他项目的人也会参与您的项目的几率。


一些评论提到命令式和面向对象的样式是一个考虑因素。

如果模块是中型或更大,则特定样式中“较重”的模块可能应该保持这种状态。我使用了三种主要样式(命令式,目标式和功能性),并将重的命令式样式重构为OO样式。使用中等或大量代码,重构可能会(异常)困难。我的经验很困惑,因为我没有任何工具支持来协助重构。

我可以想象,在命令式样式丰富的模块与那些特定于特定开发环境的惯用模块之间存在高度相关性,这可以追溯到我提出的离群值。因此,您将找到的用于该功能的任何模块都将看起来像这样,并且您希望该领域的专家也能够轻松地在您的项目中工作。但是,如果有选项,而您的团队不喜欢该模块的样式,那么我将调查这些选项。

同样,我使用的是重型OO样式的模块,在该模块中,OO原则被推到太远而使用不正确。例如,接口被用作多重继承的替代品。如您所料,这是一个粗略的实现。我能够在重构该模块方面取得合理的进展,但是最终我放弃了这种方法,因为我发现可以使用更好的软件包。


这是一个好方法。类似的项目大约有300个KLOC。
Karl Bielefeldt

3

听起来至少要考虑多个层次:

  1. 现有库及其任何修改。
  2. 这些库的新单元测试代码。
  3. 抽象层。
  4. 抽象层提供的API。
  5. 使用抽象层的示例和测试代码。

我将假设仅将所有代码重构为通用样式是没有意义的-如果这样做的话,您就不会问这个问题。

依次轮流:

  1. 对于现有的代码库,您可能会想要坚持这种风格。
  2. 现有代码的新单元测试代码位于灰色区域,尤其取决于与旧代码集成的程度。但最有可能的是,我会尝试以“首选样式”制作。
  3. 抽象层中的新代码。通过确保这确实是一个单独的代码层,即使代码正在与一个或多个旧样式进行大量交互,使用首选样式也不会有任何困难。大多数代码都需要与其他样式交互,而我从来没有发现这个问题。
  4. 显然,API本身需要最全面的考虑并满足最大的可用性需求。
  5. 同样,任何示例或测试代码都应该能够以首选样式编写。根据抽象的完整性(即是否完全隐藏了较低层),这可能很容易,也可能很困难。当然,确保将来的客户端代码可读是您的主要目标之一。

我个人发现的一些东西是具有大量旧代码库的:

  • 设置首选样式并强制更改代码不会神奇地导致所有旧代码迁移到新样式。

  • 大多数工程师倾向于(或多或少)使用给定库中的现有样式进行编码。否则,将导致大量执行。

  • 在遗留库中要求使用首选样式会导致该库中样式的很多不一致。因此,对于纯粹围绕表示的标准,与代码健壮性相反,在要求它们方面也很难看到很多好处。

作为最后一个问题(略微偏离主题,但我认为是相关的),事实是有些工程师努力遵循除自己最了解的样式标准以外的任何样式标准。我强烈建议让团队参与样式决策,并确保可以接受。这样做之后,您将可以更好地实际在混合代码中应用标准。


0

如果您正在开发带有大量第三方模块的大型项目,我将在这里同意@MetaFight。

让我们用一个真实的单词问题来描述您的问题:“ 假设您的房子生活安静。您喜欢安静的地方,从不大声说话,也从不喜欢任何家庭成员这样做。但是您与许多人互动每天外面有不同的人为您的房子带来一些东西。不一定他们也会用低声说话,在这种情况下,您在与这些人打交道时会相应地塑造自己。因此,这些人的界面或包装非常灵活,您要做的工作。 “愚蠢的例子...大声笑

但是我的意思是要按照此类库的编码标准为它们创建包装器,这样您就可以通过这些包装器使用这些库,从而在内部保持原始编码样式。

为MetaFight +1。


完全正确的解决方案imo。我使用包装器来捆绑其他人为我的项目编写的代码。首先定义一个接口,然后在实现该接口时,可以对其进行包装并进行黑盒测试。
Kieveli 2013年

1
为什么这被低估?我显然认为这是最好的解决方案:)
MetaFight 2013年

0

显然,在您的整个项目中使用单一编码样式会造成最少的混乱。首先使用编码风格的重点是使代码更易于阅读和修改。

至于库内部使用的代码样式,我认为这无关紧要。如果该库过于必要,则可以编写OO包装器,但这并不要求您使用与库示例或内部示例相同的代码样式。

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.