設(shè)計模式_15_訪問者模式

訪問者模式基本介紹
  1. 訪問者模式(VisitorPattern)吼拥,封裝-些作用于某種數(shù)據(jù)結(jié)構(gòu)的各元素的操作,它可以在不改變數(shù)據(jù)結(jié)構(gòu)的前提下定義作用于這些元素的新的操作钧大。
  2. 主要將數(shù)據(jù)結(jié)構(gòu)與數(shù)據(jù)操作分離癌椿,解決數(shù)據(jù)結(jié)構(gòu)和操作耦合性問題
  3. 訪問者模式的基本工作原理是:在被訪問的類里面加一個對外提供接待訪問者的接口
  4. 訪問者模式主要應(yīng)用場景是:需要對一個對象結(jié)構(gòu)中的對象進行很多不同操作(這些操作彼此沒有關(guān)聯(lián)),同時需要避免讓這些操作"污染"這些對象的類沦补,可以選用訪問者模式解決


    image.png
  1. Visitor是抽象訪問者,為該對象結(jié)構(gòu)中的Concret eElenent的每一個類聲明一 個visit 操作
  2. ConcreteVisitor :是一個具體的訪問值實現(xiàn)每個有Visitor聲明的操作咪橙,是每個操作實現(xiàn)的部分夕膀。
  3. Object Structure能枚舉它的元素,可以提供一 一個高層的接口匣摘,用來允許訪問者訪問元素
  4. Element 定義一個accept方法店诗,接收一個訪問者對象
  5. 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)常變化的功能需求,那么訪問
者模式就是比較合適的.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末翎卓,一起剝皮案震驚了整個濱河市契邀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌失暴,老刑警劉巖坯门,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異逗扒,居然都是意外死亡古戴,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門矩肩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來现恼,“玉大人,你說我怎么就攤上這事黍檩〔媾郏” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵刽酱,是天一觀的道長喳逛。 經(jīng)常有香客問我,道長棵里,這世上最難降的妖魔是什么润文? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮殿怜,結(jié)果婚禮上典蝌,老公的妹妹穿的比我還像新娘。我一直安慰自己头谜,他們只是感情好骏掀,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著柱告,像睡著了一般截驮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上末荐,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天侧纯,我揣著相機與錄音,去河邊找鬼甲脏。 笑死眶熬,一個胖子當(dāng)著我的面吹牛妹笆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播娜氏,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼拳缠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了贸弥?” 一聲冷哼從身側(cè)響起窟坐,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎绵疲,沒想到半個月后哲鸳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡盔憨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年徙菠,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片郁岩。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡婿奔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出问慎,到底是詐尸還是另有隱情萍摊,我是刑警寧澤,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布如叼,位于F島的核電站冰木,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏薇正。R本人自食惡果不足惜片酝,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一囚衔、第九天 我趴在偏房一處隱蔽的房頂上張望挖腰。 院中可真熱鬧,春花似錦练湿、人聲如沸猴仑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽辽俗。三九已至,卻和暖如春篡诽,著一層夾襖步出監(jiān)牢的瞬間崖飘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工杈女, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留朱浴,地道東北人吊圾。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像翰蠢,于是被迫代替她去往敵國和親项乒。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345