国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

第二十一章行為性模式—訪問者模式

這篇具有很好參考價值的文章主要介紹了第二十一章行為性模式—訪問者模式。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。


行為型模式用于描述程序在運行時復雜的流程控制,即描述多個類或對象之間怎樣相互協(xié)作共同完成單個對象無法單獨完成的任務,它涉及算法與對象間職責的分配。行為型模式分為類行為模式和對象行為模式:
  • 類行為模式:采用繼承機制來在類間分派行為

  • 對象行為模式:采用組合或聚合在對象間分配行為

由于組合關系或聚合關系比繼承關系耦合度低,滿足“合成復用原則”,所以對象行為模式比類行為模式具有更大的靈活性。

行為型模式分為:

  • 模板方法模式
  • 策略模式
  • 命令模式
  • 職責鏈模式
  • 狀態(tài)模式
  • 觀察者模式
  • 中介者模式
  • 迭代器模式
  • 訪問者模式
  • 備忘錄模式
  • 解釋器模式

以上 11 種行為型模式,除了模板方法模式解釋器模式是類行為型模式,其他的全部屬于對象行為型模式。

訪問者模式

訪問者模式:訪問者模式,用于封裝一些作用于某種數(shù)據(jù)結構中的各元素的操作,它可以在不改變數(shù)據(jù)結構的前提下定義作用于這些元素的新操作

解決的問題

在之前有一則新聞,一個爺爺給孫子買學習機器人,本以為是一個智能機器人,但是買回來之后發(fā)現(xiàn)是一個1+1=1的傻蛋機器人,爺爺就找到經(jīng)銷商來質(zhì)問,經(jīng)銷商說哦,不講武德,這個機器人的系統(tǒng)版本太低,需要系統(tǒng)版本升級

第二十一章行為性模式—訪問者模式

  • 這個軟件升級,其機器人的硬件是不會變的,這個軟件包中包含新的指令,使機器人能完成更多功能,之所以這個升級包能完成升級的原因是因為這個系統(tǒng)升級版能夠訪問這個機器人中的硬件,然后利用這些硬件資源去完成新的指令

結構

  • Visitor:抽象訪問者角色,定義了對每一個元素 Element 訪問的行為,它的參數(shù)就是可以訪問的元素,它的方法個數(shù)理論上來講與元素類個數(shù)(Element 的實現(xiàn)類個數(shù))是一樣的,從這點不難看出,訪問者模式要求元素類的個數(shù)不能改變。
  • ConcreteVisitor:具體訪問者角色,給出對每一個元素類訪問時所產(chǎn)生的具體行為。
  • Element:抽象元素角色,定義了一個接受訪問者的方法(accept),其意義是指,每一個元素都要可以被訪問者訪問。
  • ConcreteElement:具體元素角色, 提供接受訪問方法的具體實現(xiàn),而這個具體的實現(xiàn),通常情況下是使用訪問者提供的訪問該元素類的方法。
  • Object Structure:對象結構角色,定義當中所提到的對象結構,對象結構是一個抽象表述,具體點可以理解為一個具有容器性質(zhì)或者復合對象特性的類,它會含有一組元素(Element),并且可以迭代這些元素,供訪問者訪問。

實例

機器人版本升級案例

抽象元素角色

public abstract class Hardware {
    //指令
    String common;

    public Hardware(String common) {
        this.common = common;
    }
    public void run(){
        System.out.println(common);
    }
    public abstract void accept();
}

具體元素角色

public class CPU extends Hardware{
    public CPU(String common) {
        super(common);
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visitCPU(this);
    }
}
public class HardDisk extends Hardware{
    public HardDisk(String common) {
        super(common);
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visitHardDisk(this);
    }
}

抽象訪問者角色

public interface Visitor {
    void visitCPU(CPU cpu);
    void visitHardDisk(HardDisk hardDisk);
}

具體訪問者角色

public class UpdateVisitor implements Visitor {
    @Override
    public void visitCPU(CPU cpu) {
        cpu.common+=": 1+1=2";
    }

    @Override
    public void visitHardDisk(HardDisk hardDisk) {
        hardDisk.common+=": 記住: 1+1=2";
    }
}

對象結構角色

public class EggRobot {
    private HardDisk disk;
    private CPU cpu;

    public EggRobot() {
        this.disk = new HardDisk("記住 1+1=1");
        this.cpu = new CPU("1+1=1");
    }
    public void calc(){
        cpu.run();
        disk.run();
    }
    public void accept(Visitor visitor){
        cpu.accept(visitor);
        disk.accept(visitor);
    }
}

