跟踪实用程序类

时间:2011-04-11 17:52:58

标签: java usability software-design code-duplication

我最近对我在项目代码库中出现的问题越来越感到沮丧。

我正在开发一个包含大约1M行代码的大型java项目。接口和类结构设计得非常好,编写代码的工程师非常精通。问题在于,为了使代码更清晰,人们在需要重用某些功能时编写实用程序类,随着时间的推移,随着项目的增长,越来越多的实用程序方法出现。但是,当下一位工程师遇到对相同功能的需求时,他无法知道有人已在代码中的某处实现了实用程序类(或方法),并在另一个类中实现了该功能的另一个副本。结果是大量代码重复和太多具有重叠功能的实用程序类。

我们作为一个团队是否可以使用任何工具或任何设计原则来防止实用程序类的重复和低可见性?

示例:工程师A有3个位置需要将XML转换为String,因此他编写了一个名为 XMLUtil 的实用程序类,并将静态toString(Document)方法放入它。工程师B有几个地方将文档序列化为各种格式,包括String,因此他编写了一个名为 SerializationUtil 的实用程序类,并有一个名为serialize(Document)的静态方法,它返回一个String。

请注意,这不仅仅是代码复制,因为上述示例的2个实现很可能是不同的(例如,一个使用变换器API而另一个使用Xerces2-J),因此可以将其视为“最好的做法“问题也是......

更新:我想我更好地描述了我们开发的当前环境。 我们使用Hudson进行CI,使用Clover进行代码覆盖,使用Checkstyle进行静态代码分析。 我们使用敏捷开发,包括日常会谈和(可能不充分)代码审查。 我们在.util中定义了所有的实用程序类,由于它的大小现在有13个子包,在根(.util)类下有大约60个类。我们还使用第三方库,例如大多数apache commons jar和一些组成Guava的罐子。

我很肯定如果我们让某人完成重构整个软件包的任务,我们可以减少一半的实用程序,我想知道是否有任何工具可以降低运营成本,如果有的话任何可以尽可能延迟问题的方法。

9 个答案:

答案 0 :(得分:9)

解决此问题的一个好方法是开始添加更多面向对象。要使用您的示例:

  

示例:工程师A有3个位置需要将XML转换为String,因此他编写了一个名为XMLUtil的实用程序类,并在其中放置了一个静态toString(Document)方法

解决方案是停止使用JVM(String,Integer,java.util.Date,java.w3c.Document)提供的基本类型或类型,并将它们包装在您自己的项目特定类中。然后您的XmlDocument类可以提供方便的toString方法和其他实用程序方法。您自己的ProjectFooDate可以包含解析和格式化方法,否则这些方法最终会出现在各种DateUtils类等中。

这样,只要您尝试对某个对象执行某些操作,IDE就会使用您的实用程序方法提示您。

答案 1 :(得分:5)

答案 2 :(得分:4)

您可以使用几种敏捷/ XP实践来解决这个问题,例如:

  • 互相交谈(例如在每日站立会议期间)
  • 结对编程/代码审查

然后创建,记录&测试一个或多个可以引用的实用程序库项目。我建议使用Maven来管理家属/版本。

答案 3 :(得分:3)

您可以考虑建议将所有实用程序类放在组织良好的包结构中,如com.yourcompany.util.。如果人们愿意为子包和类命名,那么至少如果他们需要找到实用程序,他们就知道在哪里查看。我不认为这里有任何银弹答案。沟通很重要。也许如果开发人员在编写新工具时向其他开发人员发送简单的电子邮件,那么这足以让人们了解它。或者是共享的Wiki页面,人们可以在其中列出/记录它们。

答案 4 :(得分:1)

  1. 团队沟通(喊出“嘿,有人有文件toString吗?”)
  2. 将实用程序类保持在绝对最小值并将它们限制为单个命名空间
  3. 总是想:我怎么能用对象做到这一点。在您的示例中,我将扩展Document类并向其添加toStringserialize方法。

答案 5 :(得分:0)

将IDE“代码完成”功能与支持类型扩展的语言(例如C#和F#)结合使用时,此问题有所帮助。因此,想象Java具有这样的功能,程序员可以在IDE中轻松地探索类中的所有扩展方法,如:

Document doc = ...
doc.to //list pops up with toXmlString, toJsonString, all the "to" series extension methods

当然,Java没有类型扩展。但是您可以使用grep在项目中搜索“将SomeClass作为第一个参数的所有静态公共方法”,以获得对已经为给定类编写的实用方法的类似见解。

答案 6 :(得分:0)

很难建立一个识别“相同功能”的工具。 (理论上这实际上是不可能的,你可以在实践中做到这一点,你可能需要一个定理证明者)。

但经常发生的事情是人们克隆接近他们想要的clode,然后自定义它。使用克隆检测器可以找到那种类代码。

我们的CloneDR是一种基于使用参数化语法树检测精确和接近错过的克隆代码的工具。它匹配代码的已解析版本,因此不会因布局,更改的注释,修订的变量名称或许多情况下插入或删除的语句而混淆。有许多语言的版本(C ++,COBOL,C#,Java,JavaScript,PHP,...),你可以看到提供的克隆检测运行的例子 链接。它通常会找到10-20%的重复代码,如果您将该代码抽象到宗教基础上的库方法中,您的代码库实际上可能会缩小(一个组织使用CloneDR时会发生这种情况)。

答案 7 :(得分:0)

您正在寻找可以帮助您解决这个不可避免的问题的解决方案,然后我可以推荐一个工具:

阅读更多内容:

答案 8 :(得分:0)

  1. 标准应用程序实用程序项目。根据功能构建一个具有受限扩展范围和包的jar。
  2. 使用常见的实用程序,如apache-commons或google集合,并提供抽象
  3. 维护知识库和文档以及针对错误和增强功能的JIRA跟踪
  4. 进化重构
  5. findbugs和pmd用于查找代码重复或错误
  6. 审核并测试效用实用工具
  7. util karma!要求团队成员在代码库中做出贡献,只要他们在现有丛林代码中找到代码库或需要新密码代码。