ブログ 約2分

実装の不十分なC++デザインパターンを自動検出する

Share this article
実装の不十分なC++デザインパターンを自動検出する

デザインパターンとは、実際のアプリケーション開発で何度も遭遇するソフトウェア設計上の問題へのソリューションです。パターンは、再利用可能な設計とオブジェクト間の相互作用に関するものです。シングルトン、ファクトリ、ストラテジーのように非常に人気のあるものもあれば、フライウェイトパターンのようにあまり広く使われていないものもあります。

開発者がパターンを不適切に実装することがあり、それが設計上の問題をもたらし、その利点を損なうことがあります。不適切に実装されたパターンを特定し、その実装を修正することは有益です。

この種の問題を検出するには、次のようなソースコードに関するできるだけ多くの情報が必要です。

  • クラス、メソッド、フィールドの属性。
  • クラス間の継承関係。
  • クラス、メソッド、フィールド間の依存関係。
  • クラスがどこでインスタンス化されるか。
CppDepend

は、これらすべてのデータを含むコードモデルを生成し、 CQLinqを使用してクエリできます。シングルトンとストラテジーの2つのパターンの誤用を検出してみましょう。

シングルトン(Singleton)

シングルトンパターンは、クラスのインスタンス化を1つのオブジェクトに制限するデザインパターンです。ただし、このパターンの使用は議論の対象となっており、すべてのアーキテクトやデザイナーが推奨しているわけではありません。シングルトン論争に関する 記事 はこちらです。

シングルトンパターンを実装する際の一般的な間違いは、コンストラクタをprivateにするのを忘れることです。

次のクエリは、シングルトンと同じ特徴を持つすべてのクラス、つまり自分自身を参照するstaticフィールドとこのフィールドを返すstaticメソッドを含むが、privateコンストラクタを持たないクラスを検出します。

pattern1

ストラテジー(Strategy)

クラスがその動作のみが異なる状況は多くあります。この場合、アルゴリズムを別のクラスに分離して、実行時に異なるアルゴリズムを選択できるようにするのが良い考えです。ストラテジーパターンはそのようなニーズに適した候補です。

このパターンのUML図は次のとおりです。

Strategy_Pattern_in_UML

図が示すように、コンテキストクラスは抽象クラス「Strategy」を使用し、具象実装については知りません。しかし、一部の実装では、具象クラスがコンテキストクラスによって直接使用されています。この間違いの例を次に示します。

pattern3

CQLinqでこのストラテジーパターンを使用しているすべてのクラスを検索してみましょう。そのために、クライアントが抽象クラスではなく具象実装のメソッドを直接使用している、複数の派生クラスを持つ抽象クラスを検索できます。

pattern2

このクエリの結果は、抽象クラスの代わりに他のメソッドによって直接使用されている派生型を示します。その後、それらを使用しているメソッドを見つけて、ストラテジーパターンの実装を修正すべき場所を特定するだけです。

ただし、これはストラテジーパターンが不適切に実装されている正確な場所を特定するものではありません。代わりに、開発者が手動でレビューできる潜在的な問題領域を強調表示します。

結論

デザインパターンは設計品質を向上させることができます。しかし、不適切に実装された場合、問題やバグの原因となる可能性があります。

Share this article