类图
1. /**
2. * 游戏者接口
3. *
4. */
5. public interface IGamePlayer {
6.
7. // 登录游戏
8. public void login(String user, String password);
9.
10. // 杀怪,网络游戏的主要特色
11. public void killBoss();
12.
13. // 升级
14. public void upgrade();
15.
16. }
1. /**
2. * 游戏者
3. *
4. */
5. public class GamePlayer implements IGamePlayer {
6.
7. private String name = "";
8.
9. // 通过构造函数传递名称
10. public GamePlayer(String _name) {
11. this.name = _name;
12. }
13.
14. // 打怪,最期望的就是杀老怪
15.
16. public void killBoss() {
17.
18. this.name + " 在打怪!");
19.
20. }
21.
22. // 进游戏之前你肯定要登录吧,这是一个必要条件
23. public void login(String user, String password) {
24. "登录名为" + user + " 的角色 " + this.name + "登录成功!");
25. }
26.
27. // 升级,升级有很多方法,花钱买是一种,做任务也是一种
28. public void upgrade() {
29. this.name + " 又升了一级!");
30. }
31.
32. }
1. /**
2. * 客户端 对被代理对象不可见
3. */
4. public class GamePlayerProxy implements IGamePlayer {
5.
6. private IGamePlayer gamePlayer = null;//被代理对象
7.
8. // 通过构造函数传递要对谁进行代练
9. public GamePlayerProxy(String username) {
10. this.gamePlayer = new GamePlayer(username);
11. }
12.
13. // 代练杀怪
14. public void killBoss() {
15. this.gamePlayer.killBoss();
16. }
17.
18. // 代练登录
19. public void login(String user, String password) {
20. this.gamePlayer.login(user, password);
21. }
22.
23. // 代练升级
24. public void upgrade() {
25. this.gamePlayer.upgrade();
26. }
27.
28. }
1. /*
2. * 客户端 对被代理对象不可见
3. */
4. public class GamePlayerProxy2 implements IGamePlayer {
5.
6. private IGamePlayer gamePlayer = null;//被代理对象
7.
8. // 通过构造函数传递要对谁进行代练
9. public GamePlayerProxy2(String username) {
10. this.gamePlayer = new GamePlayer(username);
11. }
12.
13. // 代练杀怪
14. public void killBoss() {
15. this.gamePlayer.killBoss();
16. }
17.
18. // 代练登录
19. public void login(String user, String password) {
20. "登录时间是:" + new Date().toLocaleString());
21. this.gamePlayer.login(user, password);
22. }
23.
24. // 代练升级
25. public void upgrade() {
26. this.gamePlayer.upgrade();
27. "升级时间是:" + new Date().toLocaleString());
28. }
29.
30. }
1. /*
2. * 客户端 对被代理对象不可见
3. */
4. public class GamePlayerProxy3 {
5.
6. private IGamePlayer gamePlayer;
7. // 通过构造函数传递 被代练(代理)对象
8. public GamePlayerProxy3(IGamePlayer gamePlayer) {
9. this.gamePlayer = gamePlayer;
10. "我是一名代练,我玩的角色是别人的,可以动态传递进来");
11. }
12.
13. public IGamePlayer getProxy() {
14. return (IGamePlayer) Proxy.newProxyInstance(this.getClass().getClassLoader(),
15. new Class[]{IGamePlayer.class}, new MyInvocationHandler());
16. }
17.
18. private class MyInvocationHandler implements InvocationHandler {
19.
20. @Override
21. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
22. if (method.getName().equals("login")) {
23. "登录时间是:" + new Date().toLocaleString());
24. if (method.getName().equals("upgrade")) {
25. "升级时间是:" + new Date().toLocaleString());
26. }
27. method.invoke(gamePlayer, args);
28. return null;
29. }
30.
31. }
32. }
1. /*
2. * 代理模式:为其他对象提供一种代理以控制对这个对象的访问。
3. * 在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用
4. * 优点
5. (1).职责清晰
6. 真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。
7. (2).代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了的作用和保护了目标对象的作用。
8. (3).高扩展性
9. 模式结构
10. 一个是真正的你要访问的对象(目标类),一个是代理对象,真正对象与代理
11. 对象实现同一个接口,先访问代理类再访问真正要访问的对象。
12.
13. 在装饰器模式和代理模式之间还是有很多差别的。装饰器模式关注于在一个对象上动态的添加方法,然而代理模式关注于控制对对象的访问。
14. 换句话 说,用代理模式,代理类(proxy class)可以对它的客户隐藏一个对象的具体信息。因此,当使用代理模式的时候,我们常常在一个代理类中创建一个对象的实例。
15. 并且,当我们使用装饰器模 式的时候,我们通常的做法是将原始对象作为一个参数传给装饰者的构造器。
16. 我们可以用另外一句话来总结这些差别:使用代理模式,代理和真实对象之间的的关系通常在编译时就已经确定了,而装饰者能够在运行时递归地被构造。
17. */
18. public class Test {
19. public static void main(String[] args) {
20. /*
21. * 普通的静态代理: 客户端不知道被代理对象,由代理对象完成其功能的调用
22. */
23. new GamePlayerProxy("X");
24. "开始时间是:" + new Date().toLocaleString());
25. "zhangSan", "abcd");
26. proxy.killBoss();
27. proxy.upgrade();
28. "结束时间是:" + new Date().toLocaleString());
29.
30. System.out.println();
31.
32. /*
33. * 代理对象 增强了 被代理对象的功能
34. */
35. new GamePlayerProxy2("M");
36. "lisi", "efg");
37. proxy2.killBoss();
38. proxy2.upgrade();
39.
40. System.out.println();
41.
42. /*
43. * 动态代理:使用jdk提供的InvocationHandler,反射调用被代理对象的方法
44. * 结合java.reflect.Proxy 产生代理对象
45. * 动态传入被代理对象构造InvocationHandler,在handler中的invoke时可以增强被代理对象的方法的功能
46. * 或者说:(面向切面:)在什么地方(连接点), 执行什么行为(通知)
47. * GamePlayerProxy3中是方法名为login时通知开始时间,upgrade时通知结束时间
48. */
49. new GamePlayerProxy3(new GamePlayer("Y"));
50. IGamePlayer dynamicPlayer = dynamic.getProxy();
51. "wangwu", "1234");
52. dynamicPlayer.killBoss();
53. dynamicPlayer.upgrade();
54. /*
55. * 面向切面: 一些相似的业务逻辑需要加在众多的地方,那们就可以把它提取到切面中, 切面也就是事务切面:如日志切面、权限切面、业务切面
56. */
57. }
58. }
打印:
1. 开始时间是:2014-10-8 17:19:05
2. 登录名为zhangSan 的角色 X登录成功!
3. X 在打怪!
4. X 又升了一级!
5. 结束时间是:2014-10-8 17:19:05
6.
7. 登录时间是:2014-10-8 17:19:05
8. 登录名为lisi 的角色 M登录成功!
9. M 在打怪!
10. M 又升了一级!
11. 升级时间是:2014-10-8 17:19:05
12.
13. 我是一名代练,我玩的角色是别人的,可以动态传递进来
14. 登录时间是:2014-10-8 17:19:05
15. 登录名为wangwu 的角色 Y登录成功!
16. Y 在打怪!
17. 升级时间是:2014-10-8 17:19:05
18. Y 又升了一级!