Dyuichi Blog

オブジェクト指向シリーズⅣ: デザインパターン [⑬ Visitor]

概要

visitは日本語で「訪れる」,visitorは日本語で「訪問者」という意味になる.Visitorパターンは,オブジェクトの振る舞いをオブジェクトの構造から分離するためのパターンである.

Visitorパターンの主な要素は以下である.

  • Element:Visitorを受け取るacceptメソッドを定義したインターフェース
  • ConcreteElement:Elementインターフェースを実装したクラス
  • Visitor:Elementのacceptメソッド内で実行されることを想定したvisitメソッドを定義したインターフェース
  • ConcreteVisitor:Visitorインターフェースを実装したクラス.

クラス図

画像が読み込まれない場合はページを更新してみてください。

実装例(Java)

javaimport java.util.ArrayList;
import java.util.List;

// Element
interface Element {
    void accept(Visitor visitor);
}

// Concrete Element
class ConcreteElementA implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

class ConcreteElementB implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

// Visitor
interface Visitor {
    void visit(ConcreteElementA element);
    void visit(ConcreteElementB element);
}

// Concrete Visitor
class ConcreteVisitorA implements Visitor {
    @Override
    public void visit(ConcreteElementA element) {
        System.out.println("ConcreteVisitorA visit ConcreteElementA");
    }
    @Override
    public void visit(ConcreteElementB element) {
        System.out.println("ConcreteVisitorA visit ConcreteElementB");
    }
}

class ConcreteVisitorB implements Visitor {
    @Override
    public void visit(ConcreteElementA element) {
        System.out.println("ConcreteVisitorB visit ConcreteElementA");
    }
    @Override
    public void visit(ConcreteElementB element) {
        System.out.println("ConcreteVisitorB visit ConcreteElementB");
    }
}

// Client
public class VisitorPattern {
    public static void main(String[] args) {
        List<Element> elements = new ArrayList<>();
        elements.add(new ConcreteElementA());
        elements.add(new ConcreteElementB());
        for (Element element : elements) {
            element.accept(new ConcreteVisitorA());
            element.accept(new ConcreteVisitorB());
        }
    }
}

まとめ,所感

構造と振る舞いを分離できるのはありがたいと思うが,他のパターンと比較して,このパターンが生きるケースがなかなか思いつけない…