类图

/**
* 游戏者接口
* @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 { @Override
public 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:05
Y 又升了一级!

Java 实现代理(Proxy)模式的更多相关文章

  1. 行为模式--代理Proxy模式(Java)

    代理(AOP切面的雏形): 题记:顾名思义就是将某件事,某个东西的使用权进行为让授权转移.代理相当于中介(不同于中介者模式),在原本操作的类之间添加了一个桥梁.但代理不能去修改原有目标.比如:一个人要 ...

  2. java 动态代理(模式) InvocationHandler(为类中方法执行前或后添加内容)

    动态代理属于Java反射的一种. 当我们得到一个对象,想动态的为其一些方法每次被调用前后追加一些操作时,我们将会用到java动态代理. 下边上代码: 首先定义一个接口: package com.liu ...

  3. java动态代理--proxy&cglib

    大纲 代理 proxy cglib 小结 一.代理 为什么要用代理?其实就是希望不修改对象的情况下,增强对象. 静态代理: 静态代理模式,需要代理类和目标类实现同一接口,代理类的方法调用目标类的方法, ...

  4. 漫谈设计模式(一):代理(Proxy)模式与适配器(Adapter)模式对比

    1.前言 为什么要将代理模式与适配器模式放在一起来说呢?因为它们有许多的共同点,当然也有一些不同的地方.首先两者都是属于结构型模式.结构型模型是这样定义的: 结构型模式涉及到如何组合类和类以获得更大的 ...

  5. java动态代理Proxy

    package com.gz_06; public interface StudentDao { public void login(); public void regist(); } packag ...

  6. 代理(Proxy)模式简介

    Proxy 模式简介 代理模式的两个应用: 打开文档时加载大图片 例如:如果有个对象是一张很大的图片,而这张图片需要花费很长时间才能显示出来,那么当这个图片包含在文档中的后面时,使用编辑器或浏览器打开 ...

  7. java 动态代理 Proxy.newProxyInstance 使用心法

    使用JDk的Proxy类的静态方法newProxyInstance ,让JVM自动生成一个新的类,类中包含了inerfaces参数中的所有方法,每个方法都调用h.invoke 方法       AOP ...

  8. 代理(Proxy)模式

    代理模式的类图如下所示: 客户端想调用的是RealSubject,由于某种考虑或原因,只能直接访问到ProxySubject,再由ProxySubject去调用RealSubject,这就完成了一次代 ...

  9. Android与设计模式——代理(Proxy)模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描写叙述代理(Proxy)模式的: 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 代理模式 ...

随机推荐

  1. 生成清除某个数据库下的所有表的SQL语句

    方法1:重建库和表 用mysqldump --no-data把建表SQL导出来,然后drop database再create database,执行一下导出的SQL文件: 方法2:生成清空所有表的SQ ...

  2. Spring Boot (33) 分布式锁

    上一篇中使用的Guava Cache,如果在集群中就不可以用了,需要借助Redis.Zookeeper之类的中间件实现分布式锁. 导入依赖 在pom.xml中需要添加的依赖包:stater-web.s ...

  3. redis之有序集合类型(Zset)——排行榜的实现

    当数据库对排序支持的不是很好,可以利用redis有序集合排序 原文链接:http://blog.csdn.net/loophome/article/details/50373202

  4. 基于SOC方案的嵌入式开发-远程定时设备

    Soc方案实现简单的定时开关灯 http://club.gizwits.com/forum.php?mod=viewthread&tid=7787&highlight=%E5%AE%9 ...

  5. Expectation-Maximization(EM) 算法

    Expectation-Maximization 算法是统计学中用来给带隐含变量的模型做最大似然(和最大后验概率)的一种方法.EM 的应用特别广泛,经典的比如做概率密度估计用的 Gaussian Mi ...

  6. golang协程——通道channel阻塞

    新的一年开始了,不管今天以前发生了什么,向前看,就够了. 说到channel,就一定要说一说线程了.任何实际项目,无论大小,并发是必然存在的.并发的存在,就涉及到线程通信.在当下的开发语言中,线程通讯 ...

  7. 6.14 提取第n个分割的子串

    问题:从字符串中提取出一个指定的.由分割符隔开的子字符串.create view v as select 'mo,larry,curly' as namefrom t1union allselect ...

  8. Eigen库笔记整理(一)

    首先熟悉Eigen库的用途,自行百度. 引入头文件: // Eigen 部分 #include <Eigen/Core> // 稠密矩阵的代数运算(逆,特征值等) #include < ...

  9. Python 操作excel day5

    一.Python操作excel python操作excel使用xlrd.xlwt和xlutils模块 1.xlrd模块是读取excel的: 2.xlwt模块是写excel的: 3.xlutils是用来 ...

  10. Linux安装redis并且连接内网的redis

    1.安装redis步骤 1.首先准备工作  [root@10-100-14-130 ~]# yum install gcc-c++   yum install wget 2.推荐进入到linux路径/ ...