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

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

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

    Calvin's Tech Space

    成于堅忍,毀于浮躁

       :: 首頁 :: 聯系 :: 聚合  :: 管理
     

    代理模式、動態代理和面向方面

        代理的意思很好理解,它借了我日常所用的代理的意思:就是本來自己自去做的某件事,由于某種原因不能直接做,而只能人代替你做,個被你來做事的人就是代理。比如要回家,由于你要上班,沒時間票,就得票中介代你購買就是一種代理模式。個情景可以形象的描述如下:

    class:火

    {

            票:

           {……}

    }

        站是票的地方,我只能在火到票。票的實質是火完成的。

    Class:票中介

    {

            票:

            {

                   收中介

                  .票;

    }

    }

        客找票中介票的候,調用票中介.票。票中介其做了兩件事,一是去火票,二是不能白幫你票,肯定要收中介。而你得到的好是不用直接去火票,省了票的時間用來上班。

        以上我們簡單了代理模式的情景和什么要使用代理模式,下面我以一個例子來具體分析一下JAVA中的代理模式。

        有一個信息管理系,用些用瀏覽信息的限,有些用瀏覽、添加和修改信息的限,有些用有除了上述的限,除信息的限,那么我最容易想到的做法如下:

    public class ViewAction

    {

            //userId

            ……

            String permission = ……;

           if(permission.equals(Constants.VIEW))

            {

                   System.out.println(“You could view the information……”);

                   ……

    }

    }

        其他的作都和瀏覽信息的作差不多。我來看這樣,很容易看出它的一些缺點來:第一、它把算和行都放在一個里,兩者的功能相互混在一起,容易造成思路的混亂,而且修改維護測試都不好;一句,它不滿職責。第二是客戶調用的候依具體的,造成展和運行期內的調用的困,不滿足依賴顛倒原

        既然有么多的問題,我有必要對該類進行重新設計。其大家早已想到,類應該使用代理模式。是啊,和我們買票的作一不能直接行那個作,而是要先檢查權限,然后才能行;先檢查權限,后行的那各就是一個代理,修改后的代如下:

    public interface Action

    {

            public void doAction();

    }

       首先是設計一個接口,用來滿足依賴顛倒原

    Public class ViewAction implements Action

    {

            public void doAction()

            {

                   //View

                   System.out.println(“You could view the information……”);

                   ……

    }

    }

        跟火站一,是作的真實執行者。

    Public class ProxyViewAction implements Action

    {

            private Action action = new ViewAction();

            public void doAction()

            {

                   //調的方法取得用戶權

                   if(Permission.getPermission(userId).equals(Constants.VIEW))

                   {

                          action.doAction();

    }

    }

    }

        是代理,很容易理解。在我ProxyViewAction中,除了做了客真正想要做的作:doAction()以外,還進行了外的檢查限。而作核心doAction()是在一個干干凈凈ViewAction行,只做核心作,其他的不關心,滿足了職責

        端通過調用代理作,而代理一是將限判斷和作的行分離開來,滿足了職責;二是實現了一個接口,從而滿足了依賴顛倒原。比第一個思路好了很多。

        代理又被稱委派,的是代理并不真正的行那個核心作,而是委派另外一個行,如ProxyView中,ProxyView并沒有真正doAction()方法,而是交ViewAction行。

        再來看代理ProxyViewAction,可以看到它不于接口Action,而且依于具體的實現ViewAction這樣對的系統擴展很不利,比如我Add作、Delete作、Modify作等等,我需要每一個作都寫一個代理,而些代理都做同的事情,先限判斷,然后再委派。所以我需要對這些代理再行一次抽象,它只依接口Action,而不依于具體的實現

        實現這樣的想法,我需要將代理中的具體實現提走,代理的使用者在運行期提供具體的實現類,即所的依注入,如下:

    Public class ProxyAction implements Action

    {

            private Action action;

            public ProxyAction(Action action)

            {

                   this.action = action;

    }

            public void doAction()

            {

                   //調的方法取得用戶權

                   if(Permission.getPermission(userId).equals(action.getClass().getName()))

                   {

                          action.doAction();

    }

    }

    }

        這樣,我就將所有實現Action接口的實現使用一個代理來代理它。除了ViewAction能用,以后展的AddAction       ModifyActionDeleteAction等等,都可以使用一個代理ProxyAction

        而我的客似如下:

    Action action = ProxyAction(new ViewAction);

    Action.doAction();

        過對代理的依注入,我使得代理初步有了一定展性。但是我們還要看到,個代理于某一個確定的接口。仍然不能滿足我實際要求,如我的系限控制一般是整個系統級的,這樣統級限控制,我在整個系里抽象出一個一的接口,可能會有多個接口,按照上面的代理模式,我需要每一個接口寫一個代理,同的功能都是一的。這顯然不是一個好地解決法。

        基于上面的原因,我需要解決一個系在沒有一的接口的情況下,一些零散的象的某一些作使用代理模式的問題JAVA API引入了動態代理或動態委派的技

        動態代理的核心是InvocationHandler接口,要使用動態代理就必須實現該接口。個接口的委派任是在invoke(Object proxy, Method m, Object[] args)方法里面實現的:

    //調用核心功能之前作一些

    ……

    //調用核心功能

    m.invoke(obj, args);

    //調用核心功能以后做一些

    ……

        可以看到動態代理其用的是反射機制來調用核心功能的:m.invoke(obj, args);正是種反射機制的使用使得我們調用核心功能更加靈活,而不用依于某一個具體的接口,而是依Object象。

        下面我來具體看看動態代理或動態委派如何使用:

    public class ProxyAction implements InvocationHandler {

    private Object action;

    public ProxyAction(Object action)

    {

           this.action = action;

    }

    public static Object getInstance(Object action)

    {

            return Proxy.newProxyInstance(action.getClass().getClassLoader(),

    action.getClass().getInterfaces(),new ProxyAction(action));

    }

    public Object invoke(Object proxy, Method m, Object[] args)

                   throws Throwable {

            Object result;

           try {

                          //在委派之前作作,如限判斷等

               System.out.println("before method " + m.getName());

                          //行委派

               result = m.invoke(action, args);

           } catch (InvocationTargetException e) {

               throw e.getTargetException();

           } catch (Exception e) {

               throw new RuntimeException("unexpected invocation exception: "

                      + e.getMessage());

           } finally {

                          //在委派之后做

               System.out.println("after method " + m.getName());

           }

           return result;

     

    }

    }

        個代理首先是實現InvocationHandler接口;然后在getInstance()方法里得到了代理例;在invoke()方法里實現代理功能,也很簡單

        下面我來看客端:

    Action action = (Action)ProxyAction.getInstance(new ViewAction());

    Action.doAction();

        可以看到代理類對接口的依移到了客端上,這樣,代理不依于某個接口。于同的代理ProxyAction,我也可以有如下的客調用:

    Engine engine = (Engine)ProxyAction.getInstance(new EngineImpl());

    Engine.execute();

        只要engineImpl類實現Engine接口,就可以像上面那使用。

        在我可以看到,動態代理的確是有相當的靈活性。但我也看到了,個代理寫起來比,而且也差不多每次都寫這樣千篇一律的西,只有委派前的作和委派后的作在不同的代理里有著不同,其他的西都需要照寫。如果這樣的代理寫多了,也會有一些冗余代理。需要我們進一步化,里我使用模板方法模式來對這個代理類進化,如下:

    public abstract class BaseProxy implements InvocationHandler {

    private Object obj;

    protected BaseProxy(Object obj)

    {

           this.obj = obj;

    }

    public static Object getInstance(Object obj,InvocationHandler instance)

    {

            return Proxy.newProxyInstance(obj.getClass().getClassLoader(),

    obj.getClass().getInterfaces(),instance);

    }

    public Object invoke(Object proxy, Method m, Object[] args)

                   throws Throwable {

            // TODO Auto-generated method stub

            Object result;

           try {

               System.out.println("before method " + m.getName());

               this.doBegin();

               result = m.invoke(obj, args);

           } catch (InvocationTargetException e) {

               throw e.getTargetException();

           } catch (Exception e) {

               throw new RuntimeException("unexpected invocation exception: "

                      + e.getMessage());

           } finally {

               System.out.println("after method " + m.getName());

               this.doAfter();

           }

           return result;

     

    }

    public abstract void doBegin();

    public abstract void doAfter();

    }

        這樣,代理的實現類只需要關注實現委派前的作和委派后的作就行,如下:

    public class ProxyImpl extends BaseProxy {

    protected ProxyImpl(Object o)

    {

           super(o);

    }

    public static Object getInstance(Object foo)

    {

            return getInstance(foo,new ProxyImpl(foo));

    }

    //委派前的

    public void doBegin() {

            // TODO Auto-generated method stub

           System.out.println("begin doing....haha");

    }

    //委派后的

    public void doAfter() {

            // TODO Auto-generated method stub

           System.out.println("after doing.....yeah");

    }

    }

        從上面的代,我可以看出代理實現類的確是簡單多了,只關注了委派前和委派后的作,是我一個代理真正需要關心的。

        至此,代理模式和動態代理已告一段落。我動態代理引申一點開去,來作為這篇文章的蛇足。

        話題就是面向方面的程,或者AOP。我看上面的ProxyImpl,它的兩個方法doBegin()doAfter()是做核心作之前和之后的兩個截取段。正是兩個截取段,卻是我AOP的基。在OOP里,doBegin(),核心作,doAfter()三個作在多個里始在一起,但他所要完成的邏輯卻是不同的,如doBegin()可能做的是限,在所有的里它都做限;而在每個里核心作卻各不相同;doAfter()可能做的是日志,在所有的里它都做日志。正是因在所有的里,doBegin()doAfter()都做的是同邏輯,因此我需要將它提取出來,獨分析、設計編碼就是我AOP的思想。

        這樣說來,我動態代理就能作為實現AOP的基了。好了,就說這么多,關于AOP,我可以去關注關于方面的知

    posted on 2009-08-12 16:51 calvin 閱讀(230) 評論(0)  編輯  收藏 所屬分類: Design Patterns

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 免费无码又爽又刺激高潮视频| 亚洲国产综合AV在线观看| 国产成人精品免费大全| 免费看国产精品麻豆| 337p日本欧洲亚洲大胆人人 | 色老头综合免费视频| 亚洲无码精品浪潮| 暖暖免费在线中文日本| 日韩一级片免费观看| 免费在线观看一区| 免费又黄又爽又猛大片午夜 | 日韩免费观看一级毛片看看| 野花香在线视频免费观看大全 | 午夜免费福利视频| 亚洲成人免费在线| 国产一级黄片儿免费看| 亚洲av日韩综合一区久热| 亚洲成人免费电影| 亚洲综合无码无在线观看| 免费高清资源黄网站在线观看| 国产AV无码专区亚洲AV琪琪| 亚洲欧洲国产成人综合在线观看 | 亚欧人成精品免费观看| 亚洲色少妇熟女11p| 亚洲国产精品一区二区三区久久| 中文字幕不卡免费视频| 91亚洲国产成人久久精品网站| 一二三四在线播放免费观看中文版视频| 最新亚洲卡一卡二卡三新区| 亚洲国产高清在线一区二区三区| 永久免费av无码网站yy| 亚洲伊人久久大香线蕉影院| 四虎永久免费地址在线观看| 两个人看www免费视频| 亚洲一级毛片在线观| 亚洲国产精品成人AV无码久久综合影院| 久久国产精品免费看| 亚洲欧美成人av在线观看| 亚洲综合AV在线在线播放| 成人黄18免费视频| 免费观看91视频|