-
為什麼要代理?
- 解決在直接訪問物件時帶來的問題,比如說:要訪問的物件在遠端的機器上。在物件導向系統中,有些物件由於某些原因(比如物件建立開銷很大,或者某些操作需要安全控制,或者需要程序外的訪問),直接訪問會給使用者或者系統結構帶來很多麻煩,我們可以在訪問此物件時加上一個對此物件的訪問層。
-
什麼是代理模式?
- 代理模式(Proxy Pattern)是一種結構性模式。代理模式為一個物件提供了一個替身,以控制對這個物件的訪問。即透過代理物件訪問目標目標物件,可以在目標物件實現的基礎上,增強額外的功能操作,即擴充套件目標物件的功能。
-
代理模式分為靜態代理和動態代理
- 靜態:由程式設計師建立代理類或特定工具自動生成原始碼再對其編譯,在程式執行前代理類的 .class 檔案就已經存在了。
- 動態:在程式執行時,運用反射機制動態建立而成。
-
靜態代理
-
靜態代理是定義父類或者介面,然後被代理物件(即目標物件)與代理物件一起實現相同的介面或者是繼承相同父類。代理物件與目標物件實現相同的介面,然後透過呼叫相同的方法來呼叫目標物件的方法。
- 優點:可不修改目標物件的功能,透過代理物件對目標功能擴充套件。
- 缺點:因為代理物件需要與目標物件實現一樣的介面,所以會有很多代理類,一旦介面增加方法,目標物件與代理物件都要維護。
-
舉例
-
ITeacherDao:介面
-
TeacherDao:目標物件,實現介面ITeacherDao
-
TeacherDAOProxy:代理物件,也實現ITeacherDao介面,並且聚合ITeacherDao屬性,透過構造器傳參設定值,呼叫的時候透過呼叫代理物件的方法來呼叫目標物件。
-
-
動態代理
-
動態代理也叫JDK代理、介面代理。它使代理物件不需要實現介面(但目標物件要實現介面),代理物件的生成,是利用JDK的API,動態的在記憶體中構建代理物件。
-
即使用JDK包java.lang.reflect.Proxy中的newProxyInstance方法來動態的建立目標物件(被代理物件),該方法需要如下接收三個引數:
- ClassLoader loader:指定當前目標物件使用的類載入器
- Class<?>[] interfaces :目標物件實現的介面型別,使用泛型方法確認型別
- InvocationHandler h :事情處理,執行目標物件的方法時,會觸發事情處理器方法,把當前執行的目標物件方法作為引數傳入
-
核心是getProxyInstacne()
- 根據傳入的物件TeacherDao目標物件
- 利用反射機制,返回一個代理物件
- 然後透過代理物件,呼叫目標物件方法
//介面 public interface ITeacherDao { void teach(); void test(String name); } //目標物件 public class TeacherDao implements ITeacherDao { @Override public void teach() { System.out.println("一鍵三連"); } @Override public void test(String name) { System.out.println("傳參測試:" + name); } } //代理物件 public class ProxyFactory { //維護一個目標物件 , Object private Object target; //構造器 , 對target 進行初始化 public ProxyFactory(Object target) { this.target = target; } //動態生成一個代理物件 public Object getProxyInstance() { return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { //匿名類重寫invoke方法 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("動態代理開始"); Object returnVal = method.invoke(target, args);//反射機制呼叫目標物件的方法 System.out.println("動態代理結束"); return returnVal; } }); } } //測試 public class Client { public static void main(String[] args) { //建立目標物件 ITeacherDao target = new TeacherDao(); //建立代理物件 ITeacherDao proxyInstance = (ITeacherDao)new ProxyFactory(target).getProxyInstance(); //記憶體中動態生成了代理物件 System.out.println(proxyInstance.getClass()); //透過代理物件,呼叫目標物件的方法 proxyInstance.teach(); proxyInstance.test("一鍵三連"); } }
-
設計模式之代理模式
相關文章
- 《設計模式》之代理模式設計模式
- 【設計模式之代理模式】設計模式
- 設計模式之禪之代理模式設計模式
- Javascript設計模式之代理模式JavaScript設計模式
- Java設計模式之代理模式Java設計模式
- 設計模式系列之「代理模式」設計模式
- 設計模式之代理設計模式
- Java設計模式-之代理模式(動態代理)Java設計模式
- 設計模式之代理模式(proxy pattern)設計模式
- 23天設計模式之代理模式設計模式
- Java設計模式之(五)——代理模式Java設計模式
- C++設計模式之代理模式C++設計模式
- 設計模式漫談之代理模式設計模式
- Java設計模式之代理模式(Proxy)Java設計模式
- 我學設計模式 之 代理模式設計模式
- C++設計模式之Proxy模式(代理模式)C++設計模式
- 23種設計模式之代理模式(靜態代理)設計模式
- JavaScript設計模式經典之代理模式JavaScript設計模式
- 設計模式之代理模式(結構型)設計模式
- 12.java設計模式之代理模式Java設計模式
- JAVA設計模式之 代理模式【Proxy Pattern】Java設計模式
- C#設計模式之代理模式(四)C#設計模式
- C#設計模式之代理模式(三)C#設計模式
- C#設計模式之代理模式(二)C#設計模式
- C#設計模式之代理模式(一)C#設計模式
- 設計模式----代理模式設計模式
- 設計模式——代理模式設計模式
- 設計模式-代理模式設計模式
- 設計模式~代理模式設計模式
- 【設計模式】代理模式設計模式
- Java設計模式之七 —– 享元模式和代理模式Java設計模式
- android常用設計模式之代理設計模式及動態代理原理Android設計模式
- 23種設計模式之——動態代理模式設計模式
- javascript設計模式 之 3代理模式JavaScript設計模式
- 跟著GPT學設計模式之代理模式GPT設計模式
- 設計模式之觀察和代理設計模式
- PHP設計模式-代理模式PHP設計模式
- js設計模式--代理模式JS設計模式