Java设计模式(三) -- 代理模式
????????代理是一種設計模式,即通過代理對象訪問目標對象,這樣可以在目標對象實現的基礎上,增強額外的功能,即擴展目標類的功能。
????? ? 通常編程中存在一種思想,即不要隨意修改別人的代碼或者方法,所以代理就可以在不修改目標代碼的基礎上擴展該目標類。代理模式的關鍵點在于代理對象和目標對象。代理對象對目標對象進行擴展,并會調用目標對象。
????? ? 代理模式包含幾個角色:
????? ? Subject:? ? 一個接口,是代理對象和目標對象公共的接口
????? ? RealSubject:? ? 目標對象。實現接口的類。
????? ? Proxy:? ? 代理對象,包含對目標對象的引用,進而操作目標對象。代理對象包含和目標對象對接口一樣的操作,同時還會附加其他操作,相當于對目標對象的進一步封裝。
????? ??
?1.靜態代理
????????靜態代理在使用時,需要定義接口或者父類,被代理對象與代理對象一起實現相同的接口或者是繼承相同父類.
?????????代碼示例:
?????????接口:?????????? ??
public interface Image {void display(); }????? ?目標類:
public class RealImage implements Image{@Overridepublic void display() {System.out.println("這是一張漂亮的圖片");} }????? ?代理類:
public class ProxyImage implements Image{//接收保存目標對象private Image img;public ProxyImage(Image img) {this.img = img;}@Overridepublic void display() {System.out.println("打開圖片");img.display();System.out.println("關閉圖片");} }????????測試:????
結果:
????????靜態代理可以做到不修改目標對象的前提下對目標對象擴展,但是靜態代理有個缺點:代理對象需要和目標對象實現一樣的接口,所以會有很多代理類,類太多。同時,一旦接口增加方法,目標對象與代理對象都要維護。
? ? 2.動態代理
????? ? 動態代理有以下特點:
????????????1.代理對象,不需要實現接口
???????????????2.代理對象的生成,是利用JDK的API,動態的在內存中構建代理對象(需要我們指定創建代理對象/目標對象實現的接口的類型)
???????????????3.動態代理也叫做:JDK代理,接口代理
????? ? 動態代理的關鍵是反射
????? ??JDK中生成代理對象的API
????????代理類所在包:java.lang.reflect.Proxy
????????JDK實現代理只需要使用newProxyInstance方法,但是該方法需要接收三個參數,完整的寫法是:
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )????? ? 實例代碼:
????? ? 接口類和目標對象類都不變,在此基礎上增加一個代理工廠類,在Main類中建立目標對象和代理對象的聯系,然后代用代理對象的中同名方法
????? ? 代理工廠類:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy;/*** 創建動態代理對象* 動態代理不需要實現接口,但是需要知道接口的類型*/ public class ProxyFactory {private Object object;public ProxyFactory(Object object) {this.object = object;}//給目標對象生成代理對象public Object getProxyInstance() {return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(" --- start --- ");Object value = method.invoke(object, args);System.out.println(" --- end --- ");return object;}});} }????????Main類:
public class Main {public static void main(String args[]){// 目標對象Image img = new RealImage();System.out.println(img.getClass());// 給目標對象,創建代理對象Image proxy = (Image) new ProxyFactory(img).getProxyInstance();System.out.println(proxy.getClass());proxy.display();} }結果:
????
代理對象不需要實現接口,但是目標對象一定要實現接口,否則不能用動態代理? ??????
????????
總結
以上是生活随笔為你收集整理的Java设计模式(三) -- 代理模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: forward和redirect有什么区
- 下一篇: 代理模式(续)