標籤:word ack one div size 串連 throw tracking 擴充
類圖
/** * 遊戲者介面 * @author stone * */public interface IGamePlayer {// 登入遊戲public void login(String user, String password);// 殺怪,網路遊戲的主要特色public void killBoss();// 升級public void upgrade();}
/** * 遊戲者 * @author stone * */public class GamePlayer implements IGamePlayer {private String name = "";// 通過建構函式傳遞名稱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("登入名稱為" + user + " 的角色 " + this.name + "登入成功!");}// 升級,升級有非常多方法。花錢買是一種。做任務也是一種public void upgrade() {System.out.println(this.name + " 又升了一級。");}}
/** * client 對被代理對象不可見 */public class GamePlayerProxy implements IGamePlayer {private IGamePlayer gamePlayer = null;//被代理對象// 通過建構函式傳遞要對誰進行代練public GamePlayerProxy(String username) {this.gamePlayer = new GamePlayer(username);}// 代練殺怪public void killBoss() {this.gamePlayer.killBoss();}// 代練登入public void login(String user, String password) {this.gamePlayer.login(user, password);}// 代練升級public void upgrade() {this.gamePlayer.upgrade();}}
/* * client 對被代理對象不可見 */public class GamePlayerProxy2 implements IGamePlayer {private IGamePlayer gamePlayer = null;//被代理對象// 通過建構函式傳遞要對誰進行代練public GamePlayerProxy2(String username) {this.gamePlayer = new GamePlayer(username);}// 代練殺怪public void killBoss() {this.gamePlayer.killBoss();}// 代練登入public void login(String user, String password) {System.out.println("登入時間是:" + new Date().toLocaleString());this.gamePlayer.login(user, password);}// 代練升級public void upgrade() {this.gamePlayer.upgrade();System.out.println("升級時間是:" + new Date().toLocaleString());}}
/* * client 對被代理對象不可見 */public class GamePlayerProxy3 {private IGamePlayer gamePlayer;// 通過建構函式傳遞 被代練(代理)對象public GamePlayerProxy3(IGamePlayer gamePlayer) { this.gamePlayer = gamePlayer; System.out.println("我是一名代練,我玩的角色是別人的。能夠動態傳遞進來");}public IGamePlayer getProxy() {return (IGamePlayer) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]{IGamePlayer.class}, new MyInvocationHandler());}private class MyInvocationHandler implements InvocationHandler {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if (method.getName().equals("login")) {System.out.println("登入時間是:" + new Date().toLocaleString());} if (method.getName().equals("upgrade")) {System.out.println("升級時間是:" + new Date().toLocaleString());}method.invoke(gamePlayer, args);return null;}}}
/* * 代理模式:為其它對象提供一種代理以控制對這個對象的訪問。 * 在某些情況下,一個對象不適合或者不能直接引用還有一個對象,而代理對象能夠在client和目標對象之間起到中介的作用 * 長處 (1).職責清晰 真實的角色就是實現實際的商務邏輯,不用關心其它非本職責的事務。通過後期的代理完畢一件完畢事務。附帶的結果就是編程簡潔清晰。 (2).代理對象能夠在client和目標對象之間起到中介的作用,這樣起到了的作用和保護了目標對象的作用。 (3).高擴充性 模式結構 一個是真正的你要訪問的對象(目標類),一個是代理對象,真正對象與代理 對象實現同一個介面,先訪問代理類再訪問真正要訪問的對象。 在裝飾器模式和代理模式之間還是有非常多區別的。裝飾器模式關注於在一個對象上動態加入方法,然而代理模式關注於控制對對象的訪問。
換句話 說,用代理模式,代理類(proxy class)能夠對它的客戶隱藏一個對象的詳細資料。因此,當使用代理模式的時候,我們經常在一個代理類中建立一個對象的執行個體。 而且,當我們使用裝飾器模 式的時候。我們通常的做法是將原始對象作為一個參數傳給裝飾者的構造器。我們能夠用另外一句話來總結這些區別:使用代理模式,代理和真實對象之間的的關係通常在編譯時間就已經確定了,而裝飾者能夠在執行時遞迴地被構造。 */public class Test {public static void main(String[] args) {/* * 普通的靜態代理: client不知道被代理對象,由代理對象完畢其功能的調用 */IGamePlayer proxy = new GamePlayerProxy("X");System.out.println("開始時間是:" + new Date().toLocaleString());proxy.login("zhangSan", "abcd");proxy.killBoss();proxy.upgrade();System.out.println("結束時間是:" + new Date().toLocaleString());System.out.println();/* * 代理對象 增強了 被代理對象的功能 */IGamePlayer proxy2 = new GamePlayerProxy2("M");proxy2.login("lisi", "efg");proxy2.killBoss();proxy2.upgrade();System.out.println();/* * 動態代理:使用jdk提供的InvocationHandler,反射調用被代理對象的方法 * 結合java.reflect.Proxy 產生代理對象 * 動態傳入被代理物件建構InvocationHandler,在handler中的invoke時能夠增強被代理對象的方法的功能 * 或者說:(面向切面:)在什麼地方(連接點), 執行什麼行為(通知) * GamePlayerProxy3中是方法名為login時通知開始時間,upgrade時通知結束時間 */GamePlayerProxy3 dynamic = new GamePlayerProxy3(new GamePlayer("Y"));IGamePlayer dynamicPlayer = dynamic.getProxy();dynamicPlayer.login("wangwu", "1234");dynamicPlayer.killBoss();dynamicPlayer.upgrade();/* * 面向切面: 一些類似的商務邏輯須要加在眾多的地方。那們就能夠把它提取到切面中, 切面也就是事務切面:如日誌切面、許可權切面、業務切面 */}}
列印:
開始時間是:2014-10-8 17:19:05登入名稱為zhangSan 的角色 X登入成功!X 在打怪!
X 又升了一級。結束時間是:2014-10-8 17:19:05登入時間是:2014-10-8 17:19:05登入名稱為lisi 的角色 M登入成功。M 在打怪!
M 又升了一級!升級時間是:2014-10-8 17:19:05我是一名代練,我玩的角色是別人的,能夠動態傳遞進來登入時間是:2014-10-8 17:19:05登入名稱為wangwu 的角色 Y登入成功!Y 在打怪!升級時間是:2014-10-8 17:19:05Y 又升了一級!
Java 實現代理(Proxy)模式