最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS設(shè)計(jì)模式之訪問(wèn)者模式的用法詳解

 更新時(shí)間:2023年08月30日 09:52:47   作者:慕仲卿  
JS訪問(wèn)者模式是一種行為型設(shè)計(jì)模式,用于將算法與對(duì)象結(jié)構(gòu)分離, 該模式允許你定義新的操作(訪問(wèn)者)而無(wú)需修改現(xiàn)有對(duì)象結(jié)構(gòu)(被訪問(wèn)者), 通過(guò)這種方式,你可以在不改變對(duì)象結(jié)構(gòu)的情況下添加新的操作,本文就給大家詳細(xì)的講講JS訪問(wèn)者模式的用法

定義和特點(diǎn)

訪問(wèn)者模式是一種行為型設(shè)計(jì)模式,用于將算法與對(duì)象結(jié)構(gòu)分離。 該模式允許你定義新的操作(訪問(wèn)者)而無(wú)需修改現(xiàn)有對(duì)象結(jié)構(gòu)(被訪問(wèn)者)。 通過(guò)這種方式,你可以在不改變對(duì)象結(jié)構(gòu)的情況下添加新的操作。

參與者

在訪問(wèn)者模式中,有兩個(gè)主要角色:被訪問(wèn)者和訪問(wèn)者。

  • 被訪問(wèn)者:一個(gè)具有一組**元素和方法(method)**的對(duì)象結(jié)構(gòu)。
  • 訪問(wèn)者:一個(gè)能夠?qū)@些元素執(zhí)行不同**操作(visit)**的對(duì)象。
  • 被訪問(wèn)者提供了**接受(accept)**訪問(wèn)者的方法,以便訪問(wèn)者能夠在需要時(shí)訪問(wèn)元素。

使用流程

  • 首定義訪問(wèn)者接口,其中包含一組訪問(wèn)方法,每個(gè)方法對(duì)應(yīng)一種操作。
  • 在被訪問(wèn)者接口中添加一個(gè)接受訪問(wèn)者的方法accept,以便訪問(wèn)者可以訪問(wèn)被訪問(wèn)者的元素。
  • 被訪問(wèn)者的具體實(shí)現(xiàn)類需要實(shí)現(xiàn)這個(gè)接收訪問(wèn)者的方法,并**將自身作為參數(shù)(this)**傳遞給訪問(wèn)者的具體訪問(wèn)方法。
  • 創(chuàng)建一個(gè)具體的訪問(wèn)者對(duì)象v,并將其傳遞給被訪問(wèn)者的接受方法,即accept(v)
  • 被訪問(wèn)者將根據(jù)傳遞的訪問(wèn)者對(duì)象調(diào)用相應(yīng)的訪問(wèn)方法,從而執(zhí)行特定的操作。 通過(guò)這種【改變新建不同結(jié)構(gòu)的訪問(wèn)者,而不修改被訪問(wèn)者】的方式,你可以在不改變被訪問(wèn)者的結(jié)構(gòu)的情況下,為其添加新的操作。

通俗的理解

訪問(wèn)者設(shè)計(jì)模式有兩個(gè)部分完成,在實(shí)現(xiàn)不同目標(biāo)的過(guò)程中保持其中一方(被訪問(wèn)者)的結(jié)構(gòu)不變,只修改另外一方的結(jié)構(gòu)(訪問(wèn)者)。 也就是犧牲一個(gè)保全另外一個(gè)。

作用

訪問(wèn)者模式允許你將算法與對(duì)象結(jié)構(gòu)分離,并通過(guò)定義訪問(wèn)者接口和被訪問(wèn)者接口來(lái)實(shí)現(xiàn)多態(tài)性。 這種模式適用于需要對(duì)一個(gè)對(duì)象結(jié)構(gòu)中的元素進(jìn)行不同操作的場(chǎng)景,同時(shí)又希望保持對(duì)象結(jié)構(gòu)的穩(wěn)定性。

舉例

