<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      靜態代理和動態代理

      代理模式主要應用的場景是:當某些類由于一些原因不方便直接訪問或者修改,需要通過一個代理類作為橋梁,來實現間接訪問并擴展功能。

      靜態代理

      假設我們有一個游戲模塊,包含各種不同類型的游戲,我們需要在游戲開始和結束的時候加入提示,讓我們看看利用靜態代理怎么實現這個需求:

      上面的UML圖定義了一個游戲接口(Game),格斗游戲類(FightingGame)和射擊游戲類(ShootingGame)分別實現了該接口,代碼如下: ```java public interface Game { public void playGame(); } ``` ```java public class FightingGame implements Game { public void playGame() { System.out.println("FightingGame"); } } ``` ```java public class ShootingGame implements Game { public void playGame() { System.out.println("ShootingGame"); } } ``` 假如我們要在游戲開始前打印"Game Start",在游戲結束時打印"Game Over",為此我們定義一個代理類(GameProxy): ```java public class GameProxy implements Game {
      private Game game;
      
      public GameProxy(Game game) {
          this.game = game;
      }
      
      public void playGame() {
          if(game!=null) {
              System.out.println("Game Start!");
              game.playGame();
              System.out.println("Game Over!");
          }
      }
      

      }

      新建一個測試類:
      ```java
      public class MyTestClass {
      
          @Test
          public void demo01() {
              ShootingGame shootingGame = new ShootingGame();
              Game game = new GameProxy(shootingGame);
              game.playGame();
          }
      
          @Test
          public void demo02() {
              FightingGame fightingGame = new FightingGame();
              Game game = new GameProxy(fightingGame);
              game.playGame();
          }
      }
      

      運行兩個測試方法,將分別打印出:

      Game Start!
      FightingGame
      Game Over!
      
      Game Start!
      ShootingGame
      Game Over!
      

      動態代理

      我們用另一個游戲場景來演示動態代理的使用(∩_∩)。
      在LOL里有一個英雄是狂野女獵手(俗稱豹女),她有人形和獵豹兩種形態,每種形態下都有對應的技能,UML如圖:

      上面的UML圖定義了人形態(Human)和獵豹形態(Leopard)兩種接口,女獵手類(Huntress)同時實現了這兩種接口,代碼如下:

      public interface Human {
      
          /** 變身為獵豹 */
          public void transformIntoLeopard();
      
          /** 向目標投擲標槍,返回傷害值 */
          public int throwJavelin(String enemy);
      
          /** 在指定位置放置陷阱 */
          public void setTrap(int x, int y);
      }
      
      public interface Leopard {
      
          /** 變身為人形 */
          public void transformIntoHuman();
      
          /** 爪擊,返回傷害值 */
          public int clawAttack();
      }
      
      public class Huntress implements Human, Leopard {
          public void transformIntoLeopard() {
              System.out.println("變身為獵豹");
          }
      
          public int throwJavelin(String enemy) {
              System.out.println("對" + enemy + "造成100點傷害");
              return 100;
          }
      
          public void setTrap(int x, int y) {
              System.out.println("在(" + x + ", " + y + ")處放置了一個陷阱");
          }
      
          public void transformIntoHuman() {
              System.out.println("變身為人形");
          }
      
          public int clawAttack() {
              System.out.println("對前方敵人共造成200點傷害");
              return 200;
          }
      }
      

      不同于靜態代理需要建立實體代理類,我們直接在測試模塊用代碼創建動態代理:

      public class MyTestClass {
          @Test
          public void demo01() {
              Huntress huntress = new Huntress();
      
              Object proxy = Proxy.newProxyInstance(
                      huntress.getClass().getClassLoader(),
                      Huntress.class.getInterfaces(),
                      new HuntressInvocationHandler(huntress));
      
              Human humanProxy = (Human)proxy;
              humanProxy.transformIntoLeopard();
              humanProxy.setTrap(25,50);
              humanProxy.throwJavelin("武器大師");
      
              Leopard leopardProxy = (Leopard)proxy;
              leopardProxy.transformIntoHuman();
              leopardProxy.clawAttack();
          }
      }
      

      Proxy.newProxyInstance方法的聲明如下:

      public static Object newProxyInstance(ClassLoader loader,
                                                Class<?>[] interfaces,
                                                InvocationHandler h);
      

      loader -- 指定用哪個類加載器去加載代理類
      interfaces -- 代理類需要實現的接口列表,在本例中length是2
      h -- 可簡單理解為"方法調用處理器實例",InvocationHandler是JDK中專門用于實現動態代理的接口,它有一個invoke方法去處理代理實例上的方法調用并返回結果

      下面的代碼定義了一個HuntressInvocationHandler,它繼承自InvocationHandler:

      import java.lang.reflect.InvocationHandler;
      import java.lang.reflect.Method;
      import java.util.Arrays;
      
      public class HuntressInvocationHandler implements InvocationHandler {
      
          public Huntress huntress;
          public HuntressInvocationHandler(Huntress huntress) {
              this.huntress = huntress;
          }
      
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
              System.out.println("------------------------------------------");
              System.out.println("當前方法:" + method.getName());
              String argsString = Arrays.toString(args);
              System.out.println("當前參數:" + argsString);
      
              System.out.println("*****開始施放技能!*****");
              Object result = method.invoke(huntress, args);
              System.out.println("*****結束施放技能!*****");
              if(result!=null) {
                  System.out.println("*****造成"+result+"點傷害*****");
              }
      
              return result;
          }
      }
      

      invoke方法的聲明如下:

          public Object invoke(Object proxy, Method method, Object[] args)
              throws Throwable;
      

      proxy -- 代理類本身的一個實例。這個參數大部分情況下不需要關注。
      method -- 當前調用的方法
      args -- 當前調用方法的參數列表

      運行測試方法,將打印下列信息:

      --------------------------------------------------------
      當前方法:transformIntoLeopard
      當前參數:null
      *****開始施放技能!*****
      變身為獵豹
      *****結束施放技能!*****
      --------------------------------------------------------
      當前方法:setTrap
      當前參數:[25, 50]
      *****開始施放技能!*****
      在(25, 50)處放置了一個陷阱
      *****結束施放技能!*****
      --------------------------------------------------------
      當前方法:throwJavelin
      當前參數:[武器大師]
      *****開始施放技能!*****
      對武器大師造成100點傷害
      *****結束施放技能!*****
      *****造成100點傷害*****
      --------------------------------------------------------
      當前方法:transformIntoHuman
      當前參數:null
      *****開始施放技能!*****
      變身為人形
      *****結束施放技能!*****
      --------------------------------------------------------
      當前方法:clawAttack
      當前參數:null
      *****開始施放技能!*****
      對前方敵人共造成200點傷害
      *****結束施放技能!*****
      *****造成200點傷害*****
      

      總結

      靜態代理要求代理類和委托類實現同一個接口,代理類在編譯期生成,效率高。相應缺點是會多出一些代理類。
      動態代理不要求代理類和委托類實現同一個接口(沒有實現接口的類無法使用動態代理),它是在程序運行時根據需要動態創建目標類的代理對象,但由于它是通過反射來代理方法,在性能上會有所消耗。

      posted @ 2019-09-10 11:21  CoderWayne  閱讀(324)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 久久亚洲精精品中文字幕| 松江区| 韩国精品一区二区三区在线观看| 国产成人午夜福利在线观看| 国产偷国产偷亚洲清高APP| 337p西西人体大胆瓣开下部| 亚洲一区二区无码影院| 99精品国产中文字幕| 亚洲精品无amm毛片| 亚洲国产成人va在线观看天堂| 久久国产成人高清精品亚洲 | 免费人成在线观看网站| 亚洲成人网在线观看| 亚洲男人精品青春的天堂| 亚洲中文字幕无码爆乳| 天天澡天天揉揉av无码| 美女禁区a级全片免费观看| 巨大黑人极品videos精品| 丰满妇女强制高潮18xxxx | 国产精品va在线观看无码不卡| 久久av高潮av喷水av无码| 国99久9在线 | 免费| 又黄又爽又色的免费网站| 国产区精品福利在线熟女| 熟女系列丰满熟妇AV| julia无码中文字幕一区| 国产激情国产精品久久源| 日韩中av免费在线观看| 国产日韩精品一区在线不卡| 国产三级a三级三级| 亚洲人成人一区二区三区| 亚洲高清免费在线观看| 99热成人精品热久久66| 日本高清久久一区二区三区 | 护士张开腿被奷日出白浆| 91久久国产成人免费观看| h无码精品动漫在线观看| 一区二区在线观看成人午夜| 亚洲中文字幕无码中文字| 国产成人无码免费视频麻豆| 久久夜色精品国产噜噜亚洲sv|