溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

設(shè)計(jì)模式之什么是訪問(wèn)者模式

發(fā)布時(shí)間:2021-10-21 17:26:47 來(lái)源:億速云 閱讀:136 作者:iii 欄目:編程語(yǔ)言

本篇內(nèi)容介紹了“設(shè)計(jì)模式之什么是訪問(wèn)者模式”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

訪問(wèn)者模式

?  

將作用于某種數(shù)據(jù)結(jié)構(gòu)中的各元素的操作分離出來(lái)封裝成獨(dú)立的類,使其在不改變數(shù)據(jù)結(jié)構(gòu)的前提下可以添加作用于這些元素的新的操作,為數(shù)據(jù)結(jié)構(gòu)中的每個(gè)元素提供多種訪問(wèn)方式。它將對(duì)數(shù)據(jù)的操作與數(shù)據(jù)結(jié)構(gòu)進(jìn)行分離,是行為類模式中最復(fù)雜的一種模式。

?    

開(kāi)門(mén)見(jiàn)山

訪問(wèn)者模式“人如其名”,就是說(shuō)不同的訪問(wèn)者對(duì)同一個(gè)對(duì)象的訪問(wèn)結(jié)果不同。為什么會(huì)不同呢?因?yàn)檫@個(gè)訪問(wèn)者是我們自己定義的,我們就想讓他不同????。

而實(shí)際情況更是如此。我通過(guò)幾份資料總結(jié)下來(lái),這個(gè)訪問(wèn)者模式所謂的訪問(wèn)者其實(shí)就是我們想要控制的訪問(wèn)權(quán)限一樣。因?yàn)槿魏我粋€(gè)“訪問(wèn)者”都可以看到具體數(shù)據(jù)的全部?jī)?nèi)容,他只是選擇性的"不看“,這樣便區(qū)分開(kāi)了”訪問(wèn)者“「關(guān)注的內(nèi)容」,或者 「限制」訪問(wèn)者「權(quán)限」

可能我說(shuō)的有點(diǎn)繞,有點(diǎn)抱歉,我再簡(jiǎn)化一下這個(gè)內(nèi)容。

網(wǎng)絡(luò)用語(yǔ)

「拋開(kāi)表象看本質(zhì)」

如果我們拋開(kāi)訪問(wèn)者模式這些專業(yè)的定義,單純的去理解這個(gè)訪問(wèn)者模式要表達(dá)的意思,我覺(jué)得用一個(gè)東西最合適不過(guò)。那就是“網(wǎng)絡(luò)用語(yǔ)”;

不知道大家聽(tīng)沒(méi)聽(tīng)過(guò)前陣子火了的百度廣告《你說(shuō)啥》單曲。歌曲中的朝陽(yáng)大媽就是一個(gè)不知道關(guān)注點(diǎn)或者是被限制了訪問(wèn)權(quán)限的訪問(wèn)者,當(dāng)然他歌曲中說(shuō)的網(wǎng)絡(luò)語(yǔ)有好多我也不知道是啥????。沒(méi)聽(tīng)過(guò)的快去聽(tīng)吧。

還有最近的 凡爾賽文學(xué) 我不百度的時(shí)候以為是個(gè)地名,所以我的 權(quán)限 也被限制了。

正好提到這個(gè)了,那我們就拿 凡爾賽文學(xué) 這個(gè)網(wǎng)絡(luò)語(yǔ)來(lái)學(xué)習(xí)一下訪問(wèn)者模式吧~???? 

凡爾賽文學(xué)

「首先我們就要再一次拋開(kāi)表象看本質(zhì)????」

下面是我搜集到有關(guān)凡爾賽的釋義:

  1. 凡爾賽是法國(guó)巴黎的衛(wèi)星城以及伊夫林省省會(huì),曾是法蘭西王朝的行政中心。
  2. 《凡爾賽》是皮埃爾·蘇勒?qǐng)?zhí)導(dǎo)的劇情片。
  3. 以法國(guó)路易十四為時(shí)代背景的電視劇。
  4. 凡爾賽文學(xué),網(wǎng)絡(luò)熱詞,指通過(guò)先抑后揚(yáng)、自問(wèn)自答或第三人稱視角,不經(jīng)意間露出"貴族生活的線索"。
  5. 啥???