訪問者模式:訪問者模式,用于封裝一些作用于某種數(shù)據(jù)結構中的各元素的操作,它可以在不改變數(shù)據(jù)結構的前提下定義作用于這些元素的新操作

  • 某種數(shù)據(jù)結構指的就是對象結構角色也就是我們的機器人蠢蛋
  • 各元素指的就是具體元素角色,也就是我們的機器人的各個硬件比如CPU,硬盤
  • 我們定義了訪問者類,封裝了新的操作,不需要改變數(shù)據(jù)結構,通過具體元素角色(硬件)暴露方法,不改變數(shù)據(jù)結構(機器人)的情況下,讓其訪問數(shù)據(jù)結構中的具體元素,來實現(xiàn)新的操作

存在的問題

優(yōu)點:

擴展性好

  • 在不修改對象結構中的元素的情況下,為對象結構中的元素添加新的功能。

復用性好

  • 通過訪問者來定義整個對象結構通用的功能,從而提高復用程度。

分離無關行為

  • 通過訪問者來分離無關的行為,把相關的行為封裝在一起,構成一個訪問者,這樣每一個訪問者的功能都比較單一。

缺點:

對象結構變化很困難

  • 在訪問者模式中,每增加一個新的元素類,都要在每一個具體訪問者類中增加相應的具體操作,這違背了 “開閉原則”。

違反了依賴倒置原則

  • 訪問者模式依賴了具體類,而沒有依賴抽象類。

使用場景

  • 對象結構相對穩(wěn)定,但其操作算法經(jīng)常變化的程序。
  • 對象結構中的對象需要提供多種不同且不相關的操作,而且要避免讓這些操作的變化影響對象的結構。

拓展

訪問者模式用到了一種雙分派的技術。

分派:變量被聲明時的類型叫做變量的靜態(tài)類型(也被叫做明顯類型);而變量所引用的對象的真實類型又叫做變量的實際類型。

  • 比如 Map map = new HashMap() ,map 變量的靜態(tài)類型是 Map ,實際類型是 HashMap 。

根據(jù)對象的類型而對方法進行的選擇,就是分派 (Dispatch),分派又分為兩種:

  • 動態(tài)分派 (Dynamic Dispatch) 發(fā)生在運行時期,動態(tài)分派動態(tài)地置換掉某個方法,Java 通過方法的重寫支持動態(tài)分派。

  • 靜態(tài)分派 (Static Dispatch) 發(fā)生在編譯時期,分派根據(jù)靜態(tài)類型信息發(fā)生,方法重載就是靜態(tài)分派。

動態(tài)分派

通過方法重寫支持動態(tài)分派。

public class Animal {
    public void execute() {
        System.out.println("Animal");
    }
}

public class Dog extends Animal {
    @Override
    public void execute() {
        System.out.println("dog");
    }
}

public class Cat extends Animal {
     @Override
    public void execute() {
        System.out.println("cat");
    }
}

public class Client {
   	public static void main(String[] args) {
        Animal a = new Animal();
        a.execute();
      

    Animal d = new Dog();
    d.execute();
    
    Animal c = new Cat();
    c.execute();
}

}
animal
dog
cat

上面的代碼就是簡單的多態(tài)

Java 編譯器在編譯時期并不總是知道哪些代碼會被執(zhí)行,因為編譯器僅僅知道對象的靜態(tài)類型,而不知道對象的真實類型;而方法的調(diào)用則是根據(jù)對象的真實類型,而不是靜態(tài)類型。

靜態(tài)分派

通過方法重載支持靜態(tài)分派。

public class Animal {}

public class Dog extends Animal {}

public class Cat extends Animal {}

public class Execute {
    public void execute(Animal a) {
        System.out.println("Animal");
    }
    public void execute(Dog d) {
        System.out.println("dog");
    }
    public void execute(Cat c) {
        System.out.println("cat");
    }
}

public class Client {
    public static void main(String[] args) {
        Animal a = new Animal();
        Animal a1 = new Dog();
        Animal a2 = new Cat();
				// 靜態(tài)分派根據(jù)靜態(tài)類型決定
        Execute exe = new Execute();
        exe.execute(a);
        exe.execute(a1);
        exe.execute(a2);
    }
}

運行結果:

animal
animal
animal

這個結果可能出乎一些人的意料了,為什么呢?

重載方法的分派是根據(jù)靜態(tài)類型進行的,這個分派過程在編譯時期就完成了。

