1. 程式人生 > >設計模式-----代理模式

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

一簡介

代理是英文 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 呼叫的方法中的引數