設計模式-----代理模式
一簡介
代理是英文 Proxy 翻譯過來的。我們在生活中見到過的代理,大概最常見的就是朋友圈中賣面膜的同學了。
她們從廠家拿貨,然後在朋友圈中宣傳,然後賣給熟人。
UML圖
要點:
1. 使用者只關心介面功能,而不在乎誰提供了功能。上圖中介面是 Subject。
2. 介面真正實現者是上圖的 Proxied,但是它不與使用者直接接觸,而是通過代理。
3. 代理就是上圖中的 Proxy,由於它實現了 Subject 介面,所以它能夠直接與使用者接觸。
4. 使用者呼叫 Proxy 的時候,Proxy 內部呼叫了 Proxied。所以,Proxy 是中介者,它可以增強 Proxied 操作。
代理又分為靜態代理與動態代理。
二 靜態代理
為什麼叫做靜態呢?因為它的型別是事先預定好的,在程式編譯時,就能知道被代理角色是誰,比如下面程式碼中的 Badstudent 這個類。
下面我舉一個好學生代替壞學生完成作業的例子。
1.首先定義一個通用的介面Student,規定學生要做什麼。
2.然後定義一個好學生GoodStudent 實現介面,這個類作為真正的業務實現者,(代理者)
3.最後再定義一個壞學生,通過好學生完成他 的作業 (代理者)
測試
結果
做作業
看書
背單詞
靜態代理的總結
優點:可以做到不對目標物件進行修改的前提下,對目標物件進行功能的擴充套件和攔截。
缺點:因為代理物件,需要實現與目標物件一樣的介面,會導致代理類十分繁多,不易維護,同時一旦介面增加方法,則目標物件和代理類都需要維護。
代理模式可以在不修改被代理物件的基礎上,通過擴充套件代理類,進行一些功能的附加與增強。值得注意的是,代理類和被代理類應該共同實現一個介面,或者是共同繼承某個類
三 動態代理
動態代理可以在程式執行期間根據需要動態的建立代理類及其例項,來完成具體的功能。
三要素:
1 代理介面:規定被代理的類的功能
2. 具體實現類: 實現代理介面,作為被代理者
3 具體執行者: 實現 InvocationHandler 介面 ,作為代理者
下面我們定義一個櫃檯賣酒的例子,可以理解為原來是散戶賣酒,現在通過櫃檯代理賣酒
具體實現:
1.定義代理介面
2.具體實現類
賣茅臺酒
賣劍南春
3.代理者 櫃檯A
測試
結果
這裡是:GuiTaiA
賣茅臺酒
消費結束
------------
這裡是:GuiTaiA
劍南春
消費結束
語法解析
Proxy
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
loader 自然是類載入器 (目標類載入器)
interfaces 程式碼要用來代理的介面(目標類介面)
h 一個 InvocationHandler 物件 (實際執行類)
InvocationHandler
public interface InvocationHandle
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
- proxy 代理物件
- method 代理物件呼叫的方法
- args 呼叫的方法中的引數