Visitor パターン

转自:http://www.techscore.com/tech/DesignPattern/Visitor.html

 

 

 

第13章では Visitor パターンを学びます。Visitor とは、英語で「訪問者」を意味します。Visitor パターンでは、「処理」を訪問者である Visitor オブジェクトに記述することで、処理の追加を簡単にします。処理対象となる、Acceptor オブジェクトは、Visitor オブジェクトを受け入れる accept(Visitor visitor)メソッドを実装している必要があります。

例えば、家の「水道工事」を行ってもらう場合、あなたは、「水道工事業者」を家に呼んで、「よろしくお願いします。」と言って、後は全てお 任せしますよね。同様に、「庭の手入れ」を行ってもらう場合は、「庭師」を家に呼んで、全てお任せしてしまうでしょう。そのほかにも、電気工事業者を呼ぶ ことも、リフォーム業者を呼ぶこともあるでしょう。これらの訪問者に対して、あなたは、「では、よろしく」と言って、ほとんどの作業をお任せするはずで す。

お任せの仕方に多少の違いがあるかもしれませんが、最終的には、全てを業者にお任せすることになると思います。もし、新しいサービスを提供 する業者が現れたときにも、各家庭は、なんら態度を変える必要が無く、その業者を呼んで、「よろしくお願いします。」というだけで、その新しいサービスを 受けることができます。

Visitor パターンでは、このように、受け入れる側に処理を追加することなく、処理を追加することができるパターンです。

 

 

 

サンプルケースでは、家庭訪問を例に考えて見ます。各家庭では、先生であろうと、近所のおばちゃんであろうと、訪問者が訪れると、知らない人でなければ、「いらっしゃい」と言って受け入れます。この際、各家庭を Acceptor 、先生を Visitor として、Visitor パターンに当てはめて考えて見ます。Visitor パターンでは、Visitor は、訪問対象となる、家庭を訪問します。訪問された家庭は、「ようこそいらっしゃいました」と先生を受けいれます。

さて、新人先生の小学校でも、秋の家庭訪問の時期がやってきました。新人先生も、初めての家庭訪問にどきどきしながら、各家庭を訪れました。

 

新人先生 こ・こ・こ・こんにちわ
親御さん

あら、いらっしゃい新人先生。
どうかなさいましたか?青い顔して・・・。

新人先生 い・・いえ、緊張して。
親御さん あら、先生ったらかわいい。

各家庭の親御さんたちは、新人先生がどきどきしているのをあざ笑うかのように冷静です。新人先生は、何で自分だけこんなにどぎまぎしているのだろうと不思議に思い、学校に帰ってベテラン先生に聞きました。

 

新人先生 ベテラン先生、家庭訪問したとき、なぜ親御さんたちは、すごく冷静ですね。
私は、なんだかどぎまぎしちゃって。
ベテラン先生 それは、当たり前だよ。
君は、自分の家に、誰か訪問してきたとき、そんなにどきどきするかい?
新人先生 いえ、人が訪問してくるのは別に
ベテラン先生

だよね。今回、初めての経験をしているのは、君だけで、 親御さんたちは、これまで何回も家庭訪問を受けている。 少なくとも、去年は受けているだろうし、もしかしたら、兄弟などを合わせると、 既に10回以上の家庭訪問を受けている方もおられるかも知れない。 親御さんたちは、これまで、先生方を受け入れてきたのと同じように、 君を受け入れているわけだね。 メソッドで表すと、 accept(Teacher teacher) となるだろうか。 このように、先生を受け入れるメソッドを既に持っている家庭は、 違う兄弟の家庭訪問や、違う先生の家庭訪問でも、 なんら別のメソッドを用意する必要がないわけですね。

新人先生

なるほど。
どの先生が来るかによって、いろいろとメソッドを用意していたら、
親御さんたちも大変ですよね。

さて、ではこの状況をクラスで表現してみましょう。

//先生クラス
public abstract class Teacher{
List students = null;
public abstract void visit(Home studentHome);
public abstract void visit(TanakaHome studentHome);
public abstract void visit(SuzukiHome studentHome);
public List getStudentList(){
return students;
}

}
//新人先生クラス
public class RookieTeacher extends Teacher{
List students = null;
public RookieTeacher(List students){
this.students = students;
}
public void visit(Home studentHome){
System.out.println("こんにちは");
}
public void visit(TanakaHome studentHome){
studentHome.praisedChild();
}
public void visit(SuzukiHome studentHome){
studentHome.reprovedChild();
}
}
//家庭クラス
public abstract class Home{
public abstract Object praisedChild();
public abstract Object reprovedChild();
}
//受け入れインタフェース
public interface TeacherAcceptor{
public void accept(Teacher teacher);
}
//鈴木さんの家庭
public class SuzukiHome extends Home implements TeacherAcceptor{
public Object praisedChild(){
System.out.println("あら、先生ったらご冗談を");
return new Tea();
}
public Object reprovedChild(){
System.out.println("うちの子に限ってそんなことは・・・。");

return null;
}
/**
* 訪問者を受け入れるメソッド
*/
public void accept(Teacher teacher){
teacher.visit(this);
}
}

新人先生を表す RookieTeacher クラスでは、visit メソッドがオーバーロードされており、訪問する家庭によって visit メソッドが選択されます。クラス図は、以下のようになります。

新しい先生が赴任してきた場合も、各家庭は、なんら変更を必要としませんね。

 

 

 

 

Visitor パターンの一般的なクラス図は以下のようになります。

你可能感兴趣的:(object,list,null,Class,interface)