// 被訪問(wèn)者接口:點(diǎn)心店
interface Bakery {
  accept(visitor: CustomerVisitor): void;
  make(): string;
  makePlus(): string;
}
// 具體的被訪問(wèn)者:圓點(diǎn)心店
class CirclePastry implements Bakery {
  // 被訪問(wèn)者的接受方法
  accept(visitor: CustomerVisitor): void {
    // 將自身作為參數(shù)(this)傳遞給訪問(wèn)者的具體訪問(wèn)方法
    visitor?.visitCirclePastry(this);
  }
  make(): string {
    return "制作圓點(diǎn)心";
  }
  makePlus(): string {
    return "制作精品圓點(diǎn)心";
  }
}
// 具體的被訪問(wèn)者:方點(diǎn)心店
class SquarePastry implements Bakery {
  accept(visitor: CustomerVisitor): void {
    visitor?.visitSquarePastry(this);
  }
  make(): string {
    return "制作方點(diǎn)心";
  }
  makePlus(): string {
    return "制作精品方點(diǎn)心";
  }
}
// 訪問(wèn)者接口:顧客
interface CustomerVisitor {
  visitCirclePastry(pastry: CirclePastry): void;
  visitSquarePastry(pastry: SquarePastry): void;
}
// 具體的訪問(wèn)者:點(diǎn)心愛(ài)好者
class PastryLover implements CustomerVisitor {
  visitCirclePastry(pastry: CirclePastry): void {
    console.log(`點(diǎn)心愛(ài)好者選擇了${pastry.make()}`);
  }
  visitSquarePastry(pastry: SquarePastry): void {
    console.log(`點(diǎn)心愛(ài)好者選擇了${pastry.make()}`);
  }
}
// 使用示例
const circlePastry: Bakery = new CirclePastry();
const squarePastry: Bakery = new SquarePastry();
const pastryLover: CustomerVisitor = new PastryLover();
circlePastry.accept(pastryLover); // 輸出:點(diǎn)心愛(ài)好者選擇了制作圓點(diǎn)心
squarePastry.accept(pastryLover); // 輸出:點(diǎn)心愛(ài)好者選擇了制作方點(diǎn)心
// 在保證被訪問(wèn)者結(jié)構(gòu)的不變的前提下通過(guò)修改訪問(wèn)者的結(jié)構(gòu)達(dá)到完成不同操作的目的
// 訪問(wèn)者接口:高級(jí)顧客
interface CustomerVisitorPlus {
  visitCirclePastry(pastry: CirclePastry): void;
  visitSquarePastry(pastry: SquarePastry): void;
}
// 具體的訪問(wèn)者:高級(jí)點(diǎn)心愛(ài)好者
class PastryLoverWithMoney implements CustomerVisitorPlus {
  visitCirclePastry(pastry: CirclePastry): void {
    console.log(`點(diǎn)心愛(ài)好者選擇了${pastry.makePlus()}`);
  }
  visitSquarePastry(pastry: SquarePastry): void {
    console.log(`點(diǎn)心愛(ài)好者選擇了${pastry.makePlus()}`);
  }
}
const pastryLoverWithMoney: PastryLoverWithMoney = new PastryLoverWithMoney();
circlePastry.accept(pastryLoverWithMoney); // 輸出:點(diǎn)心愛(ài)好者選擇了制作高級(jí)圓點(diǎn)心
squarePastry.accept(pastryLoverWithMoney); // 輸出:點(diǎn)心愛(ài)好者選擇了制作高級(jí)方點(diǎn)心
// 可以看出來(lái)circlePastry和squarePastry都被復(fù)用了

Babel插件中的使用

在 Babel 插件中修改 AST(抽象語(yǔ)法樹(shù))時(shí),通常會(huì)使用訪問(wèn)者模式。

  • 定義訪問(wèn)者:定義一個(gè)訪問(wèn)者對(duì)象,該對(duì)象包含用于處理不同類型的 AST 節(jié)點(diǎn)的方法。每個(gè)方法對(duì)應(yīng)一種 AST 節(jié)點(diǎn)類型,該方法將被調(diào)用以訪問(wèn)和處理相應(yīng)類型的節(jié)點(diǎn)。
  • 遍歷和修改 AST:通過(guò)使用 Babel 提供的遍歷器(@babel/traverse),可以遍歷整個(gè) AST。在遍歷過(guò)程中,對(duì)于每個(gè)訪問(wèn)到的節(jié)點(diǎn),將根據(jù)節(jié)點(diǎn)的類型調(diào)用相應(yīng)的訪問(wèn)者方法。
  • 修改 AST:在訪問(wèn)者方法中,您可以對(duì) AST 進(jìn)行修改。這可以涉及更改節(jié)點(diǎn)屬性、替換節(jié)點(diǎn)、添加新節(jié)點(diǎn)等操作。通過(guò)修改 AST,插件可以實(shí)現(xiàn)源代碼的轉(zhuǎn)換和重寫(xiě)。