對(duì)于凡爾賽一共有 5 種釋義,他的結(jié)構(gòu)應(yīng)該是這樣的

public class Versailles {

    private final String interpretation1 = "凡爾賽是法國(guó)巴黎的衛(wèi)星城以及伊夫林省省會(huì),曾是法蘭西王朝的行政中心。";
    private final String interpretation2 = "《凡爾賽》是皮埃爾·蘇勒?qǐng)?zhí)導(dǎo)的劇情片。";
    private final String interpretation3 = "以法國(guó)路易十四為時(shí)代背景的電視劇。";
    private final String interpretation4 = "凡爾賽文學(xué),網(wǎng)絡(luò)熱詞,指通過(guò)先抑后揚(yáng)、自問(wèn)自答或第三人稱視角,不經(jīng)意間露出\"貴族生活的線索\"。";
    private final String interpretation5 = "啥???";
    
}
 

因?yàn)槲覀冞€要對(duì)這個(gè)數(shù)據(jù)進(jìn)行訪問(wèn),所以還要給他加個(gè)訪問(wèn)的方法 #visit

public class Versailles {

   .....
       ....
       ...
    /*
     * 訪問(wèn)
     */
    public void visit(){

    }
}
 

既然要訪問(wèn),肯定要有訪問(wèn)者啊,因?yàn)樵L問(wèn)者挺多的,比如我、我的小伙伴、還有你。

所以我們就使用依賴倒置原則來(lái)定義一個(gè)訪問(wèn)者接口 Visitor 然后有個(gè)訪問(wèn)方法,再把凡爾賽給訪問(wèn)者去讓其自己訪問(wèn),那代碼實(shí)現(xiàn)起來(lái)應(yīng)該是這樣的。

Visitor接口

public interface Visitor {
    void visit(Versailles versailles);
}
 

凡爾賽的訪問(wèn)方法調(diào)整一下,最終完整類如下

public class Versailles {

    private final String interpretation1 = "凡爾賽是法國(guó)巴黎的衛(wèi)星城以及伊夫林省省會(huì),曾是法蘭西王朝的行政中心。";
    private final String interpretation2 = "《凡爾賽》是皮埃爾·蘇勒?qǐng)?zhí)導(dǎo)的劇情片。";
    private final String interpretation3 = "以法國(guó)路易十四為時(shí)代背景的電視劇。";
    private final String interpretation4 = "凡爾賽文學(xué),網(wǎng)絡(luò)熱詞,指通過(guò)先抑后揚(yáng)、自問(wèn)自答或第三人稱視角,不經(jīng)意間露出\"貴族生活的線索\"。";
    private final String interpretation5 = "啥???";

    /**
     * 將該對(duì)象提供給訪問(wèn)者訪問(wèn)
     * @param visitor 訪問(wèn)者
     * 方法名改成 accept 更好,表示這個(gè)類接受一個(gè)訪問(wèn)者來(lái)訪問(wèn)自己????
     */
    public void accept(Visitor visitor){
        visitor.visit(this);
    }
}
 

接下來(lái)就是具體的訪問(wèn)者了,那我根據(jù)實(shí)際情況來(lái)定義一些訪問(wèn)者

  1. I
  2. MyFriend
  3. You

一共三個(gè)訪問(wèn)者

「I」(我自己)

我比較博學(xué)多識(shí),我知道凡爾賽是地名、電影、電視劇三個(gè)

「MyFriend」(狗哥)

看他的樣子應(yīng)該是不知道

設(shè)計(jì)模式之什么是訪問(wèn)者模式  
狗哥一問(wèn)三不知

「You」(你呢?)

我就當(dāng)你知道凡爾賽文學(xué),已經(jīng)領(lǐng)悟到了無(wú)形裝逼的境界好了????

看下這三個(gè)類的情況

/**
 * 我比較博學(xué)多識(shí)
 * <p>
 * 歡迎跟我一起學(xué)習(xí),微信(lvgocc)公眾號(hào)搜索:星塵的一個(gè)朋友
 *
 * @author lvgorice@gmail.com
 * @version 1.0
 * @blog @see http://lvgo.org
 * @CSDN @see https://blog.csdn.net/sinat_34344123
 * @date 2020/12/1
 */