雙分派

所謂雙分派技術就是在選擇一個方法的時候,不僅僅要根據(jù)消息接收者的運行時區(qū)別,還要根據(jù)參數(shù)的運行時區(qū)別。

public class Animal {
    public void accept(Execute exe) {
        // 2.傳遞了this給Execute,根據(jù)靜態(tài)類型進行方法重載實現(xiàn)靜態(tài)分派
        exe.execute(this);
    }
}

public class Dog extends Animal {
    public void accept(Execute exe) {
        exe.execute(this);
    }
}

public class Cat extends Animal {
    public void accept(Execute exe) {
        exe.execute(this);
    }
}

public class Execute {
    public void execute(Animal a) {
        System.out.println("animal");
    }
    public void execute(Dog d) {
        System.out.println("dog");
    }
    public void execute(Cat c) {
        System.out.println("cat");
    }
}

public class Client {
    public static void main(String[] args) {
        Animal a = new Animal();
        Animal d = new Dog();
        Animal c = new Cat();

?    Execute exe = new Execute();
  	// 1.exe傳遞給Animal類型的變量調(diào)用,方法重寫實現(xiàn)動態(tài)分派
?    a.accept(exe);
?    d.accept(exe);
?    c.accept(exe);
}

}
animal
dog
cat

上面代碼中:

  • 客戶端將 Execute 的對象做為參數(shù)傳遞給 Animal 類型的變量調(diào)用的方法,這里完成第一次分派,這里是方法重寫,所以是動態(tài)分派,也就是執(zhí)行實際類型中的方法;

  • 同時也將自己 this 作為參數(shù)傳遞進去,這里就完成了第二次分派,這里的 Execute 類中有多個重載方法,而傳遞進行的是 this,就是具體的實際類型的對象,所以是靜態(tài)分派。

  • 雙分派實現(xiàn)動態(tài)綁定的本質(zhì):在重載方法委派的前面加上了繼承體系中覆蓋的環(huán)節(jié),由于覆蓋是動態(tài)的,所以重載就是動態(tài)的了。

理解:文章來源地址http://www.zghlxwxcb.cn/news/detail-468104.html

  • 1、動態(tài)分派要達到的效果是正確的,分別輸出 a、b、c,但是實現(xiàn)每個對象的方法都寫在其各自的類中,不好維護,它的實現(xiàn)過程不行。
  • 2、靜態(tài)分派的這種實現(xiàn)過程是比較好的,沒有把輸出 a、b、c 的操作耦合到各自的類中,而是統(tǒng)一在 Execute 中維護執(zhí)行,但是卻沒有達到想要的效果。。
  • 3、所以也就有了雙分派,同樣是將執(zhí)行過程放在 Execute 中管理,最后也達到了想要的效果,輸出結果為 a、b、c。其實現(xiàn)方法其實就是在各個類中依賴了 Execute,再將自己 this 傳遞過去,從而實現(xiàn)在 Execute 操作的目的。