應(yīng)用場(chǎng)景

  • DOM 操作:在瀏覽器中,DOM(文檔對(duì)象模型)表示網(wǎng)頁(yè)的結(jié)構(gòu)和內(nèi)容。使用訪問(wèn)者模式,您可以定義一個(gè)訪問(wèn)者對(duì)象,該對(duì)象可以遍歷 DOM 樹(shù)的節(jié)點(diǎn),并執(zhí)行相應(yīng)的操作。例如,可以創(chuàng)建一個(gè)訪問(wèn)者來(lái)查找特定類型的節(jié)點(diǎn)、修改節(jié)點(diǎn)屬性或樣式,或執(zhí)行其他與 DOM 相關(guān)的操作。
  • 數(shù)據(jù)結(jié)構(gòu)操作:JavaScript 中有許多內(nèi)置的數(shù)據(jù)結(jié)構(gòu),如數(shù)組、集合、映射等。通過(guò)使用訪問(wèn)者模式,您可以定義一個(gè)訪問(wèn)者對(duì)象,來(lái)對(duì)這些數(shù)據(jù)結(jié)構(gòu)進(jìn)行遍歷和操作。例如,可以創(chuàng)建一個(gè)訪問(wèn)者來(lái)計(jì)算數(shù)組中的總和、過(guò)濾符合特定條件的元素,或者將映射轉(zhuǎn)換為另一種形式。
  • 編譯器和解析器:在編譯器和解析器中,訪問(wèn)者模式經(jīng)常被用來(lái)處理抽象語(yǔ)法樹(shù)(AST)。通過(guò)定義訪問(wèn)者對(duì)象,可以遍歷 AST 并執(zhí)行各種語(yǔ)義分析、優(yōu)化或代碼生成操作。這樣可以將復(fù)雜的編譯器邏輯分離到不同的訪問(wèn)者方法中,使其更易于維護(hù)和擴(kuò)展。
  • 事件處理:在瀏覽器中,事件處理是非常常見(jiàn)的任務(wù)。訪問(wèn)者模式可以用于處理不同類型的事件,并執(zhí)行相應(yīng)的操作。例如,可以創(chuàng)建一個(gè)訪問(wèn)者來(lái)處理鼠標(biāo)事件、鍵盤(pán)事件或其他用戶交互事件。
  • 數(shù)據(jù)校驗(yàn)和驗(yàn)證:當(dāng)需要對(duì)數(shù)據(jù)進(jìn)行復(fù)雜的校驗(yàn)和驗(yàn)證時(shí),訪問(wèn)者模式可以提供一種結(jié)構(gòu)化的方法。您可以定義一個(gè)訪問(wèn)者對(duì)象,該對(duì)象遍歷數(shù)據(jù)結(jié)構(gòu)并執(zhí)行各種校驗(yàn)邏輯。這樣可以將校驗(yàn)邏輯從數(shù)據(jù)結(jié)構(gòu)中分離出來(lái),使其更加可維護(hù)和可擴(kuò)展。

