訪問者模式基本介紹
- 訪問者模式(VisitorPattern)吼拥,封裝-些作用于某種數(shù)據(jù)結(jié)構(gòu)的各元素的操作,它可以在不改變數(shù)據(jù)結(jié)構(gòu)的前提下定義作用于這些元素的新的操作钧大。
- 主要將數(shù)據(jù)結(jié)構(gòu)與數(shù)據(jù)操作分離癌椿,解決數(shù)據(jù)結(jié)構(gòu)和操作耦合性問題
- 訪問者模式的基本工作原理是:在被訪問的類里面加一個對外提供接待訪問者的接口
-
訪問者模式主要應(yīng)用場景是:需要對一個對象結(jié)構(gòu)中的對象進行很多不同操作(這些操作彼此沒有關(guān)聯(lián)),同時需要避免讓這些操作"污染"這些對象的類沦补,可以選用訪問者模式解決
- Visitor是抽象訪問者,為該對象結(jié)構(gòu)中的Concret eElenent的每一個類聲明一 個visit 操作
- ConcreteVisitor :是一個具體的訪問值實現(xiàn)每個有Visitor聲明的操作咪橙,是每個操作實現(xiàn)的部分夕膀。
- Object Structure能枚舉它的元素,可以提供一 一個高層的接口匣摘,用來允許訪問者訪問元素
- Element 定義一個accept方法店诗,接收一個訪問者對象
- ConcreteElement為具體元素裹刮,實現(xiàn)了accept方法
例子:將觀眾分為男人和女人音榜,對歌手進行測評,當(dāng)看完某個歌手表演后捧弃,得到他們對該歌手不同的評價(評價有不同的種類赠叼,比如成功。失敗等)
public abstract class Action {
public abstract void getManResult(Man man);
public abstract void getWomanResult(Woman woman);
}
public class Success extends Action {
@Override
public void getManResult(Man man) {
// TODO Auto-generated method stub
System.out.println("男人認(rèn)為成功");
}
@Override
public void getWomanResult(Woman woman) {
// TODO Auto-generated method stub
System.out.println("女人認(rèn)為成功");
}
}
public class Failure extends Action{
@Override
public void getManResult(Man man) {
// TODO Auto-generated method stub
System.out.println("男人認(rèn)為失敗");
}
@Override
public void getWomanResult(Woman woman) {
// TODO Auto-generated method stub
System.out.println("女人認(rèn)為失敗");
}
}
//說明
//1.這里我們使用到了雙分派违霞,即首先在客戶端程序中,將具體狀態(tài)作為參數(shù)傳遞Woman中(第一次分派)
//2.然后Woman類調(diào)用作為參數(shù)的"具體方法"中方法getWomanResult, 同時將自2(this)作為參數(shù)傳入嘴办,完成第二次的分派
public abstract class Person {
public abstract void accpet(Action action);
}
public class Man extends Person{
@Override
public void accpet(Action action) {
// TODO Auto-generated method stub
action.getManResult(this);
}
}
public class Woman extends Person {
@Override
public void accpet(Action action) {
// TODO Auto-generated method stub
action.getWomanResult(this);
}
}
public class ObjectStructure {
private List<Person> persons = new ArrayList<Person>();
public void attach(Person p){
persons.add(p);
}
public void detach(Person p){
persons.remove(p);
}
public void display(Action action){
for(Person person : persons)
person.accpet(action);
}
}
public class Client {
public static void main(String[] args) {
ObjectStructure structure = new ObjectStructure();
Person man = new Man();
Person woman = new Woman();
structure.attach(man);
structure.attach(woman);
Success success = new Success();
Failure failure = new Failure();
structure.display(success);
System.out.println("===============");
structure.display(failure);
}
}
上面提到了雙分派,所謂雙分派是指不管類怎么變化买鸽,我們都能找到期望的方法運行涧郊。
雙分派意味著得到執(zhí)行的操作取決于請求的種類和兩個接收者的類型
訪問者模式的注意事項和細(xì)節(jié)
?優(yōu)點
1)訪問者模式符合單一職責(zé)原則、讓程序具有優(yōu)秀的擴展性眼五、靈活性非常高
2)訪問者模式可以對功能進行統(tǒng)一妆艘,可以做報表、UI看幼、攔截器與過濾器批旺,適用于數(shù)據(jù)
結(jié)構(gòu)相對穩(wěn)定的系統(tǒng)
?缺點
1)具體元素對訪問者公布細(xì)節(jié),也就是說訪問者關(guān)注了其他類的內(nèi)部細(xì)節(jié)诵姜,這是迪米
特法則所不建議的汽煮,這樣造成了具體元素變更比較困難
2)違背了依賴倒轉(zhuǎn)原則。訪問者依賴的是具體元素,而不是抽象元素
3)因此暇赤,如果一個系統(tǒng)有比較穩(wěn)定的數(shù)據(jù)結(jié)構(gòu)心例,又有經(jīng)常變化的功能需求,那么訪問
者模式就是比較合適的.