デザインパターン(21)ビジターVisitorパターン

Javaでは、すべてのオブジェクトはObjectオブジェクトから継承され、そうすることの利点の一つは、管理しやすいオブジェクト・データ構造の集合を作るために、たとえば、あなたがVectorに任意の型のオブジェクトを使用することができます。

しかし、今の問題は使用することは、あなたのコレクション(接続)は、オブジェクトの1種類を格納していないオブジェクトのみ場合は、これらのオブジェクトのいくつかの個別の操作をしたい場合は、最初の条件は、オブジェクトタイプを知っている、そこにありますinstanceofは、プログラム、最も簡単な場合には、おそらくあなたはようになり、良い方法のように思えます。
 パブリッククラスElementA { 
    //いくつかの実装 
 }   publicクラスElementB {      //いくつかの実装   }   publicクラスElementC {      //いくつかの実装   }   // ...      イテレータイテレータ= arrayList.iterator()      (iterator.hasNext()一方){          IF()ElementAのinstanceof O          (ElementA)o.operationA();         それ以外(ElementB instanceofはO)であれば           (ElementB)o.operationB();       それ以外(ElementC instanceofはO)であれば           (ElementC)o.operationC();       他           のSystem.out.println(                  「申し訳ありません!私はあなたが誰であるか分かりません!」 
 





















                   + o.toString())。 
        // ...
    }

    // ....
 
あなたは、オブジェクトの種類ごとに動作時間を変更したいのであれば不可能ではない、ではなく、将来の拡張、今日のように、あなたは多くの場所を変更する必要があります。

オブジェクト自体の観点から、それを上に考えるために、家の中のオブジェクトのいずれか、オブジェクト、言った:「家の外骨の折れるを判断してはいけない、今あなたは私が誰かわからないということ、そしてあなたは、うまく私を訪問来ますあなたは、私が誰あなたが私に行う方法を知っている方法を教えてください」!

上記の説明を実施するためのプログラムで:
  • IElement.java
パブリックインターフェースIElement { 
    公共ボイド(IVisitor訪問者)を受け入れます。
}

  • ElementA.java
パブリッククラスElementAはIElement {実装
    公共ボイド受け入れる(IVisitor訪問者){ 
        visitor.visit(この); 
    } 

    公共ボイドoperationA(){ 
        System.out.printlnは(
              「Aさんの仕事を......ようアンドよう...」)。
    } 
}

  • ElementB.java
パブリッククラスElementBはIElement {実装
    公共ボイド受け入れる(IVisitor訪問者){ 
        visitor.visit(この); 
    } 

    公共ボイドoperationB(){ 
        System.out.printlnは(
           「例えば、このようなアンド... Bの仕事を...」)。
    } 
}

  • ElementC.java
パブリッククラスElementCが実装IElement { 
    公共ボイド受け入れる(IVisitorのビジター){ 
        visitor.visit(この); 
    } 

    公共ボイドoperationC(){ 
        System.out.printlnは(
            「例えば、このようなアンド... Cの仕事を...」)。
    } 
}

  • IVisitor.java
public interface IVisitor { 
    public void visit(ElementA element); 
    public void visit(ElementB element); 
    public void visit(ElementC element); 
}  

  • VisitorA.java
public class VisitorA implements IVisitor { 
    public void visit(ElementA element) { 
        element.operationA(); 
    }

    public void visit(ElementB element) { 
        element.operationB(); 
    }

    public void visit(ElementC element) { 
        element.operationC(); 
    } 
}  

  • Main.java
パブリッククラスメイン{ 
    公共の静的な無効メイン(文字列[] args){ 
        //自分のタイプについて何も知らない
        要素の配列にそれらを保存した後、// 
        IElement []リスト= {新しいElementA()、
                           新ElementB()、
                           新ElementC() }。

        IVisitor訪問者=新しいVisitorA(); 

        以下のために(; iはlist.lengthを<; I = 0 int型私は++)
            リストを[I] .accept(訪問者)。
    } 
}

ビジターアクセスは、完了するために、過負荷に基づいてIElementのすべての実装のための項目され、それをアクセスするためにIVisitorを受け入れ、あなたは別の部分に頼ることができますので、受け入れる()メソッド、IVisitorは、明白な(IElementにアクセスするための正しい方法を使用しますIElement上の対応する操作の訪問で行われた関数名、または達成するための過負荷)、および()、あなたがいる限り、その上にオブジェクトの代替IVisitorタイプとして、今日各IElementの動作を交換したい場合、つまり、この行:
 IVisitor新しい新しいVisitorA訪問者= //(); 
 // IVisitorを置き換える、あなたが操作をすべて置き換えることができ
 、複数の場所変更せずに//を
 IVisitorビジター=新しいVisitorBを(); 
 

実際の例を与えるために、VisitorAを考えるだけで怠惰なセールスマンさて、今日より勤勉なセールスマンVisitorBは、IElementを訪問した後、IElementは限り、プログラムにVisitorBを達成するために多くの操作を行いますがありますすることができるようになりますVisitorBカテゴリを追加します。
  • VisitorB.java
public class VisitorB implements IVisitor { 
    public void visit(ElementA element) { 
        System.out.println("VisitorB is a hard worker...."); 
        element.operationA(); 
        System.out.println(
            "I want to do some extra work on A...."); 
    }

    public void visit(ElementB element) { 
        System.out.println("VisitorB is a hard worker...."); 
        element.operationB(); 
        System.out.println(
                   "I want to do some extra work on B...."); 
    }

    public void visit(ElementC element) { 
        System.out.println("VisitorB is a hard worker...."); 
        element.operationC(); 
        System.out.println(
                  「私はCにいくつかの余分な仕事をしたい....」); 
    } 
}

実証するための主な変更点:
  • Main.java
public class Main { 
    public static void main(String[] args) { 
        IElement[] list = {new ElementA(), 
                           new ElementB(), 
                           new ElementC()}; 

        System.out.println("visitorA is coming......."); 
        IVisitor visitorA = new VisitorA(); 
        for (int i=0; i < list.length; i++) 
           list[i].accept(visitorA);

        System.out.println("\nvisitorB is coming......."); 
        IVisitor visitorB = new VisitorB(); 
        for (int i=0; i < list.length; i++) 
            list[i].accept(visitorB); 
    } 
} 

System.out.println()の例では、ただのヒント、それはまた、IElementの追加方法のためのあなたの直接呼び出しである可能性があります。 

ビジターモードUMLクラス図は以下の構造:


では Javaの世界には 記事があり、言及は弾力性を改善するためにリフレクションを使用することができたときに、さらに参照することができます興味を持っている訪問者の使用 ビジターデザインパターンで反省

ます。https://www.cnblogs.com/moiyer/archive/2011/08/10/2316168.htmlで再現

おすすめ

転載: blog.csdn.net/weixin_34026484/article/details/94693164