摘要:定義代理類的接口計算費用定義代理類通過構造函數(shù)傳遞對誰代練代練代練登錄代練升級計算費用在上方中先實現(xiàn)了接口,然后再調(diào)用該接口中的方法,完成結算動態(tài)代理動態(tài)代理在實現(xiàn)階段不用關系代理誰。在運行階段指定代理那個對象。
栗子
定義一個游戲者接口
public interface IGamePlayer{ // 登錄游戲 public void login(String user, String password); // 殺怪 public void killBoss(); // 升級 public void upgrade(); }
定義游戲著類,實現(xiàn)游戲者接口
public class GamePlay implements IGamePlayer{ private String name = ""; // 構造函數(shù)注入 public GamePlayer(String _name){ this.name = _name; } // 打怪 public void killBoss(){ System.out.println(this.name + "在打怪"); } // 登錄 public void login(String user, String password){ System.out.println("登錄"); } // 升級 public void upgrade(){ System.out.println(this.name + "升級"); } }
場景類
public class Client{ public static void main(String[] args){ // 定義一個玩家 IGamePlayer player = new GamePlayer("張三"); // 開始游戲 System.out.println("開始游戲"); // 登錄 player.login("zangshan", "password"); // 殺怪 player.killBoss(); // 升級 player.upgrade(); // 記錄結束時間 } }改進
增加一個代練
public class GamePlayerProxy implements IGamePlayer{} private IGamePlayer gamePlayer = null; // 構造函數(shù)注入 public GamePlayerProxy(IGamePlayer _gamePlayer){ this.gamePlayer = _gamePlayer; } // 代練 public void killBoss(){ this.gamePlayer.killBoss(); } // 代練登錄 public void login(String user, String password){ this.gamePlayer.login(user, password); } // 代練升級 public void upgrade(){ this.gamePlayer.upgrade(); } }
場景類如下
public class Client { public static void main(String[] args){ // 定義一個玩家 IGamePlayer player = new GamePlayer("張三"); // 定義代練者 IGamePlayer proxy = new GamePlayerProxy(player); // 開始游戲 proxy.login("zangshan", "password"); proxy.killBoss(); // 升級 proxy.upgrade(); } }擴展
代理分為普通代理和透明代理
普通代理普通代理要求客戶端只能訪問代理角色,不能訪問真實角色。
// 普通代理的游戲者 public class GamePlayer implemnts IGamePlayer{ private String name = ""; // 構造函數(shù)傳遞姓名 public GamePlayer(IGamePlayer _gamePlayer, String _name)throws Exception{ if(_gamePlayer == null){ throw new Exception("不能創(chuàng)建真實角色"); }else{ this.name = _name; } } // 打怪 public void killBoss(){ System.out.println(this.name + "在打怪!"); } // 登錄 public void login(String user. String password){ } // 升級 public void upgrade(){ } }
// 普通代理的代理者 public class GamePlayerProxy implements IGamePlayer{ private IGamePlayer gamePlayer = null; // 構造函數(shù)注入 public GamePlayerProxy(String name){ try{ gamePlayer = new GamePlayer(this, name); }catch(Exception e){ } } // 代練 public void killBoss(){ this.gamePlayer.killBoss(); } // 登錄 public void login(String user, String password){ this.gamePlayer.login(user, password); } // 升級 public void upgrade(){ this.gamePlayer.upgrade(); } }
最后場景類
public class Client{ public static void main(String[] args){ // 定義代練者 IGamePlayer proxy = new GamePlayerProxy(""); // 開始 proxy.login("", "password"); // 升級 proxy.upgrade(); // 記錄結束時間 } }強制代理
public interface IGamePlayer{ // 登錄 public void login(String user, String password); // 殺怪 public void killBoss(); // 升級 public void upgrade(); // 找代理 public IGamePlayer getProxy(); }
// 強制代理的真實角色 public class GamePlayer implements IGamePlayer{ private String name = ""; // 找代理 private IGamePlayer proxy = null; public GamePlayer(String _name){ this.name = _name; } // 找到代理 public IGamePlayer getProxy(){ this.proxy = new GamePlayerProxy(this); return this.proxy; } // 打怪 public void killBoss(){ if(this.isProxy()){ }else{ } } // 登錄 public void login(String user, String password){ if(this.isProxy()){ }else{ } } // 升級 public void upgrade(){ if(this.isProxy()){ }else{ } } // 是否代理 private boolean isProxy(){ if(this.proxy == null){ return false; }else{ return true; } } }
// 強制代理代理類 public class GamePlayerProxy implements IGamePlayer{ private IGamePlayer gamePlayer = null; // 構造函數(shù)傳遞用戶名 public GamePlayerProxy(IGamePlayer _gaemPlayer){ this.gamePlayer = _gamePlayer; } // 代練 public void killBoss(){ this.gaemPlayer.killBoss(); } // 登錄 public void login(String user, String password){ this.gamePlayer.login(user, password); } // 升級 public void upgrade(){ this.gamePlayer.upgrade(); } // 如果代理沒有,為自身 public IGamePlayer getProxy(){ return this; } }
最后書寫場景類
public class Client{ public static void main(String[] args){ // 定義游戲角色 IGamePlayer player = new GamePlayer("張三"); // 開始游戲 player.login("zangshan", "password"); // 殺怪 player.killBoss(); // 升級 player.upgrade(); } }
強制代理場景類
public class Client{ public static void main(String[] args){ // 定義游戲角色 IGamePlayer player = new GamePlayer("張三"); // 獲得指定代理 IGamePlayer proxy = player.getProxy(); // 開始打游戲 proxy.login("zangshan", "password"); // 開始殺怪 proxy.killBoss(); // 升級 proxy.upgrade(); } }代理需要擁有個性
即一個類可以實現(xiàn)多個接口,完成不同任務的整合。
// 定義代理類的接口 public interface IProxy{ // 計算費用 public void count(); }
// 定義代理類 public class GamePlayerProxy implements IGamePlayer, IProxy{ private IGamePlayer gamePlayer = null; // 通過構造函數(shù)傳遞對誰代練 public GamePlayerProxy(IGamePlayer _gamePlayer){ this.gamePlayer = _gamePlayer; } // 代練 public voidkillBoss(){ this.gamePlayer.killBoss(); } // 代練登錄 public void login(String user, String password){ this.gamePlayer.login(user, password); } // 代練升級 public void upgrade(){ this.gamePlayer.upgrade(); this.count(); } // 計算費用 public void count(){ } }
在上方中先實現(xiàn)了IProxy接口,然后再調(diào)用該接口中的方法,完成結算.動態(tài)代理
動態(tài)代理在實現(xiàn)階段不用關系代理誰。在運行階段指定代理那個對象。
即,在實現(xiàn)的時候不用關心代理誰,只需要在運行的時候指定代理那個對象
// 動態(tài)代理類 public class GamePlayIH implements invocationHandler{ // 被代理著 Class cls = null; // 被代理的實例 Object obj = null; // 我要代理誰 public GamePlayerIH(Object _obj){ this.obj = _obj; } // 調(diào)用被代理的方法 public Object invoke(Object proxy, Method method, Object[] args)throws Throwable{ Object result = method.invoke(this.obj, args); return result; } }
// 動態(tài)代理場景類 public class Client{ public static void main(String[] args)throws Throwable{ // 定義一個癡迷的玩家 IGamePlayer player = new GamePlayer("張三"); // 定義一個handler invocationHandler handler = new GamePlayIH(player); // 開始游戲,記錄時間戳 System.out.println("開始時間"); // 獲得類的父類加載器 ClassLoader cl = player.getClass().getClassLoader(); // 動態(tài)產(chǎn)生代理者 IGamePlayer proxy = (IGamePlayer)proxy.newProxyinstance(cl, new Class[]{IGamePlayer.class}, handler); // 登錄 proxy.login("zhangsan", "password"); // 開始 proxy.killBoss(); // 升級 proxy.upgrade(); // 記錄結束時間 } }
ps 動態(tài)代理直接在需要代理的時候直接動態(tài)生成代理
此時,如果需要登錄的時候發(fā)送消息,此時修改如下
public class GamePlayIH implements invocationHandler { // 被代理著 Class cls = null; // 被代理的實例 Object obj = null; // 我要代理誰 public GamePlayIH(Object _obj){ this.obj = _obj; } // 調(diào)用代理的方法 public Object invoke(Object proxy, Method method, Object[] args){ Objetc result = method.invoke(this.obj, args); // 如股票是登錄方法,發(fā)送消息 if(method.getName().equalslgnoreCase("login")){ } return result; } }
這樣就完成的消息的發(fā)送
最后// 抽象主題 public interface Subject{ // 業(yè)務操作 public void doSomething(String str); } // 真實主題 public class RealSubject implements Subject{ // 業(yè)務操作 public void doSomething(String str){ /// 業(yè)務操作 } }
下面是動態(tài)代理類該動態(tài)代理類通過構造函數(shù)將將對象傳入。
由于實現(xiàn)了invoke方法,此時會被調(diào)度到該方法
public class MyinvocationHandler implements invocationHandler{ // 被代理的對象 private Object target = null; // 構造函數(shù)傳遞 public MyInvocationHandler(Object _obj){ this.target = _obj; } // 代理方法 public Object invoke(Object proxy, Method method, Object[] args)throws Throwable{ // 執(zhí)行被代理的方法 return method.invoke(this.target, args); } }
下面是動態(tài)代理類
public class DynamiProxy{ public static T newProxyinstance(ClassLoader loader, Class>[] interfaces, invocationHandler h){ // 尋找JoinPoint連接點 // 尋找連接點,即方法執(zhí)行前后的連接點 if(true){ // 執(zhí)行一個前置通知 new BeforeAdvice().exec(); } // 執(zhí)行切面 // 并返回結果 return (T)Proxy.newProxyinstance(loader.interfaces, h); } }
下面實現(xiàn)通知
public interface IAdvice{ public void exec(); }
public class BeforeAdvice implements IAdvice{ public void exec(){ System.out.println("我是通知"); } }
最后書寫場景類
public class Client{ public static void main(String[] args){ // 定義一個主題 Subject subject = new RealSUbject(); // 定義一個前置通知 invocationHandler handler = new MyinvocationHandler(subject); // 定義主題代理 Subject proxy = DynamicProxy.newProxyinstance(subject.getClass().getClassLoader(), subject.getClass().getinterfaces(),handler); // 最后執(zhí)行這個代理的接口 proxy.doSomething("Finish"); } }
總結 程序的執(zhí)行的過程,在DynamicProxy類中,使用newProxyinstance方法重寫生成一個對象,這個對象是其代理對象,一個類的動態(tài)代理是這樣的過程
先場景類需要調(diào)用doSomething方法的時候,進入動態(tài)代理類,當動態(tài)代理類調(diào)用Proxy.newProxyinstance的時候,會調(diào)度到代理方法,由代理方法再執(zhí)行method.invoke(this.target, args);完成對代理的調(diào)用。
https://www.iming.info/dai-li...
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/73152.html
摘要:下面總結了它倆的異同相同點都需要實現(xiàn)同一個接口或者繼承同一個抽象類,并且代理角色和裝飾角色都持有被代理角色和構件角色的引用。 寫完上一篇之后有小伙伴問我有沒有寫過代理模式,想看看我的理解。原本我的設計模式系列是按照創(chuàng)建型-行為型-結構型的順序?qū)懴氯サ?,既然小伙伴誠心誠意了,我就大發(fā)慈悲的穿插一篇代理模式。開玩笑,題外話。 說起代理模式,就不由得想起經(jīng)紀人,說起經(jīng)紀人,就想起了...對,...
摘要:簡介代理模式和裝飾者模式是兩種常見的設計模式。這里通過構造函數(shù)的參數(shù)將被代理對象傳入到代理中,也可以通過其它方式,如提供一個方法。下面是的代碼輸出首先依然是先創(chuàng)建一個需要被代理的對象,然后把它傳入到的構造函數(shù)中。 簡介 代理模式和裝飾者模式是兩種常見的設計模式。代理模式是為其它對象提供一種代理以控制對這個對象的訪問。在某些情況下,一個對象不適合或者不能直接引用另一個對象,而代理對象可以...
摘要:代理設計模式代理模式為其他對象提供一種代理以控制對這個對象的訪問。代理模式是常見的設計模式之一是指不直接調(diào)用實際的對象,而是通過代理對象,來間接的調(diào)用實際的對象。對象類定義了代理對象所代表的目標對象。 代理設計模式 代理模式:為其他對象提供一種代理以控制對這個對象的訪問。代理模式是常見的設計模式之一,是指不直接調(diào)用實際的對象,而是通過代理對象,來間接的調(diào)用實際的對象。為什么要采用這種間...
閱讀 1639·2021-11-04 16:11
閱讀 3363·2021-09-09 11:33
閱讀 1611·2019-08-30 15:54
閱讀 641·2019-08-30 15:44
閱讀 3210·2019-08-30 15:43
閱讀 2589·2019-08-30 13:06
閱讀 1724·2019-08-29 17:00
閱讀 923·2019-08-29 15:33