デザインパターン19のビジターパターン

バックグラウンド

実生活にはそのようなシナリオがあります。コレクションオブジェクトにはさまざまな要素があり、要素ごとにさまざまな訪問者とアクセス方法があります。たとえば、スーパーマーケットにはさまざまな商品があり、服を買う顧客もたくさんいます。顧客が異なれば、製品に対する評価も異なります。

処理される比較的安定したデータ要素とさまざまなアクセス方法を備えたデータ構造に遭遇した場合、ビジターモデルを使用できます。ビジターモデルにより、アクセス方法をデータ構造から分離できるため、元のプログラムコードを変更することなく、新しいアクセス方法を拡張し、柔軟な拡張を実現できます。

ビジターパターンは何ですか

上記のテキストはクラウドにある可能性があります。ビジターパターンを使用する機能は、データ構造内の要素を操作メソッドから分離することであるということだけを知っておく必要があります。

「「

オブジェクト構造の要素に対して実行される操作を表します。Visitorでは、操作する要素のクラスを変更せずに新しい操作を定義できます。データ構造を変更せずに、これらの要素に作用する新しい操作を定義できます。 。)

ビジターパターンは、主に次の5つの要素で構成されています。

「「
  • 抽象ビジター(ビジター)ロール:特定の要素にアクセスするためのインターフェースを定義します。特定の要素クラスごとに、訪問操作visit()に対応し、この操作のパラメータータイプは、訪問する特定の要素を識別します。

  • 特定のビジター(ConcreteVisitor)ロール:抽象ビジターロールで宣言された各アクセス操作を実装し、要素にアクセスするときにビジターが何をすべきかを決定します。

  • 抽象要素(Element)の役割:accept()操作を含むインターフェースを宣言し、受け入れられたビジターオブジェクトがaccept()メソッドのパラメーターとして使用されます。

  • 具体的な要素(ConcreteElement)の役割:抽象要素の役割によって提供されるaccept()操作を実装します。メソッド本体は通常visitor.visit(this)です。さらに、具体的な要素には、独自のビジネスロジックに関連する操作が含まれる場合もあります。

  • オブジェクト構造の役割:要素の役割を含むコンテナーであり、訪問者がコンテナー内のすべての要素をトラバースするためのメソッドを提供します。通常、List、Set、Mapなどの集約クラスによって実装されます。

構造図は次のとおりです。

ビジターモード

コード

素子

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

ConcreteElement

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

    public String operationA() {
        return "具体元素A的操作。";
    }
}
public class ConcreteElementB implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    public String operationB() {
        return "具体元素B的操作。";
    }
}

ビジター

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

ConcreteVisitor

public class ConcreteVisitorA implements Visitor {
    @Override
    public void visit(ConcreteElementA element) {
        System.out.println("具体访问者A访问-->" + element.operationA());
    }

    @Override
    public void visit(ConcreteElementB element) {
        System.out.println("具体访问者A访问-->" + element.operationB());
    }
}
public class ConcreteVisitorB implements Visitor {
    @Override
    public void visit(ConcreteElementA element) {
        System.out.println("具体访问者B访问-->" + element.operationA());
    }

    @Override
    public void visit(ConcreteElementB element) {
        System.out.println("具体访问者B访问-->" + element.operationB());
    }
}

ObjectStructure

public class ObjectStructure {
    private List<Element> list = new ArrayList<>();

    public void accept(Visitor visitor) {
        Iterator<Element> i = list.iterator();
        while (i.hasNext()) {
            i.next().accept(visitor);
        }
    }

    public void add(Element element) {
        list.add(element);
    }

    public void remove(Element element) {
        list.remove(element);
    }
}

テストコード

@Test
public void test() {
    ObjectStructure os=new ObjectStructure();
    os.add(new ConcreteElementA());
    os.add(new ConcreteElementB());
    Visitor visitor=new ConcreteVisitorA();
    os.accept(visitor);
    System.out.println("------------------------");
    visitor=new ConcreteVisitorB();
    os.accept(visitor);
}

試験結果:

具体访问者A访问-->具体元素A的操作。
具体访问者A访问-->具体元素B的操作。
------------------------
具体访问者B访问-->具体元素A的操作。
具体访问者B访问-->具体元素B的操作。

コールチェーンは次のとおりです。

//举例A:
ObjectStructure#accept() -> ConcreteElementA#accept() -> ConcreteVisitorA#visit()

ビジターパターンを考える

では、いつビジターモードを使用するのでしょうか。

オブジェクトの構造が安定しているが、操作アルゴリズムが頻繁に変更される場合は、ビジターモードを使用して、これらの操作アルゴリズムが変更されてデータ構造に影響を与えないようにすることができます。アルゴリズムをデータ構造から分離します。

実際、イテレーターを使用してコレクション要素をトラバースする場合、イテレーターモードを使用するだけでなく、ビジターモードも使用します。コレクション自体はトラバーサルに参加しませんが、イテレータメソッドを介して取得されます。

「「

この種の場所では、ビジターパターンの使用を検討する必要があります。ビジネスルールでは、複数の異なるオブジェクトをトラバースする必要があります。これ自体がビジターパターンの開始点でもあります。イテレーターパターンは、同じタイプまたは同じインターフェイスのデータにのみアクセスできます(もちろん、instanceofを使用する場合は、すべてのデータにアクセスでき、引数はありません)。ビジターパターンはイテレーターパターンです。の展開では、さまざまなオブジェクトをトラバースしてから、さまざまな操作を実行できます。つまり、アクセスするさまざまなオブジェクトに対してさまざまな操作を実行できます。

ビジターモードは集中型の通常モードであり、特に大規模な再建プロジェクトに適しています。この段階では、要件が非常に明確であり、元のシステムの機能ポイントも明確です。ビジターモードを介して、いくつかの機能を実行できます。簡単に分類できます。、統一されたレポート計算、UI表示など、究極の目標機能の集中化を実現するために、他のモードと組み合わせて、独自のフィルターまたはインターセプターのセットを構築することもできます。

 

過去におすすめ

QRコードをスキャンして、よりエキサイティングになります。または、WeChatLvshen_9を検索すると、返信してバックグラウンドで情報を取得できます

  1. 回复"java" 获取java电子书;

  2. 回复"python"获取python电子书;

  3. 回复"算法"获取算法电子书;

  4. 回复"大数据"获取大数据电子书;

  5. 回复"spring"获取SpringBoot的学习视频。

  6. 回复"面试"获取一线大厂面试资料

  7. 回复"进阶之路"获取Java进阶之路的思维导图

  8. 回复"手册"获取阿里巴巴Java开发手册(嵩山终极版)

  9. 回复"总结"获取Java后端面试经验总结PDF版

  10. 回复"Redis"获取Redis命令手册,和Redis专项面试习题(PDF)

  11. 回复"并发导图"获取Java并发编程思维导图(xmind终极版)

もう1つ:[マイベネフィット]をクリックして、さらに驚きを持ってください。

おすすめ

転載: blog.csdn.net/wujialv/article/details/109713535