<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    細心!用心!耐心!

    吾非文人,乃市井一俗人也,讀百卷書,跨江河千里,故申城一游; 一兩滴辛酸,三四年學業,五六點粗墨,七八筆買賣,九十道人情。

    BlogJava 聯系 聚合 管理
      1 Posts :: 196 Stories :: 10 Comments :: 0 Trackbacks
    延續 Proxy模式(一) 的議題,來看看實現代理的兩種方式:Static Proxy與Dynamic Proxy。嚴格來說這是屬於模式的實現方式,不過藉由實例可以更瞭解Proxy模式的應用。

    先來看個例子,這個例子是記錄(log)動作,程式中很常需要為某些動作或事件作下記錄,以便在事後檢視或是作為除錯時的資訊,一個最簡單的例子如下:
    • HelloSpeaker.java
    import java.util.logging.*; 

    public class HelloSpeaker {
    private Logger logger =
    Logger.getLogger(this.getClass().getName());

    public void hello(String name) {
    logger.log(Level.INFO, "hello method starts....");

    System.out.println("Hello, " + name);

    logger.log(Level.INFO, "hello method ends....");
    }
    }

    HelloSpeaker在執行hello()方法時,您希望能記錄該方法已經執行及結束,最簡單的作法就是如上在執行的前後加上記錄動作,然而 Logger介入了HelloSpeaker中,記錄這個動作並不屬於HelloSpeaker,這使得HelloSpeaker增加了非業務上需要的邏輯在當中。

    想想如果程式中這種記錄的動作到處都有需求,上面這種寫法勢必造成必須複製記錄動作的程式碼,使得維護記錄動作的困難度加大。如果不只有記錄動作,有一些非物件本身職責的相關動作也混入了物件之中(例如權限檢查、事務管理等等),會使得物件的負擔更形加重,甚至混淆了物件的職責,物件本身的職責所佔的程式碼,或許遠小於這些與物件職責不相關動作的程式碼。

    怎麼辦,用下面的方法或許好一些,先定義一個介面,然後實作該介面:
    • IHello.java
    public interface IHello { 
    public void hello(String name);
    }

    • HelloSpeaker.java
    public class HelloSpeaker implements IHello { 
    public void hello(String name) {
    System.out.println("Hello, " + name);
    }
    }

    接下來實作一個代理物件HelloProxy:
    • HelloProxy.java
    import java.util.logging.*; 

    public class HelloProxy implements IHello {
    private Logger logger =
    Logger.getLogger(this.getClass().getName());
    private IHello helloObject;

    public HelloProxy(IHello helloObject) {
    this.helloObject = helloObject;
    }

    public void hello(String name) {
    logger.log(Level.INFO, "hello method starts....");

    helloObject.hello(name);

    logger.log(Level.INFO, "hello method ends....");
    }
    }

    執行時可以如此:
    IHello helloProxy = new HelloProxy(new HelloSpeaker());
    helloProxy.hello("Justin");

    代理物件HelloProxy將代理真正的HelloSpeaker來執行hello(),並在其前後加上記錄的動作,這使得 HelloSpeaker在撰寫時不必介入記錄動作,HelloSpeaker可以專心於它的職責。

    這是Static Proxy的基本範例,然而如您所看到的,代理物件的一個介面只服務於一種類型的物件,而且如果要代理的方法很多,勢必要為每個方法進行代理, Static Proxy在程式規模稍大時就必定無法勝任。

    Java在JDK 1.3之後加入協助開發Dynamic Proxy功能的類別,我們不必為特定物件與方法撰寫特定的代理,使用Dynamic Proxy,可以使得一個handler服務於各個物件,首先,一個handler必須實現 java.lang.reflect.InvocationHandler:
    • LogHandler.java
    import java.util.logging.*; 
    import java.lang.reflect.*;

    public class LogHandler implements InvocationHandler {
    private Logger logger =
    Logger.getLogger(this.getClass().getName());
    private Object delegate;

    public Object bind(Object delegate) {
    this.delegate = delegate;
    return Proxy.newProxyInstance(
    delegate.getClass().getClassLoader(),
    delegate.getClass().getInterfaces(),
    this);
    }

    public Object invoke(Object proxy,
    Method method,
    Object[] args) throws Throwable {
    Object result = null;
    try {
    logger.log(Level.INFO,
    "method starts..." + method);
    result = method.invoke(delegate, args);
    logger.log(Level.INFO,
    "method ends..." + method);
    } catch (Exception e){
    logger.log(Level.INFO, e.toString());
    }
    return result;
    }
    }

    InvocationHandler的invoke()方法會傳入被代理物件的方法名稱與執行參數實際上要執行的方法交由method.invoke (),並在其前後加上記錄動作,method.invoke()傳回的物件是實際方法執行過後的回傳結果。

    Dynamic Proxy必須宣告介面,實作該介面,例如:
    • IHello.java
    public interface IHello { 
    public void hello(String name);
    }

    • HelloSpeaker.java
    public class HelloSpeaker implements IHello { 
    public void hello(String name) {
    System.out.println("Hello, " + name);
    }
    }

    java.lang.reflect.Proxy的newProxyInstance()依要代理的物件、介面與handler產生一個代理物件,我們可以使用下面的方法來執行程式:
    LogHandler logHandler = new LogHandler();
    IHello helloProxy = (IHello) logHandler.bind(
    new HelloSpeaker());
    helloProxy.hello("Justin");

    LogHandler不在服務於特定物件與介面,而HelloSpeaker也不用插入任何有關於記錄的動作,它不用意識到記錄動作的存在。
    posted on 2007-04-17 10:38 張金鵬 閱讀(489) 評論(0)  編輯  收藏 所屬分類: Structural 模式
    主站蜘蛛池模板: 亚洲综合色成在线播放| 午夜在线亚洲男人午在线| 日本h在线精品免费观看| 男人的好看免费观看在线视频 | 成年女人免费v片| 亚洲偷自精品三十六区| 91视频免费网站| 国产亚洲精品无码拍拍拍色欲| 中文字幕亚洲精品无码| 歪歪漫画在线观看官网免费阅读 | 亚洲精品天堂在线观看| 久久九九AV免费精品| 久久久久久亚洲av成人无码国产| 国产亚洲精品精品精品| 四虎影在线永久免费四虎地址8848aa| 亚洲国产成人超福利久久精品| 中文字幕无码免费久久| 亚洲高清免费视频| 一级毛片成人免费看a| 毛片免费观看网址| 亚洲国产欧美国产综合一区| 国产在线19禁免费观看| 日本特黄特色AAA大片免费| 亚洲中文字幕无码专区| 中国一级毛片视频免费看| 亚洲国产精品日韩专区AV| WWW国产成人免费观看视频| 亚洲精品中文字幕乱码三区| 无码精品国产一区二区三区免费| 国产AⅤ无码专区亚洲AV| 另类小说亚洲色图| 国产亚洲精品自在线观看| 好紧我太爽了视频免费国产| 97亚洲熟妇自偷自拍另类图片 | 亚洲AV午夜成人影院老师机影院| 一级女人18片毛片免费视频| 免费观看午夜在线欧差毛片 | 免费人妻无码不卡中文字幕系| 亚洲韩国精品无码一区二区三区| igao激情在线视频免费| 亚洲福利精品电影在线观看|