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

Go設(shè)計(jì)模式之代理模式圖文詳解

 更新時(shí)間:2023年07月24日 08:31:56   作者:demo007x  
這篇文章將通過(guò)圖文講解給大家詳細(xì)的介紹一下Go代理模式,代理模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,代理控制著對(duì)于原對(duì)象的訪問(wèn), 并允許在將請(qǐng)求提交給對(duì)象前后進(jìn)行一些處理,感興趣的同學(xué)跟著小編一起來(lái)看看吧

代理模式

亦稱: Proxy

代理模式是一種結(jié)構(gòu)型設(shè)計(jì)模式, 讓你能夠提供對(duì)象的替代品或其占位符。 代理控制著對(duì)于原對(duì)象的訪問(wèn), 并允許在將請(qǐng)求提交給對(duì)象前后進(jìn)行一些處理。

問(wèn)題

為什么要控制對(duì)于某個(gè)對(duì)象的訪問(wèn)呢? 舉個(gè)例子: 有這樣一個(gè)消耗大量系統(tǒng)資源的巨型對(duì)象, 你只是偶爾需要使用它, 并非總是需要。

數(shù)據(jù)庫(kù)查詢有可能會(huì)非常緩慢。

你可以實(shí)現(xiàn)延遲初始化: 在實(shí)際有需要時(shí)再創(chuàng)建該對(duì)象。 對(duì)象的所有客戶端都要執(zhí)行延遲初始代碼。 不幸的是, 這很可能會(huì)帶來(lái)很多重復(fù)代碼。

在理想情況下, 我們希望將代碼直接放入對(duì)象的類中, 但這并非總是能實(shí)現(xiàn): 比如類可能是第三方封閉庫(kù)的一部分。

解決方案

代理模式建議新建一個(gè)與原服務(wù)對(duì)象接口相同的代理類, 然后更新應(yīng)用以將代理對(duì)象傳遞給所有原始對(duì)象客戶端。 代理類接收到客戶端請(qǐng)求后會(huì)創(chuàng)建實(shí)際的服務(wù)對(duì)象, 并將所有工作委派給它。

代理將自己偽裝成數(shù)據(jù)庫(kù)對(duì)象, 可在客戶端或?qū)嶋H數(shù)據(jù)庫(kù)對(duì)象不知情的情況下處理延遲初始化和緩存查詢結(jié)果的工作。

這有什么好處呢? 如果需要在類的主要業(yè)務(wù)邏輯前后執(zhí)行一些工作, 你無(wú)需修改類就能完成這項(xiàng)工作。 由于代理實(shí)現(xiàn)的接口與原類相同, 因此你可將其傳遞給任何一個(gè)使用實(shí)際服務(wù)對(duì)象的客戶端。

真實(shí)世界類比

信用卡和現(xiàn)金在支付過(guò)程中的用處相同。

信用卡是銀行賬戶的代理, 銀行賬戶則是一大捆現(xiàn)金的代理。 它們都實(shí)現(xiàn)了同樣的接口, 均可用于進(jìn)行支付。 消費(fèi)者會(huì)非常滿意, 因?yàn)椴槐仉S身攜帶大量現(xiàn)金; 商店老板同樣會(huì)十分高興, 因?yàn)榻灰资杖肽芤噪娮踊姆绞竭M(jìn)入商店的銀行賬戶中, 無(wú)需擔(dān)心存款時(shí)出現(xiàn)現(xiàn)金丟失或被搶劫的情況。

代理模式結(jié)構(gòu)

  • 服務(wù)接口 (Service Interface) 聲明了服務(wù)接口。 代理必須遵循該接口才能偽裝成服務(wù)對(duì)象。

  • 服務(wù) (Service) 類提供了一些實(shí)用的業(yè)務(wù)邏輯。

  • 代理 (Proxy) 類包含一個(gè)指向服務(wù)對(duì)象的引用成員變量。 代理完成其任務(wù) (例如延遲初始化、 記錄日志、 訪問(wèn)控制和緩存等) 后會(huì)將請(qǐng)求傳遞給服務(wù)對(duì)象。

    通常情況下, 代理會(huì)對(duì)其服務(wù)對(duì)象的整個(gè)生命周期進(jìn)行管理。

  • 客戶端 (Client) 能通過(guò)同一接口與服務(wù)或代理進(jìn)行交互, 所以你可在一切需要服務(wù)對(duì)象的代碼中使用代理。

偽代碼

本例演示如何使用代理模式在第三方騰訊視頻 (TencentVideo, 代碼示例中記為 TV) 程序庫(kù)中添加延遲初始化和緩存。

使用代理緩沖服務(wù)結(jié)果。

程序庫(kù)提供了視頻下載類。 但是該類的效率非常低。 如果客戶端程序多次請(qǐng)求同一視頻, 程序庫(kù)會(huì)反復(fù)下載該視頻, 而不會(huì)將首次下載的文件緩存下來(lái)復(fù)用。

代理類實(shí)現(xiàn)和原下載器相同的接口, 并將所有工作委派給原下載器。 不過(guò), 代理類會(huì)保存所有的文件下載記錄, 如果程序多次請(qǐng)求同一文件, 它會(huì)返回緩存的文件。

// 遠(yuǎn)程服務(wù)接口。
interface ThirdPartyTVLib is
    method listVideos()
    method getVideoInfo(id)
    method downloadVideo(id)
// 服務(wù)連接器的具體實(shí)現(xiàn)。該類的方法可以向騰訊視頻請(qǐng)求信息。請(qǐng)求速度取決于
// 用戶和騰訊視頻的互聯(lián)網(wǎng)連接情況。如果同時(shí)發(fā)送大量請(qǐng)求,即使所請(qǐng)求的信息
// 一模一樣,程序的速度依然會(huì)減慢。
class ThirdPartyTVClass implements ThirdPartyTVLib is
    method listVideos() is
        // 向騰訊視頻發(fā)送一個(gè) API 請(qǐng)求。
    method getVideoInfo(id) is
        // 獲取某個(gè)視頻的元數(shù)據(jù)。
    method downloadVideo(id) is
        // 從騰訊視頻下載一個(gè)視頻文件。
// 為了節(jié)省網(wǎng)絡(luò)帶寬,我們可以將請(qǐng)求結(jié)果緩存下來(lái)并保存一段時(shí)間。但你可能無(wú)
// 法直接將這些代碼放入服務(wù)類中。比如該類可能是第三方程序庫(kù)的一部分或其簽
// 名是`final(最終)`。因此我們會(huì)在一個(gè)實(shí)現(xiàn)了服務(wù)類接口的新代理類中放入
// 緩存代碼。當(dāng)代理類接收到真實(shí)請(qǐng)求后,才會(huì)將其委派給服務(wù)對(duì)象。
class CachedTVClass implements ThirdPartyTVLib is
    private field service: ThirdPartyTVLib
    private field listCache, videoCache
    field needReset
    constructor CachedTVClass(service: ThirdPartyTVLib) is
        this.service = service
    method listVideos() is
        if (listCache == null || needReset)
            listCache = service.listVideos()
        return listCache
    method getVideoInfo(id) is
        if (videoCache == null || needReset)
            videoCache = service.getVideoInfo(id)
        return videoCache
    method downloadVideo(id) is
        if (!downloadExists(id) || needReset)
            service.downloadVideo(id)
// 之前直接與服務(wù)對(duì)象交互的 GUI 類不需要改變,前提是它僅通過(guò)接口與服務(wù)對(duì)
// 象交互。我們可以安全地傳遞一個(gè)代理對(duì)象來(lái)代替真實(shí)服務(wù)對(duì)象,因?yàn)樗鼈兌紝?shí)
// 現(xiàn)了相同的接口。
class TVManager is
    protected field service: ThirdPartyTVLib
    constructor TVManager(service: ThirdPartyTVLib) is
        this.service = service
    method renderVideoPage(id) is
        info = service.getVideoInfo(id)
        // 渲染視頻頁(yè)面。
    method renderListPanel() is
        list = service.listVideos()
        // 渲染視頻縮略圖列表。
    method reactOnUserInput() is
        renderVideoPage()
        renderListPanel()
// 程序可在運(yùn)行時(shí)對(duì)代理進(jìn)行配置。
class Application is
    method init() is
        aTVService = new ThirdPartyTVClass()
        aTVProxy = new CachedTVClass(aTVService)
        manager = new TVManager(aTVProxy)
        manager.reactOnUserInput()

代理模式適合應(yīng)用場(chǎng)景

使用代理模式的方式多種多樣, 我們來(lái)看看最常見(jiàn)的幾種。

  • 延遲初始化 (虛擬代理)。 如果你有一個(gè)偶爾使用的重量級(jí)服務(wù)對(duì)象, 一直保持該對(duì)象運(yùn)行會(huì)消耗系統(tǒng)資源時(shí), 可使用代理模式。

  • 你無(wú)需在程序啟動(dòng)時(shí)就創(chuàng)建該對(duì)象, 可將對(duì)象的初始化延遲到真正有需要的時(shí)候。

  • 訪問(wèn)控制 (保護(hù)代理)。 如果你只希望特定客戶端使用服務(wù)對(duì)象, 這里的對(duì)象可以是操作系統(tǒng)中非常重要的部分, 而客戶端則是各種已啟動(dòng)的程序 (包括惡意程序), 此時(shí)可使用代理模式。

  • 代理可僅在客戶端憑據(jù)滿足要求時(shí)將請(qǐng)求傳遞給服務(wù)對(duì)象。

  • 本地執(zhí)行遠(yuǎn)程服務(wù) (遠(yuǎn)程代理)。 適用于服務(wù)對(duì)象位于遠(yuǎn)程服務(wù)器上的情形。在這種情形中, 代理通過(guò)網(wǎng)絡(luò)傳遞客戶端請(qǐng)求, 負(fù)責(zé)處理所有與網(wǎng)絡(luò)相關(guān)的復(fù)雜細(xì)節(jié)。

  • 記錄日志請(qǐng)求 (日志記錄代理)。 適用于當(dāng)你需要保存對(duì)于服務(wù)對(duì)象的請(qǐng)求歷史記錄時(shí)。代理可以在向服務(wù)傳遞請(qǐng)求前進(jìn)行記錄。

  • 緩存請(qǐng)求結(jié)果 (緩存代理)。 適用于需要緩存客戶請(qǐng)求結(jié)果并對(duì)緩存生命周期進(jìn)行管理時(shí), 特別是當(dāng)返回結(jié)果的體積非常大時(shí)。代理可對(duì)重復(fù)請(qǐng)求所需的相同結(jié)果進(jìn)行緩存, 還可使用請(qǐng)求參數(shù)作為索引緩存的鍵值。

  • 智能引用。 可在沒(méi)有客戶端使用某個(gè)重量級(jí)對(duì)象時(shí)立即銷毀該對(duì)象。代理會(huì)將所有獲取了指向服務(wù)對(duì)象或其結(jié)果的客戶端記錄在案。 代理會(huì)時(shí)不時(shí)地遍歷各個(gè)客戶端, 檢查它們是否仍在運(yùn)行。 如果相應(yīng)的客戶端列表為空, 代理就會(huì)銷毀該服務(wù)對(duì)象, 釋放底層系統(tǒng)資源。

  • 代理還可以記錄客戶端是否修改了服務(wù)對(duì)象。 其他客戶端還可以復(fù)用未修改的對(duì)象。

實(shí)現(xiàn)方式

  • 如果沒(méi)有現(xiàn)成的服務(wù)接口, 你就需要?jiǎng)?chuàng)建一個(gè)接口來(lái)實(shí)現(xiàn)代理和服務(wù)對(duì)象的可交換性。 從服務(wù)類中抽取接口并非總是可行的, 因?yàn)槟阈枰獙?duì)服務(wù)的所有客戶端進(jìn)行修改, 讓它們使用接口。 備選計(jì)劃是將代理作為服務(wù)類的子類, 這樣代理就能繼承服務(wù)的所有接口了。
  • 創(chuàng)建代理類, 其中必須包含一個(gè)存儲(chǔ)指向服務(wù)的引用的成員變量。 通常情況下, 代理負(fù)責(zé)創(chuàng)建服務(wù)并對(duì)其整個(gè)生命周期進(jìn)行管理。 在一些特殊情況下, 客戶端會(huì)通過(guò)構(gòu)造函數(shù)將服務(wù)傳遞給代理。
  • 根據(jù)需求實(shí)現(xiàn)代理方法。 在大部分情況下, 代理在完成一些任務(wù)后應(yīng)將工作委派給服務(wù)對(duì)象。
  • 可以考慮新建一個(gè)構(gòu)建方法來(lái)判斷客戶端可獲取的是代理還是實(shí)際服務(wù)。 你可以在代理類中創(chuàng)建一個(gè)簡(jiǎn)單的靜態(tài)方法, 也可以創(chuàng)建一個(gè)完整的工廠方法。
  • 可以考慮為服務(wù)對(duì)象實(shí)現(xiàn)延遲初始化。

代理模式優(yōu)缺點(diǎn)

  • 你可以在客戶端毫無(wú)察覺(jué)的情況下控制服務(wù)對(duì)象。

  • 如果客戶端對(duì)服務(wù)對(duì)象的生命周期沒(méi)有特殊要求, 你可以對(duì)生命周期進(jìn)行管理。

  • 即使服務(wù)對(duì)象還未準(zhǔn)備好或不存在, 代理也可以正常工作。

  • 開(kāi)閉原則。 你可以在不對(duì)服務(wù)或客戶端做出修改的情況下創(chuàng)建新代理。

  • 代碼可能會(huì)變得復(fù)雜, 因?yàn)樾枰陆ㄔS多類。

  • 服務(wù)響應(yīng)可能會(huì)延遲。

代碼示例

Go設(shè)計(jì)模式之代理模式講解和代碼示例_Golang_腳本之家 (jb51.net)

到此這篇關(guān)于Go設(shè)計(jì)模式之代理模式圖文詳解的文章就介紹到這了,更多相關(guān)Go代理模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺析Go語(yǔ)言中包的介紹與初始化

    淺析Go語(yǔ)言中包的介紹與初始化

    這篇文章主要為大家詳細(xì)介紹了Go語(yǔ)言中包的介紹與初始化,從而搞清Go程序的執(zhí)行次序,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解下
    2023-10-10
  • Go語(yǔ)言操作etcd的示例詳解

    Go語(yǔ)言操作etcd的示例詳解

    etcd是使用Go語(yǔ)言開(kāi)發(fā)的一個(gè)開(kāi)源的、高可用的分布式key—value存儲(chǔ)系統(tǒng),可以用于配置共享和服務(wù)的注冊(cè)和發(fā)現(xiàn),下面我們就來(lái)看看Go語(yǔ)言是如何操作etcd的吧
    2024-03-03
  • Go語(yǔ)言使用kafka-go實(shí)現(xiàn)Kafka消費(fèi)消息

    Go語(yǔ)言使用kafka-go實(shí)現(xiàn)Kafka消費(fèi)消息

    本篇文章主要介紹了使用kafka-go庫(kù)消費(fèi)Kafka消息,包含F(xiàn)etchMessage和ReadMessage的區(qū)別和適用場(chǎng)景,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-12-12
  • Golang基于內(nèi)存的鍵值存儲(chǔ)緩存庫(kù)go-cache

    Golang基于內(nèi)存的鍵值存儲(chǔ)緩存庫(kù)go-cache

    go-cache是一個(gè)內(nèi)存中的key:value store/cache庫(kù),適用于單機(jī)應(yīng)用程序,本文主要介紹了Golang基于內(nèi)存的鍵值存儲(chǔ)緩存庫(kù)go-cache,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-03-03
  • Golang切片Slice功能操作詳情

    Golang切片Slice功能操作詳情

    這篇文章主要介紹了Golang切片功能操作詳情,切片是一個(gè)擁有相同類型元素的可變長(zhǎng)度的序列。它是基于數(shù)組類型做的一層封,切片是一個(gè)引用類型,它的內(nèi)部結(jié)構(gòu)包含地址、長(zhǎng)度和容量
    2022-09-09
  • Go數(shù)據(jù)結(jié)構(gòu)之HeapMap實(shí)現(xiàn)指定Key刪除堆

    Go數(shù)據(jù)結(jié)構(gòu)之HeapMap實(shí)現(xiàn)指定Key刪除堆

    這篇文章主要給大家介紹了Go語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之HeapMap實(shí)現(xiàn)指定Key刪除堆,通過(guò)使用Go語(yǔ)言中的container/heap包,我們可以輕松地實(shí)現(xiàn)一個(gè)優(yōu)先級(jí)隊(duì)列,文中有詳細(xì)的代碼示例講解,需要的朋友可以參考下
    2023-07-07
  • Goland 的安裝及激活教程(window、linux下安裝)

    Goland 的安裝及激活教程(window、linux下安裝)

    這篇文章主要介紹了Golang Goland 的安裝及激活詳細(xì)教程,包括window下安裝goland和linux下安裝goland,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • 一文詳解Go Http Server原理

    一文詳解Go Http Server原理

    這篇文章主要為大家介紹了Go Http Server原理示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • Go語(yǔ)言LeetCode500鍵盤行題解示例詳解

    Go語(yǔ)言LeetCode500鍵盤行題解示例詳解

    這篇文章主要為大家介紹了Go語(yǔ)言LeetCode500鍵盤行題解示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • GoLang五種字符串拼接方式小結(jié)

    GoLang五種字符串拼接方式小結(jié)

    本文主要介紹了GoLang五種字符串拼接方式詳解,包括+操作符、fmt.Sprintf、strings.Builder、bytes.Buffer和strings.Join,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-12-12

最新評(píng)論

花垣县| 阿合奇县| 岐山县| 高邮市| 池州市| 拜泉县| 浦江县| 延寿县| 巩留县| 涞水县| 永平县| 洛隆县| 蓝田县| 莱西市| 常熟市| 商南县| 沂南县| 高邮市| 桃园市| 永宁县| 会泽县| 丹阳市| 思茅市| 南陵县| 志丹县| 明水县| 理塘县| 灵寿县| 丹江口市| 博客| 阜康市| 施秉县| 富蕴县| 翁牛特旗| 庆阳市| 武汉市| 留坝县| 辽中县| 富宁县| 天峻县| 曲阳县|