博客 阅读时间 2 分钟

自动检测实现不当的 C++ 设计模式

分享本文
Automatically Detect Poorly Implemented C++ Design Patterns.

设计模式是针对您在真实应用开发中反复遇到的软件设计问题的解决方案。模式关乎可复用的设计以及对象之间的交互。其中一些非常流行,如单例、工厂和策略模式;另一些则没有被广泛使用,如享元模式。

有时开发者对模式的实现很糟糕,这会引入设计问题并降低其收益。识别实现不当的模式并纠正其实现是很有用的。

要检测这类问题,我们需要尽可能多地了解源代码的信息,包括:

  • 类、方法和字段的属性。
  • 类之间的继承关系。
  • 类、方法和字段之间的依赖关系。
  • 类在何处被实例化。
CppDepend

生成一个包含所有这些数据的代码模型,并让您可以使用CQLinq对其进行查询。让我们尝试检测两种模式的误用:单例模式和策略模式。

单例模式(Singleton)

单例模式是一种将类的实例化限制为一个对象的设计模式。然而,使用这个模式已经变得有争议,并非所有架构师和设计师都推荐它;这里有一篇关于单例之争的文章。

实现单例模式时的一个常见错误是没有将构造函数设为私有。

以下查询检测所有具有与单例相同特征的类——即包含一个引用自身的静态字段和一个返回该字段的静态方法的类——但构造函数不是私有的。

pattern1

策略模式(Strategy)

在许多情况下,类之间仅在行为上有所不同。在这种情况下,将算法隔离到独立的类中是个好主意,这样您就可以在运行时选择不同的算法。策略模式正是满足这类需求的好选择。

以下是该模式的 UML 图:

Strategy_Pattern_in_UML

如图所示,上下文类使用抽象类"Strategy",并不了解具体实现。然而,在某些实现中,上下文类直接使用了具体类。下面是这种错误的一个示例:

pattern3

让我们用 CQLinq 搜索所有使用这种策略模式的类。为此,我们可以搜索拥有多个派生类、且客户端直接使用具体实现的方法而非抽象类的抽象类。

pattern2

这个查询的结果给出了被其他方法直接使用(而非通过抽象类)的派生类型。然后您只需找到使用它们的方法,即可确定应该在哪里纠正策略模式的实现。

不过,这并不能识别出策略模式实现不当的确切位置。相反,它突出显示了潜在的问题区域,开发者随后可以手动审查。

结论

设计模式可以提升设计质量。然而,如果实现不当,它们可能变成问题和缺陷的源头。

分享本文