設計模式篇---代理模式

文章目錄

    • 概念
    • 結構
    • 實例
      • 靜態代理
      • 動態代理
    • 總結

概念

代理模式:給某一個對象提供一個代理或占位符,并由代理對象來控制對原對象的訪問。
比如我們想從其他國家買東西,但我們無法直接聯系外國的商家,可以找代理商,讓他們幫我們處理,我們是客戶端,只需要面向代理商即可,只需要把錢交給代理商,剩下的那些操作,比如聯系商家、和商家簽訂協議等我們都不需要關心。

結構

在這里插入圖片描述
Subject(抽象主題):它是代理類和真實類的共同接口,這樣一來在任何使用真實對象的地方都可以使用代理對象,客戶端通常需要針對抽象主題角色進行編程。
Proxy(代理類) :它包含了真實對象的引用,所以可以在任何時候操作真實對象。一般在調用真實對象前后還需要執行其他操作。
RealSubject(真實類–被代理類):真實類中實現了主要的業務操作。客戶端可以調用代理類,來間接的調用真實類。

實例

靜態代理

我們想從海外買臺電腦,用代理模式實現這個流程。
在這里插入圖片描述

購買東西的接口

public interface IBuySomething {void pay();
}

真實類,也就是被代理類

public class Person implements IBuySomething{@Overridepublic void pay() {System.out.println("付款");}
}

代理商,也就是代理類,他來幫我們聯系商家

public class Agent implements IBuySomething {private IBuySomething person;public Agent(IBuySomething person) {this.person = person;}@Overridepublic void pay() {findBusiness();person.pay();}private void findBusiness() {System.out.println("我是代理商,付款之前先找到商家");}
}

客戶端

public class Client {public static void main(String[] args) {IBuySomething person;person = new Agent(new Person());person.pay();}
}

打印結果:
在這里插入圖片描述
也可以讓代理商來替我們的朋友來買東西,只需要再聲明一個朋友類,讓代理商來代理即可。

朋友類

public class Friend implements IBuySomething{@Overridepublic void pay() {System.out.println("我是朋友,我付款");}
}

客戶端

public class Client {public static void main(String[] args) {IBuySomething person;person = new Agent(new Friend());person.pay();}
}

打印結果
在這里插入圖片描述
反過來,如果想換一家代理商,那就再創建一個新的代理商類即可。

public class Agent2 implements IBuySomething{private IBuySomething person;public Agent2(IBuySomething person) {this.person = person;}@Overridepublic void pay() {findBusiness();person.pay();}private void findBusiness() {System.out.println("我是另外一個代理商,付款之前先找到商家");}
}

動態代理

以上的這種代理方式叫做靜態代理。
靜態代理的特點是,一個代理類只能代理一個真實類,或者只能代理一個方法。因為它在執行前就編譯成了class文件,不會進行改變了,所以被稱為靜態代理。
但如果我們想動態的代理不同的真實類,或者代理不同的方法,可以使用動態代理來實現。動態代理可以讓系統在運行時根據實際需求來動態的創建代理類。
有關動態代理,有兩個重要的類。
Proxy類
Proxy類提供了用于創建動態代理對象的方法。它的主要方法newProxyInstance

    public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)

該方法即用來創建一個動態代理對象;第一個參數是代理類的類加載器(作用是將.class文件加載到jvm中,進而生成一個對象實例);第二個參數是真實類實現的接口列表;第三個是執行代理方法的具體程序—InvocationHandler。
簡單總結下,要想生成一個代理對象,首先得創建class對象(第一個參數的作用),其次得知道代理誰(第二個參數的作用),最后代理的方法是什么(第三個參數)。這樣看來,第二個和第三個參數都是動態的,可變的,這也就是代理模式的靈活性。

InvocationHandler
上面的第三個參數InvocationHandler 是一個接口,它只有一個invoke方法

public Object invoke(Object proxy, Method method, Object[] args)throws Throwable;

該方法用來處理代理類實例的代理方法,并返回相應的結果。即我們代理的方法寫在這個方法里。
第一個參數是代理對象;第二個參數是需要代理的方法;第三個參數是需要執行代理方法的參數。

還是拿買東西的例子來說,我們如果買完東西后,發現不合適,需要退款,這時候我們面向的還是代理商,但如果用靜態代理的話,那還是需要再寫一個代理退款的類,如果業務方法更多的話,那我們需要創建更多的靜態代理類,這樣處理起來很麻煩。如果用動態代理的話,就沒有這么冗余。我們首先實現一個InvocationHandler,它的invoke方法是用來實現代理對象的方法。

