定義
Visitorパターンは、オブジェクト構造の効果の各要素の動作の表現は、それがこれらの要素の新しい操作の各要素のクラスの前提を変更しない役割を定義するために私達にできることです。システムのデータ構造に適用ビジターパターンは比較的安定しています。
役割
- Vistor:抽象訪問。クラス宣言ConcreteElementのそれぞれにおけるオブジェクトの動作構造。
- ConcreteVisitor:特定の訪問者。ビジターを達成するための各操作は、各操作は、アルゴリズムの一部として実装され、述べました。
- 要素:抽象要素。定義された操作を受け入れ、それが引数としてビジターにあります。
- ConcreteElement:特定の要素。動作を実現受け入れます。
- ObjectStructure:オブジェクト構造。その要素を列挙することができ、我々は、訪問者がその要素にアクセスできるようにするために、高レベルのインタフェースを提供することができます。
長所と短所
利点
新しいアクセス権を追加する操作が容易になります。
クラス階層は、操作を定義、既存のクラス階層を変更することなく、ユーザーを有効にします。
これは、散乱要素が一つのクラスに従事するのではなく、訪問者のオブジェクトにオブジェクトに関連する要素のアクセス行動に焦点を当てます。
短所
クラスは困難である新しい要素を追加します。Visitorパターンでは、それぞれの新しい要素を追加するクラスは、「開閉に反し、抽象的で来場者の役割、および特定のクラスへの各訪問者の具体的な動作の増加に対応して、新たな抽象操作を追加することを意図しています「要件の原則。
カプセル化に違反します。ビジターパターンを使用している場合、パッケージには、クラスの組み合わせを中断します。
理解することはより困難。これは、最も困難なデザインパターンのように見えます。
例
薬局に例の薬のための
要約医学:
/**
* 抽象药
*/
public abstract class Medicine {
protected String name;
protected double price;
public Medicine (String name,double price){
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public abstract void accept(Visitor visitor);
}
特定の薬:
public class MedicineA extends Medicine{
public MedicineA(String name, double price) {
super(name, price);
}
public void accept(Visitor visitor) {
visitor.visitor(this);
}
}
public class MedicineB extends Medicine{
public MedicineB(String name, double price) {
super(name, price);
}
public void accept(Visitor visitor) {
visitor.visitor(this);
}
}
抽象の訪問者:
/**
* 抽象访问者
*/
public abstract class Visitor {
protected String name;
public void setName(String name) {
this.name = name;
}
public abstract void visitor(MedicineA a);
public abstract void visitor(MedicineB a);
}
特定の訪問者:
/**
* 药房工作者
*/
public class WorkerOfPharmacy extends Visitor{
public void visitor(MedicineA a) {
System.out.println("药房工作者:" + name + "拿药 :" + a.getName());
}
public void visitor(MedicineB b) {
System.out.println("药房工作者:" + name + "拿药 :" + b.getName());
}
}
/**
* 划价员
*/
public class Charger extends Visitor{
@Override
public void visitor(MedicineA a) {
System.out.println("划价员:" + name +"给药" + a.getName() +"划价:" + a.getPrice());
}
@Override
public void visitor(MedicineB b) {
System.out.println("划价员:" + name +"给药" + b.getName() +"划价:" + b.getPrice());
}
}
処方:
public class Presciption {
List<Medicine> list = new ArrayList<Medicine>();
public void accept(Visitor visitor){
Iterator<Medicine> iterator = list.iterator();
while (iterator.hasNext()) {
iterator.next().accept(visitor);
}
}
public void addMedicine(Medicine medicine){
list.add(medicine);
}
public void removeMedicien(Medicine medicine){
list.remove(medicine);
}
}
テスト:
public static void main(String[] args) {
Medicine a = new MedicineA("板蓝根", 11.0);
Medicine b = new MedicineB("感康", 14.3);
Presciption presciption = new Presciption();
presciption.addMedicine(a);
presciption.addMedicine(b);
Visitor charger = new Charger();
charger.setName("张三");
Visitor workerOfPharmacy = new WorkerOfPharmacy();
workerOfPharmacy.setName("李四");
presciption.accept(charger);
System.out.println("-------------------------------------");
presciption.accept(workerOfPharmacy);
}
コンソール出力:
划价员:张三给药板蓝根划价:11.0
划价员:张三给药感康划价:14.3
-------------------------------------
药房工作者:李四拿药 :板蓝根
药房工作者:李四拿药 :感康