この記事を書く前に、私はまた、訪問者のダニエル・ネットワークの設計パターンによって書かれたダース以上の記事を見て、訪問者があまりにも多く、このモデルは最も複雑なものですが、私は他のデザインパターンを考えるとないことを言います異なるので、自分のためのビットは、私はほとんどの人が理解できると信じています。
まず、ビジターパターンを認識
1、の概念
各要素のいくつかのデータ構造に適用されるいくつかの包装作業は、それがこのデータ構造を前提として、これらの動作要素の役割の新しい定義を変更することはできません。
それを理解するには?私たちのすべてが栄光の王を演じた場合、例えば、取ります。各ヒーローは、3つの基本的なスキルを持っているが、選手たちは英雄のスキルは同じではありません達成するために、さまざまな方法で動作します。たとえば、あなたが唯一の漢が頭を送信し再生することができ、勝利である漢の夢を果たして涙。
この例では、荘子とジェン智の三つの基本的なスキルが変更されていませんが、訪問者のパターンは、これらの3つのスキルにいくつかの異なった効果を得ることができます。我々はそれを理解するために、さらにクラス図を描くことができます。
2、図タイプ
私は、このモデルが、それは、そのクラス図のより複雑に言うと信じて、私たちは、各モジュールのために着色された後、実際にはそれほど面倒ではないことを見つけることができるようになります。上記のクラス図は、6つのロールの合計に関連します。
(1)Vistor(抽象訪問者):ユーザー・インターフェース・オブジェクト構造訪問の役割文の特定の要素。プレーヤー内部の王の栄光の異なるピースのように。
(2)ConcreteVisitor(特に、訪問者):訪問者は、定義された各特定動作Vistorのために実装されています。これは、1人の特定の選手のようです。
(3)要素(抽象要素):パラメータとして訪問者の操作を受け付ける定義。それは主人公のテンプレート内部の王にたとえることができます。
(4)ConcreteElement(特に金属):要素に対する操作を実行するための要素を受け入れる()メソッド呼び出しVistorアクセス方式を実現します。それは幻滅とジェン智のように、特定の主人公のように表すことができます。
(5)ObjectStructure(オブジェクト構造):組み合わせモードであってもよいし、設定することができる;を含む要素を列挙するために、Vistorアクセスその要素を可能にするインターフェースを提供します。荘子とジェン智は外の要素へのアクセスが許可されています。
これを念頭に、ここでは分析するために、コードを使用することができます。
第二に、コードの実装
最初のステップ:(テンプレートの主人公)を抽象要素を定義
public abstract class Hero {
//英雄可以接受玩家的访问,让玩家来操作
public abstract void accept(Player visitor);
}
复制代码
ステップ2:特定の要素の定義(具体的には、主人公A)
まず、ジェン智を定義することができます
//甄姬
public class ZhenHero extends Hero {
//可以接受玩家的操作
@Override
public void accept(Player visitor) {
visitor.visitZhen(this);
}
//自身的技能
public void operate() {
System.out.println("甄姬放出了技能");
}
}
复制代码
幻滅もあります
//庄周
public class ZhuangHero extends Hero {
//接受外部的访问
@Override
public void accept(Player visitor) {
visitor.visitZhuang(this);
}
//自身的技能
public void operate() {
System.out.println("庄周放出了技能");
}
}
复制代码
第三段階:抽象訪問者(プレイヤー)を定義します
//玩家可以访问甄姬和庄周的技能
public interface Player {
public abstract void visitZhuang(ZhuangHero element);
public abstract void visitZhen(ZhenHero element);
}
复制代码
第四段階:特定の訪問者(私の選手や他の選手)を定義します
最初は自分の操作です
public class PlayerMe implements Player {
@Override
public void visitZhuang(ZhuangHero element) {
System.out.println("玩家我访问庄周,庄周开始使出技能");
element.operate();
}
@Override
public void visitZhen(ZhenHero element) {
System.out.println("玩家我访问甄姬,甄姬开始使出技能");
element.operate();
}
}
复制代码
その後、他のプレイヤーが操作します
public class PlayerOthers implements Player {
@Override
public void visitZhuang(ZhuangHero element) {
System.out.println("玩家其他人访问庄周,庄周开始使出技能");
element.operate();
}
@Override
public void visitZhen(ZhenHero element) {
System.out.println("玩家其他人访问甄姬,甄姬开始使出技能");
element.operate();
}
}
复制代码
ステップ5:オブジェクト構造体の定義
public class ObjectStructure {
//保存所有需要被访问的元素
private List<Hero> heros = new ArrayList<Hero>();
public void handleRequest(Player visitor) {
//访问所有元素
for(Hero hero : heros) {
hero.accept(visitor);
}
}
public void addHero(Hero hero) {
heros.add(hero);
}
}
复制代码
ステップ6:クライアントのテスト
public class Client {
public static void main(String[] args) {
ObjectStructure os = new ObjectStructure();
Hero zhuang = new ZhuangHero();
Hero zhen = new ZhenHero();
os.addHero(zhuang);
os.addHero(zhen);
Player visitorMe = new PlayerMe();
Player visitorOthers = new PlayerOthers();
// 让访问者访问对象结构中的元素
os.handleRequest(visitorMe);
os.handleRequest(visitorOthers);
}
}
复制代码
最後のステップは、我々は結果を見ることができます
これは、Visitorパターンです。
第三に、ビジターパターン解析
条件は、オブジェクトモデルの構造を使用して、訪問者は、一般的に変更されていないということですが、操作は同じような状況の欠如ではありません。例えば、オブジェクト、XMLドキュメントの解析、コンパイラの設計などの複雑なセットは、多くの場合、このモードを使用します。
利点は、ビジターパターンによって解決される問題は、すなわち、使用シナリオの欠点は、オブジェクト構造内の適切な変更を使用することなくことがあるということです。