到了這里,關于第二十一章行為性模式—訪問者模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 第二十一章 Classes

    類定義并不是 ObjectScript 的正式組成部分。相反,可以在類定義的特定部分中使用 ObjectScript (特別是在方法定義中,可以在其中使用其他實現(xiàn)語言)。 每個 IRIS 類都有一個名稱,該名稱在定義它的命名空間中必須是唯一的。完整的類名是由一個或多個句點分隔的字符串,如

    2024年02月09日
    瀏覽(35)
  • 第二十一章 Unity 光源

    第二十一章 Unity 光源

    光源是每個場景必不可少的部分,光源除了能夠照亮場景之外,還可以產(chǎn)生陰影效果。 Unity中分為四種 光源類型 : 1. 方向光:Directional Light 用于模擬太陽光,方向光任何地方都能照射到。 2. 點光源:Point Light 用于模擬電燈泡的照射效果。 3. 聚光燈:Spot Light 用于模擬聚光燈

    2024年02月16日
    瀏覽(31)
  • 第二十一章網(wǎng)絡通信

    第二十一章網(wǎng)絡通信

    網(wǎng)絡程序設計基礎 局域網(wǎng)與互聯(lián)網(wǎng) 為了實現(xiàn)兩臺計算機的通信,必須用一個網(wǎng)絡線路連接兩臺計算機。如下圖所示 ?網(wǎng)絡協(xié)議 1.IP協(xié)議 IP是Internet Protocol的簡稱,是一種網(wǎng)絡協(xié)議。Internet 網(wǎng)絡采用的協(xié)議是TCP/IP協(xié)議,其全稱是Transmission Control Protocol/Internet Protocol。Internet 依靠

    2024年02月05日
    瀏覽(31)
  • 【Three.js】第二十一章 Physics 物理

    【Three.js】第二十一章 Physics 物理

    物理是WebGL可以添加到項目體驗中最酷的功能之一。人們喜歡真實物理感的物體,看到它們碰撞、倒塌、墜落和彈跳,就像我的作品集一樣: https: //bruno-simon.com/ 有很多方法可以將物理功能添加到您的項目中,這取決于您想要實現(xiàn)的目標。您可以使用一些數(shù)學和解決方案(例

    2024年02月09日
    瀏覽(26)
  • 第二十一章 : Spring Boot 集成RabbitMQ(五)

    第二十一章 : Spring Boot 集成RabbitMQ(五) 前言 本章知識點: 如何保證消息100%可靠性發(fā)送的技術解決方案。 一、 應用場景 在使用消息隊列時,因為生產(chǎn)者和消費者不直接交互,所以面臨下面幾個問題: 1)要把消息添加到隊列中,怎么保證消息成功添加? 2)如何保證消息

    2024年02月03日
    瀏覽(20)
  • UCB Data100:數(shù)據(jù)科學的原理和技巧:第二十一章到第二十六章

    UCB Data100:數(shù)據(jù)科學的原理和技巧:第二十一章到第二十六章

    原文:SQL II 譯者:飛龍 協(xié)議:CC BY-NC-SA 4.0 學習成果 介紹過濾組的能力 在 SQL 中執(zhí)行數(shù)據(jù)清理和文本操作 跨表連接數(shù)據(jù) 在本講座中,我們將繼續(xù)上次的工作,介紹一些高級的 SQL 語法。 首先,讓我們加載上一堂課的數(shù)據(jù)庫。 HAVING 通過在每個組的所有行上應用一些條件來過

    2024年01月21日
    瀏覽(99)
  • 第二十一章 Prim算法與Kruskal算法(通俗證明與詳細講解)

    第二十一章 Prim算法與Kruskal算法(通俗證明與詳細講解)

    我們先解釋一下什么是最小生成樹。 這個概念是基于圖的,如果說存在一條路線串通起來了所有的點,那么這條路線就叫做生成樹。而在這些路線中最短的那一條就叫做最小生成樹。 如上圖所示,圖中的紅色路線就是一個生成樹,假設這條紅色路線是眾多生成樹路線中最小

    2024年02月11日
    瀏覽(30)
  • Chrome 開發(fā)者工具 第二十一章(替換 Web 內(nèi)容和 HTTP 響應)

    Chrome 開發(fā)者工具 第二十一章(替換 Web 內(nèi)容和 HTTP 響應)

    Chrome 開發(fā)者工具的本地替換功能是一個強大的工具,它允許開發(fā)者在不修改服務器代碼的情況下模擬前端更改。這個功能特別適用于那些需要快速測試前端更改,但又不想或不能等待后端更新的情況。 本地替換的工作原理 本地替換通過在開發(fā)者工具中進行更改,并將這些更

    2024年02月22日
    瀏覽(21)
  • 《HeadFirst設計模式(第二版)》第十一章代碼——代理模式

    《HeadFirst設計模式(第二版)》第十一章代碼——代理模式

    代碼文件目錄: ?RMI: MyRemote MyRemoteClient MyRemoteImpl 能夠遠程監(jiān)控的糖果機: 在上一章的代碼的基礎上做一些修改 GumballMachine GumballMachineRemote GumballMachineTestDrive GumballMonitor GumballMonitorTestDrive 五個狀態(tài)類: 同樣的修改:

    2024年02月12日
    瀏覽(29)
  • 第二十一章:CCNet:Criss-Cross Attention for Semantic Segmentation ——用于語義分割的交叉注意力

    第二十一章:CCNet:Criss-Cross Attention for Semantic Segmentation ——用于語義分割的交叉注意力

    原文題目:《CCNet:Criss-Cross Attention for Semantic Segmentation?》 原文引用:Huang Z, Wang X, Huang L, et al. Ccnet: Criss-cross attention for semantic segmentation[C]//Proceedings of the IEEE/CVF international conference on computer vision. 2019: 603-612. 原文鏈接: https://openaccess.thecvf.com/content_ICCV_2019/papers/Huang_CCNet_Criss

    2024年02月16日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包