public class I implements Visitor {
    @Override
    public void visit(Versailles versailles) {
        System.out.println(versailles.getInterpretation1());
        System.out.println(versailles.getInterpretation2());
        System.out.println(versailles.getInterpretation3());
    }
}
// 弱智狗哥
public class MyFriend implements Visitor {
    @Override
    public void visit(Versailles versailles) {
        System.out.println(versailles.getInterpretation5());
    }
}
// 網(wǎng)絡(luò)達(dá)人
public class You implements Visitor {
    @Override
    public void visit(Versailles versailles) {
        System.out.println(versailles.getInterpretation4());
    }
}
 

最后我們?cè)谀M一下運(yùn)行起來(lái)的情況

class VisitorTest {

    @Test
    void visit() {
        Versailles versailles = new Versailles();

        System.out.println("lvgo 你知道凡爾賽嗎?");
        versailles.accept(new I());

        System.out.println("\n狗哥 你知道凡爾賽嗎?");
        versailles.accept(new MyFriend());
        
        System.out.println("\n你知道凡爾賽嗎?");
        versailles.accept(new You());
    }
}
 

結(jié)果,狗哥拉胯

lvgo 你知道凡爾賽嗎?
凡爾賽是法國(guó)巴黎的衛(wèi)星城以及伊夫林省省會(huì),曾是法蘭西王朝的行政中心。
《凡爾賽》是皮埃爾·蘇勒?qǐng)?zhí)導(dǎo)的劇情片。
以法國(guó)路易十四為時(shí)代背景的電視劇。

狗哥 你知道凡爾賽嗎?
啥???

你知道凡爾賽嗎?
凡爾賽文學(xué),網(wǎng)絡(luò)熱詞,指通過(guò)先抑后揚(yáng)、自問(wèn)自答或第三人稱視角,不經(jīng)意間露出"貴族生活的線索"。
 

不同的訪問(wèn)者,看到數(shù)據(jù)結(jié)構(gòu)中的結(jié)果不同。再來(lái)看下訪問(wèn)者的定義

在不改變集合元素的前提下,為一個(gè)集合中的每個(gè)元素提供多種訪問(wèn)方式,即每個(gè)元素有多個(gè)訪問(wèn)者對(duì)象訪問(wèn)。 

雖然我們這里用的是一個(gè)對(duì)象,試著將它變成集合(多個(gè)網(wǎng)絡(luò)語(yǔ)而已)吧。使用循環(huán)把每個(gè)元素都“送”給訪問(wèn)者,這個(gè)就留著給你動(dòng)手試試吧,也留給自己以后回來(lái)看的時(shí)候能被逼動(dòng)動(dòng)腦????。實(shí)在不想動(dòng),關(guān)注回復(fù) “源碼” 吧!???? 

訪問(wèn)者模式類圖 ????

最后,我們來(lái)看下標(biāo)準(zhǔn)的訪問(wèn)者模式結(jié)構(gòu)圖

設(shè)計(jì)模式之什么是訪問(wèn)者模式  
訪問(wèn)者類圖

這個(gè)結(jié)構(gòu)比較復(fù)雜

  1. 客戶端高層模塊     Client;
  2. 訪問(wèn)者接口,依賴倒置接口     Visitor;
  3. 被訪問(wèn)的元素,     Element
  4. 最后一個(gè),     ObjectStructure 對(duì)象結(jié)構(gòu);

這里唯一可能需要解釋的就是這個(gè) ObjectStructure 了,他即用于來(lái)定義管理 Element 的對(duì)象載體。它可以是我們業(yè)務(wù)場(chǎng)景中任何需要被訪問(wèn)元素的載體對(duì)象,比如上述例子中,我們想把這個(gè)結(jié)構(gòu)放進(jìn)去那我就可以定義一個(gè)詞語(yǔ)類 Word ,里面可以有 NetWordLanguage,Professional vocabulary 等等對(duì)象。如下所示

public class Word {

    /**
     * 網(wǎng)絡(luò)語(yǔ)
     */
    private final List<NetWordLanguage> netWordLanguages = new ArrayList<>();

    public void addWord(NetWordLanguage netWordLanguage) {
        if (!netWordLanguages.contains(netWordLanguage)){
            netWordLanguages.add(netWordLanguage);   
        }
    }
}
 
?  

訪問(wèn)者全部源代碼關(guān)注回復(fù) “源碼” 獲取

?    

“設(shè)計(jì)模式之什么是訪問(wèn)者模式”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI