【設計模式】牛掰格拉斯的代理模式

来源:https://www.cnblogs.com/lixinjie/archive/2020/05/25/a-post-about-designpattern-of-proxy.html
-Advertisement-
Play Games

代理的本質無論任何時候,只要談到設計模式,大腦中一定要蹦出這四個字“活學活用”。要想對某個事物做到活學活用,必須要對它足夠瞭解,甚至要剖析到本質才行。總是會有些人說,我幹嘛要知道原理,幹嘛要去看源碼?會用就行了。對於這種情況,我只有五個字相送,“你開心就好”。不可否認,認識一個陌生事物,大部分情況還 ...



代理的本質



無論任何時候,只要談到設計模式,大腦中一定要蹦出這四個字“活學活用”。

要想對某個事物做到活學活用,必須要對它足夠瞭解,甚至要剖析到本質才行。

總是會有些人說,我幹嘛要知道原理,幹嘛要去看源碼?會用就行了。對於這種情況,我只有五個字相送,“你開心就好”。

不可否認,認識一個陌生事物,大部分情況還是要從定義開始。

代理模式為某對象提供一種代理以控制對該對象的訪問,從而限制、增強或修改該對象的一些特性。

如果對代理模式本身就很熟悉的人,一眼就明白什麼意思,甚至連代碼怎麼寫都會浮現在腦海中。

關鍵是對代理模式一點都不熟悉的人,看到定義後絕對一臉懵。下麵通過簡單的圖形來揭開迷惑。

沒有使用代理模式,如下圖01:


”直接訪問“目標”。

使用了代理模式,如下圖02:


”訪問代理代理訪問“目標”。


人群中一定會有兩種聲音:

1)設計模式是很高深莫測的東西,有這麼簡單嗎?

2)這怎麼沒有代碼實現啊?

來聽聽作者的看法:

1)高深莫測和簡單不一定都是對沖的。幸福絕對是高深莫測的,那什麼是幸福呢,最多的答案恐怕就是,“一畝土地兩頭牛,老婆孩子熱炕頭”。

多麼簡單朴實的答案,可惜,包括我在內的很多人都追求不到。主要原因是我們人為(主觀)的把很多事情搞複雜了。下麵這個事情可以說明這一點。

中秋節放假時到附近的一個小景區去看一看,我發現有一種果樹的果子掛滿枝頭,又大又圓,讓人看了之後特別有欲望,甚至垂涎欲滴,可惜沒有一個人去摘。

我的第一反應就是果子肯定不能吃。過了一會兒,終於抑制不住好奇心,就找了一個比較矮的果樹,摸了摸枝頭上的果子。果然硬如磐石。

2)對於一上來就說代碼實現的人,只能認為是你擁有了一把錘子之後,看什麼都像釘子。

代碼實現永遠都是最後一步,但在它之前,要找出問題,分析問題,給出方案,論證方案可行性。如果這些都OK了,代碼就是水到渠成的事了。

記住這句話:

認清原理,搞清本質,永遠都是最重要的,不單單是在寫代碼上,在社會上依然如此。

那代理的本質是什麼呢?就兩個字,“加層”,即增加一(多)層。這就是本質。

像其它的什麼“控制訪問”啦,“增強或修改特性”啦,只不過是這個“層"產生的一些(副)作用罷了。


生活中充滿著代理


雖然大部分人都沒有參與過訴訟,但作為常識我們都知道,當事人可以通過協議把自己的一些權力授權給律師,律師就可以在法庭上行使這些權利,此時律師就是代理。

現在網購已成為生活的一部分,但是收快遞卻比較麻煩,因為通常家中無人。此時菜鳥驛站(或媽媽驛站)出現了,它幫我們簽收和暫存包裹,所以它就是代理。

現在生活壓力大,每個人都要上班,所以中午和下午都沒有時間去接送自己上小學的孩子,此時只能選擇午托,我們交了托費之後就等於給了它授權,它代替我們去接送孩子,可見午托也是代理。

還有各種產品的代理商,有大區代理,省級代理,市級代理,等等。還有就是微商/代購,微商自己沒有貨品,只是發發朋友圈,最終是別人發貨。代購就更直接了,代替你去購買,然後再郵寄給你。

明星藝人都有自己的經紀人,可以替自己接一些活動,討價還價,安排日程等。此時經紀人就是代理。還有大BOSS也會請一到多個秘書,來代替自己做一些事情。

可見,生活中充滿著很多代理,他們以各種各樣的形式存在著,發揮著各種各樣的功能和作用,也確實解決了很多社會和生活的問題。

但從本質來看,代理大都以“層”的形式呈現,站在老闆的前面,替老闆做事情。


和電腦相關的代理


大部分人可能都聽過這樣一句話,凡是遇到不好解決的問題,大都可以通過加一層得到有效的解決。加的這個層很多時候和代理有關。

為了網路安全問題,可以加一層防火牆,防火牆雖然不完全是代理,但卻用到許多代理的理論和技術。

為了擴充本地區域網絡,可以加一層交換機或路由器,它用來代理和轉髮網絡請求。還會有一些附帶的其它功能。

為了平衡多個伺服器的處理能力,我們在前面加一個請求路由層,也就是負載均衡器了,如Nginx,它可以代理請求,並按規則轉發。

再說說CRUD,原來是我們寫代碼直接使用JDBC訪問資料庫,現在我們寫代碼使用的是ORM框架,ORM框架再使用JDBC去訪問資料庫。ORM框架可以看作是JDBC的代理。

我們可以看到,從硬體到中間件,再到程式框架,都有代理的影子。


和編程相關的代理


上面所說的代理,都是廣義的代理,主要側重於角色和功能。

一旦在編程中談到代理,基本就是狹義代理了。除了廣義代理的要求外,還要保持類型的相容和“介面”的一致

說白了就是需要被代理對象的地方,給它一個代理也可以。可以在被代理對象上調用的方法,在代理上也可以調用。

這個要求和代理模式中的要求是一樣的。

如果被代理的對象是一個類。我們用Target表示。

class Target {

    public String getDateTime() {
        return "2019-10-09"
    }

}


為了保持類型相容和介面一致,我們需要生成一個子類。

除此之外還要有被代理的對象,所以還需一個成員變數。

為了添加一些功能,通常需要重寫一些方法。

class Proxy extends Target {

    private Target target;

    @Override
    public String getDateTime() {
        return target.getDateTime() + ", 星期三";
    }

}

這樣就生成了一個代理,在需要Target的地方換成Proxy也沒有問題,而且還會在日期後面加上星期。

如果被代理的對象是一個介面。我們用ITarget表示。

interface ITarget {

    String sayHello(String name);

}

 

class Target implements ITarget {

    @Override
    public String sayHello(String name) {
        return "hello " + name;
    }

}


此時我們只需實現介面即可(當然也可以生成子類),其它的保持不變。

class Proxy implements ITarget {

    private ITarget target;

    @Override
    public String sayHello(String name) {
        return target.sayHello(name) + ", long time no see.";
    }
}

這也是一個代理,同樣可以使用Proxy代替Target,而且在原來問好的基礎上增加了更多的話語。

由於類型相容且介面一致,所以用戶代碼有時也不知道到底是對象本身還是它的代理,不過這通常並不重要。

代理的好處我們已經看到了,但是也有不好的地方,就是要寫代理的代碼,造成代碼量增加。

這個問題已經通過動態代理解決了。在Java里比較有名的動態代理,就是JDK動態代理CGLIB代理。這大家都知道了。

全文總結

代理的本質就是通過加一層來解決問題。類型相容和介面一致只是限制條件而已。

代理有著廣泛的應用,想想Spring的成功,代理貢獻了多少,絕對功不可沒。

仔細體會下“加層”的含義,在代碼中和生活中,你會發現它真的很牛掰格拉斯。

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • # 概述 - 1.新增的屬性 placeholder Calendar, date, time, email, url, search ContentEditable Draggable Hidden Context-menu Data-Val(自定義屬性) - 2.新增的標簽 語義化標簽(一群類似 ...
  • 因人而異 自學肯定也是可以的,最主要還是要看個人的學習能力,意志力,和自己的決心, 下麵我就說一下,在自學時需要註意的一些誤區和需要掌握哪些技術知識,才能去找工作。 前端自學者存在的學習誤區: 1、所學東西可能已過時 奉為經典的東西可能已經過時,或者已經有了更好的替代者,而你獲取信息的渠道有限,消息 ...
  • 隨著技術以如此快的速度發展,現在我們有必要選擇合適的工具來使用。每個軟體項目都有它需要滿足的多個需求和規範,因此為了滿足這些需求,選擇一種編程語言以允許您以有效的方式開發和管理項目非常重要。 由於有許多種編程語言和框架可供選擇,它們之間的比較已成為必然,因為你需要知道哪一個提供了最好的服務。當涉及到 ...
  • 什麼是NodeJS JS是腳本語言,腳本語言都需要一個解析器才能運行。對於寫在HTML頁面里的JS,瀏覽器充當瞭解析器的角色。而對於需要獨立運行的JS,NodeJS就是一個解析器。 每一種解析器都是一個運行環境,不但允許JS定義各種數據結構,進行各種計算,還允許JS使用運行環境提供的內置對象和方法做 ...
  • 之前一直採用VS進行各種前端後端的開發,隨著項目的需要,正逐步融合純前端的開發模式,開始主要選型為Vue + Element 進行BS前端的開發,後續會進一步整合Vue + AntDesign的界面套件,作為兩種不同界面框架的展現方式。採用Vue + Element 的前端開發和之前的開發模式需要有... ...
  • 從事web前端6年的工作,曾經是信息管理的一名應屆生,由於專業難找工作,掙錢少,當時選擇了轉行學前端開發技術,今天師兄就給大家講一下,作為應屆生,想學前端快點找工作應該如何去學。 對於畢業生來說,最要緊的事情就是快點找到工作。所以你學前端的時候就抓重點來學,因為很多東西,工作上用不到,所以學了也沒必 ...
  • 前提: (1) 相關博文地址: SpringBoot + Vue + ElementUI 實現後臺管理系統模板 -- 前端篇(一):搭建基本環境:https://www.cnblogs.com/l-y-h/p/12930895.html SpringBoot + Vue + ElementUI 實現 ...
  • 迭代器模式是一種使用頻率非常高的設計模式,迭代器用於對一個聚合對象進行遍歷。通過引入迭代器可以將數據的遍歷功能從聚合對象中分離出來,聚合對象只負責存儲數據,聚合對象只負責存儲數據,而遍曆數據由迭代器來完成。 模式動機 一個聚合對象,如一個列表(List)或者一個集合(Set),應該提供一種方法來讓別 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...