デザインパターンとは、システム設計におけるクラスやインターフェースの関係に名前をつけたものです。 GoFの23のパターンが有名です。デザインパターンというのは、どんなパターンなのか、パターンの目的は何かということを覚えることが非常に重要なのですが、これを実際に適用しようとした場合に、いつ適用していいかが見えてこないとお話になりません。

そこで、自分の勉強も兼ねつつ、パターンの実践時における使用場所や、パターンを適用するきっかけを見つけられるようにメモしておきます。

15番目のパターンはデータ構造と振る舞いを分離して、振る舞いを実行するクラスの変更や拡張を可能にするVisitorパターンのメモです。

Visitorパターン

Visitor パターンは、データ構造と振る舞いを別々のクラスに扱わせて、振る舞いの変更や追加、拡張を可能にするパターンです。

Visitorのクラス図

Visitorパターンは、データ構造(データの階層構造)が変化しない場合に限り有効なパターンになります。Visitorパターンを使う目的は一つで、データ構造に対して、振る舞いが変化する可能性がある場合に対応しやすくする事です

クラス図を見ると、インターフェースVisitor には visit というメソッドが2つあります。これはデータ構造が2種類あることを示しています。振る舞いを追加する場合、インターフェースVisitorを実装したクラスを作ることで対応します。

このパターンはダブルディスパッチとも呼ばれます。データ構造側のポリモーフィズムを使ったディスパッチと、振る舞い側のポリモーフィズムを使ったディスパッチの2回を使っています。

mainメソッド

Visitor visitor = new ConcreteVisitorA(); 
DataElement elementA = new ConcreteDataElementA(); 
 
elementA.accept(visitor); 

データ構造クラス

public void accept(Visitor visitor) { 
    visitor.visit(this); 
} 

Visitorパターンの注目する点は、インターフェースVisitのメソッド引数に実装クラス名が指定されていることです。これによって、データ構造ごとにメソッドを実装することができ、メソッドの中身がきれいになります。ここで抽象クラス名を使ってしまうと、メソッドの内部でクラスの種類によって条件分岐の処理をしなければいけなくなります。つまり、Visitorはデータ構造に依存していると言うことです。データ構造が変更になると、Visitor自体も変更する必要があることに注意です

Visitor の使いどころ

Visitorパターンがよく使われるのは、「大きなデータ構造を渡り歩き、レポートを出力するような場合」である。そうすれば、データ構造体オブジェクト自体がレポート生成用のコードを持たなくていい。また、データ構造体のコードを変更しなくても、新しいレポート機能を追加したいときには、新しいVisitorを追加することで実現できる。このことは、レポート機能を別コンポーネントとして分離し、顧客にとって必要な機能だけを個別に配布できることを意味している。

また、Visitor パターンを使う場合として、「Validation処理(妥当性チェック)」が挙げれると思います。処理するデータ構造を決めてしまって、ValidationクラスをVisitor として実装すれば、必要なチェックを実行時に追加、削除できるようになると思います。

実装サンプルと参考文献

  • 日立ソフト(Visitorパターン) 日立ソフト

  • Skeleton of GOF’s Design Pattern(JavaとC++のサンプルがあります) Visitorの骸骨

  • デザインパターンのお勧め書籍

  • 独習シリーズのデザインパターン編。デザインパターンを一人でも学べます。
  • Sun Microsystemのお墨付き。GoF以外のパターンも学べます。
  • UMLを使って、オブジェクト指向のいいとこ取りができます。
  • デザインパターンだけではなく、ソフトウェア設計の原則やプラクティスまで学びたい人におすすめ