public class AgentHandler implements java.lang.reflect.InvocationHandler {private Object object;public AgentHandler(Object object) {this.object = object;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {findBusiness();Object result = method.invoke(object, args);return result;}private void findBusiness() {System.out.println("我是代理商,我要先找到商家");}
}

我們也增加一個退款的方法

public interface IBuySomething {void pay();void refund();
}

客戶端調用

public class Client {public static void main(String[] args) {IBuySomething person = new Person();InvocationHandler handler = new AgentHandler(person);Object o = Proxy.newProxyInstance(person.getClass().getClassLoader(), person.getClass().getInterfaces(), handler);IBuySomething proxy = (IBuySomething) o;proxy.refund();}
}

打印結果:
在這里插入圖片描述

總結

靜態代理比較好理解,代理類里面實現了代理的方法。
而動態代理的代理對象是通過Proxy創建的,代理的方法是在InvocationHandler里的invoke方法里,和靜態代理對比的話,代理類和代理方法是分離開的。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/213267.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/213267.shtml
英文地址,請注明出處:http://en.pswp.cn/news/213267.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

dell r720遠程網絡安裝ubuntu20.04(無U盤)

登陸后界面&#xff0c;在主界面上&#xff0c;我們就可以看到各個硬件組件的狀態。在快速啟動任務欄中&#xff0c;可以對系統電源進行操作&#xff0c;如開機、關機等。安裝操作系統&#xff0c;在虛擬控制臺預覽處點擊>啟動 按照瀏覽器出現的提示確定安裝控件等&#x…

NSSCTF web刷題記錄7

文章目錄 [SDCTF 2022]CURL Up and Read [SDCTF 2022]CURL Up and Read 考點&#xff1a;SSRF 打開題目發現是curl命令&#xff0c;提示填入url 嘗試http://www.baidu.com&#xff0c;成功跳轉 將url的字符串拿去解碼&#xff0c;得到json格式數據 讀取下環境變量&#xff0c…

基礎寵物商店管理系統(Java)大一程序設計

一.開發環境 Windows 11 -- JDK 21 -- IDEA 2021.3.3 二.需求 三.代碼部分 //創建一個寵物類&#xff0c;被另外兩類繼承public class Pet {private String name;private int age;private String gender;private double cost0;//買進價格private double sellprice0;//賣出價…

【Spring】Spring統一功能處理

Spring統一功能處理 攔截器攔截器什么是攔截器攔截器的基本使用定義攔截器注冊配置攔截器 攔截器詳解攔截器的攔截路徑配置攔截器實現原理初始化處理請求 適配器模式 統一數據返回格式統一數據返回格式快速入門 統一異常處理 攔截器 場景: 我們要對一個網站實現強制登陸的功能…

ChibiOS簡介2/5

ChibiOS簡介2/5 1. 源由2. ChibiOS基礎知識2/52.4 Chapter 4 - ChibiOS General Architecture2.4.1 The Big Picture&#xff08;總體框圖&#xff09;2.4.2 Embedded Components&#xff08;嵌入式組件&#xff09;2.4.3 Application Model&#xff08;應用模型&#xff09;2.…

爬蟲解析——Xpath的安裝及使用(五)

目錄 一、Xpath插件的安裝 二、安裝 lxml 三、Xpath解析文件 1.解析本地文件 &#xff08;1&#xff09;導入本地文件 &#xff08;2&#xff09;解析本地文件 2.服務器文件解析 &#xff08;1&#xff09;獲取網頁源碼 &#xff08;2&#xff09;解析服務器響應文件 …

力扣373. 查找和最小的 K 對數字

優先隊列 思路&#xff1a; 使用下標 (x, y) 標識數值對&#xff0c;x 為第一個數組的下標&#xff0c;y 為第二個數組的下標&#xff1b;所以 k 個數值對 x 的范圍屬于 [0, min(k, m)]&#xff0c;m 為第一個數組的 size&#xff1b;數值對 (x, y) &#xff0c;那么下一個比其…

TailwindCSS 如何處理RTL布局模式

背景 TikTok作為目前全世界最受歡迎的APP&#xff0c;需要考慮兼容全世界各個地區的本地化語言和閱讀習慣。其中對于阿拉伯語、波斯語等語言的閱讀書寫習慣是從右向左的&#xff0c;在前端有一個專有名字RTL模式&#xff0c;即Right-to-Left。 其中以阿拉伯語作為第一語言的人…

C# 獲取windows 系統開關機時間

關機時間&#xff0c;引用&#xff1a;https://www.coder.work/article/1589448 public static DateTime GetLastSystemShutdown() { string sKey "System\CurrentControlSet\Control\Windows"; Microsoft.Win32.RegistryKey key …

建立個人學習觀|地鐵上的自習室

作者&#xff1a;向知 如果大家有機會來北京&#xff0c;可以來看看工作日早上八九點鐘&#xff0c;15 號線從那座叫“順義”的城市通向“望京”的地鐵&#xff0c;你在那上面&#xff0c;能看到明明白白的&#xff0c;人們奔向夢想的模樣。 一、地鐵上的自習室 我在來北京之前…

華為數據之道學習筆記】3-5 規則數據治理

在業務規則管理方面&#xff0c;華為經常面對“各種業務場景業務規則不同&#xff0c;記不住&#xff0c;找不到”“大量規則在政策、流程等文件中承載&#xff0c;難以遵守”“各國規則均不同&#xff0c;IT能否一國一策、快速上線”等問題。 規則數據是結構化描述業務規則變量…

【算法集訓】基礎數據結構:三、鏈表

鏈表就是將所有數據都用一個鏈子串起來&#xff0c;其中鏈表也有多種形式&#xff0c;包含單向鏈表、雙向鏈表等&#xff1b; 現在畢竟還是基礎階段&#xff0c;就先學習單鏈表吧&#xff1b; 鏈表用頭結點head表示一整個鏈表&#xff0c;每個鏈表的節點包含當前節點的值val和下…

2024 年頂級的 Android 系統修復軟件與方法

您是否正在尋找可以修復 PC 上 Android 操作系統的工具&#xff1f;這是我們精選的最好的 Android 系統修復軟件&#xff01; Android 是世界著名的智能手機操作系統。全世界有數百萬人使用這個操作系統&#xff0c;這使得它安全可靠。然而&#xff0c;這仍然不能使它完美無缺…

048:利用vue-video-player播放m3u8

第048個 查看專欄目錄: VUE ------ element UI 專欄目標 在vue和element UI聯合技術棧的操控下&#xff0c;本專欄提供行之有效的源代碼示例和信息點介紹&#xff0c;做到靈活運用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安裝、引用&#xff0c;模板使…

普冉(PUYA)單片機開發筆記(6): 呼吸燈

概述 上一篇的實驗中&#xff0c;分別正確地配置了 TIM16 和 TIM1&#xff0c;TIM16 的中斷服務程序中每隔 500ms 翻轉板載 LED 一次&#xff1b;TIM1 的 CHANNEL_1 用于輸出一個固定占空比的 PWM 信號。這一次我們進一小步&#xff1a;使用 TIM16 的中斷設置 TIM1 CHANNEL_1 …

MyBatis進階之分頁和延遲加載

文章目錄 分頁1. RowBounds 分頁2. PageHelper 分頁3. PageInfo 對象屬性描述 延遲加載立即加載激進式延遲加載真-延遲加載 分頁 Mybatis 中實現分頁功能有 3 種途徑&#xff1a; RowBounds 分頁&#xff08;不建議使用&#xff09;Example 分頁&#xff08;簡單情況可用)Pag…

關于對向量檢索研究的一些學習資料整理

官方學習資料 主要是的學習資料是&#xff0c; 官方文檔 和官方博客。相關文章還是挺多 挺不錯的 他們更新也比較及時。有最新的東西 都會更新出來。es scdn官方博客 這里簡單列一些&#xff0c;還有一些其他的&#xff0c;大家自己感興趣去看。 什么是向量數據庫 Elasticse…

文件加密軟件哪個最好用 好用的文件加密軟件推薦

一說到文件加密軟件&#xff0c;可能大家都會去搜一些不知名的軟件來&#xff0c;但是選擇這種加密軟件&#xff0c;最好還是要看一些資質的。 資質不好的&#xff0c;可能加密過后你自己也打不開文件&#xff0c;&#xff08;ps&#xff1a;我自己就遇到過這種情況&#xff09…

【華為OD機試python】分蘋果【2023 B卷|100分】

【華為OD機試】-真題 !!點這里!! 【華為OD機試】真題考點分類 !!點這里 !! 題目描述 A、B兩個人把蘋果分為兩堆,A希望按照他的計算規則等分蘋果, 他的計算規則是按照二進制加法計算,并且不計算進位 12+5=9(1100 + 0101 = 9), B的計算規則是十進制加法,包括正常進位,…

基于Java SSM框架高校校園點餐訂餐系統項目【項目源碼+論文說明】計算機畢業設計

基于java的SSM框架高校校園點餐訂餐系統演示 摘要 21世紀的今天&#xff0c;隨著社會的不斷發展與進步&#xff0c;人們對于信息科學化的認識&#xff0c;已由低層次向高層次發展&#xff0c;由原來的感性認識向理性認識提高&#xff0c;管理工作的重要性已逐漸被人們所認識&a…