以上就是JS設(shè)計(jì)模式之訪問(wèn)者模式的用法詳解的詳細(xì)內(nèi)容,更多關(guān)于JS訪問(wèn)者模式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • JavaScript中btoa和atob全局函數(shù)示例詳解

    JavaScript中btoa和atob全局函數(shù)示例詳解

    這篇文章主要給大家介紹了關(guān)于JavaScript中btoa和atob全局函數(shù)的相關(guān)資料,atob和btoa是window對(duì)象的兩個(gè)函數(shù),用來(lái)編碼解碼Base64,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-08-08
  • js將字符串中的每一個(gè)單詞的首字母變?yōu)榇髮?xiě)其余均為小寫(xiě)

    js將字符串中的每一個(gè)單詞的首字母變?yōu)榇髮?xiě)其余均為小寫(xiě)

    本文主要介紹了javascript將字符串中的每一個(gè)單詞的首字母變?yōu)榇髮?xiě)其余均為小寫(xiě)的方法。具有一定的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-01-01
  • JavaScript 圖片放大鏡(可拖放、縮放效果)

    JavaScript 圖片放大鏡(可拖放、縮放效果)

    背景:很久之前就在marry5.com看到這個(gè)效果,當(dāng)時(shí)覺(jué)得很神奇,礙于水平有限,沒(méi)做出來(lái)。
    2008-09-09
  • JavaScript本地存儲(chǔ)的幾種方式小結(jié)

    JavaScript本地存儲(chǔ)的幾種方式小結(jié)

    在 JavaScript 中,本地存儲(chǔ)指的是將數(shù)據(jù)保存在用戶的瀏覽器中,能夠在頁(yè)面刷新或關(guān)閉后仍然保留,本文給大家介紹了本地存儲(chǔ)的幾種方式,每種存儲(chǔ)方式的特點(diǎn)、區(qū)別及應(yīng)用場(chǎng)景,需要的朋友可以參考下
    2024-12-12
  • 深入學(xué)習(xí)JavaScript中的promise

    深入學(xué)習(xí)JavaScript中的promise

    這篇文章主要介紹了深入學(xué)習(xí)JavaScript中的promise,Promise對(duì)象的主要?途是通過(guò)鏈?zhǔn)秸{(diào)?的結(jié)構(gòu),將原本回調(diào)嵌套的異步處理流程,轉(zhuǎn)化成“對(duì)象.then().then()...”的鏈?zhǔn)浇Y(jié)構(gòu)
    2022-06-06
  • js實(shí)現(xiàn)拖拽功能

    js實(shí)現(xiàn)拖拽功能

    本文主要介紹了js實(shí)現(xiàn)拖拽效果的實(shí)例,具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-03-03
  • 詳解JavaScript 浮點(diǎn)數(shù)運(yùn)算的精度問(wèn)題

    詳解JavaScript 浮點(diǎn)數(shù)運(yùn)算的精度問(wèn)題

    這篇文章主要介紹了詳解JavaScript 浮點(diǎn)數(shù)運(yùn)算的精度問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • JavaScript實(shí)現(xiàn)二叉樹(shù)定義、遍歷及查找的方法詳解

    JavaScript實(shí)現(xiàn)二叉樹(shù)定義、遍歷及查找的方法詳解

    這篇文章主要介紹了JavaScript實(shí)現(xiàn)二叉樹(shù)定義、遍歷及查找的方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了二叉樹(shù)的相關(guān)概念及javascript構(gòu)建二叉樹(shù)、遍歷、查找二叉樹(shù)的常用操作技巧,需要的朋友可以參考下
    2017-12-12
  • JavaScript給每一個(gè)li節(jié)點(diǎn)綁定點(diǎn)擊事件的實(shí)現(xiàn)方法

    JavaScript給每一個(gè)li節(jié)點(diǎn)綁定點(diǎn)擊事件的實(shí)現(xiàn)方法

    這篇文章主要介紹了JavaScript給每一個(gè)li節(jié)點(diǎn)綁定點(diǎn)擊事件的實(shí)現(xiàn)方法,包括js循環(huán)給li綁定參數(shù)不同的點(diǎn)擊事件,需要的朋友可以參考下
    2016-12-12
  • JS實(shí)現(xiàn)固定時(shí)間點(diǎn)執(zhí)行某任務(wù)的代碼示例

    JS實(shí)現(xiàn)固定時(shí)間點(diǎn)執(zhí)行某任務(wù)的代碼示例

    在Web前端開(kāi)發(fā)中,有時(shí)我們需要在特定的時(shí)間點(diǎn)執(zhí)行某些任務(wù),例如每日定時(shí)發(fā)送數(shù)據(jù)報(bào)告、每小時(shí)更新一次用戶界面等,JavaScript 提供了多種方法來(lái)實(shí)現(xiàn)這一需求,本文將詳細(xì)介紹如何使用這些工具和技術(shù),并通過(guò)豐富的代碼示例展示其具體應(yīng)用,需要的朋友可以參考下
    2025-02-02

最新評(píng)論

泸西县| 天祝| 永兴县| 隆化县| 桃江县| 酉阳| 东安县| 新民市| 武强县| 龙里县| 大悟县| 南部县| 柏乡县| 石林| 崇左市| 米易县| 内丘县| 鄱阳县| 峨山| 扬州市| 军事| 吴堡县| 延边| 福海县| 苍山县| 河曲县| 上蔡县| 哈尔滨市| 札达县| 郎溪县| 阜康市| 抚远县| 绍兴市| 渝中区| 车险| 九江市| 天柱县| 盈江县| 武汉市| 东乡县| 冷水江市|