我是游戏至尊
代码
IGamePlayer
package com.peng.game;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public interface IGamePlayer {
// 登录系统
public void login(String username, String password);
// 杀怪
public void killBoss();
// 升级
public void upgrade();
}
GamePlayer
package com.peng.game;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class GamePlayer implements IGamePlayer {
private String username;
private String password;
public GamePlayer(String username, String password) {
super();
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public void login(String username, String password) {
System.out.println(username + "登录了!");
}
@Override
public void killBoss() {
System.out.println("在打怪!");
}
@Override
public void upgrade() {
System.out.println("又升一级!");
}
}
Client
package com.peng.game;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class Client {
public static void main(String[] args) {
// 创建游戏玩家
IGamePlayer igp = new GamePlayer("123", "***");
// 登录游戏系统
igp.login("123", "***");
// 杀野怪
igp.killBoss();
// 升级
igp.upgrade();
}
}
游戏玩的时间长了,腰酸背痛眼睛干涩,手臂酸麻。其结果就像吃了“一日丧命散”,静脉逆流,胡思乱想,而走火入魔,那该怎们解决呢,我们也想玩游戏,但又不想碰触到游戏的烦恼。如何解决,代练公司这么多,哈哈,这么好,先修改下类图。
代码
GamePlayerProxy
package com.peng.game;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class GamePlayerProxy implements IGamePlayer {
private IGamePlayer gamePlayer = null;
// 通过构造函数对谁进行代练
public GamePlayerProxy(IGamePlayer _gamePlayer) {
this.gamePlayer = _gamePlayer;
}
// 代练登录
@Override
public void login(String username, String password) {
this.gamePlayer.login(username, password);
}
// 代练打怪
@Override
public void killBoss() {
this.gamePlayer.killBoss();
}
// 代练升级
@Override
public void upgrade() {
this.gamePlayer.upgrade();
}
}
Client
package com.peng.game;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class Client {
public static void main(String[] args) {
// 创建游戏玩家
GamePlayerProxy gpp = new GamePlayerProxy(new GamePlayer("123", "***"));
// 登录游戏系统
gpp.login("123", "***");
// 杀野怪
gpp.killBoss();
// 升级
gpp.upgrade();
}
}
代码
抽象主题类
public interface Subject {
// 定义一个方法
public void request();
}
真实主题类
public class RealSubject implements Subject {
@Override
public void request() {
// 业务逻辑处理
}
}
代理类
public class Proxy implements Subject {
// 要代理哪个实现类
private Subject subject = null;
// 默认被代理者
public Proxy() {
this.subject = new Proxy();
}
// 传递被代理者
public Proxy(Object... object) {
//这里自己悟一下--简单提示,自己拓展
//public Proxy(RealSubject subject) {
// this.subject=subject;
//}
}
@Override
public void request() {
this.before();
this.request();
this.after();
}
private void before() {
// 预处理操作
}
private void after() {
// 善后处理
}
}
看下不同代理模式的类图吧
普通代理
改动很小,仅仅是修改了两个实现类的构造函数,GamePlayer增加了一个_gamePlayer的参数,而代理模式则传入代理者的名称即可
GamePlayer
package com.peng.game;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class GamePlayer implements IGamePlayer {
private String name="";
//_gamePlayer放代理者
public GamePlayer(IGamePlayer _gamePlayer,String _name) throws Exception {
super();
if(_gamePlayer==null){
throw new Exception("不能创建真实角色!");
}else{
this.name=_name;
}
}
@Override
public void login(String username, String password) {
System.out.println(username + "登录了!");
}
@Override
public void killBoss() {
System.out.println(this.name+"在打怪!");
}
@Override
public void upgrade() {
System.out.println(this.name+"又升一级!");
}
}
GamePlayerProxy
package com.peng.game;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class GamePlayerProxy implements IGamePlayer {
private IGamePlayer gamePlayer = null;
// 通过构造函数对谁进行代练
public GamePlayerProxy(String name) {
try{
gamePlayer=new GamePlayer(this,name);
}catch(){
//异常处理
}
}
// 代练登录
@Override
public void login(String username, String password) {
this.gamePlayer.login(username, password);
}
// 代练打怪
@Override
public void killBoss() {
this.gamePlayer.killBoss();
}
// 代练升级
@Override
public void upgrade() {
this.gamePlayer.upgrade();
}
}
场景类
package com.peng.game;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class Client {
public static void main(String[] args) {
// 创建游戏玩家
GamePlayerProxy gpp = new GamePlayerProxy(new GamePlayer("kungfu~peng"));
// 登录游戏系统
gpp.login("123", "***");
// 杀野怪
gpp.killBoss();
// 升级
gpp.upgrade();
}
}
在该模式下,调用者只知道代理而不用真实的角色是谁,屏蔽了真实角色的变更对高层对象的影响
强制代理
类图
IGamePlayer
package com.peng.game;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public interface IGamePlayer {
// 登录系统
public void login(String username, String password);
// 杀怪
public void killBoss();
// 升级
public void upgrade();
// 返回代理
public IGamePlayer getProxy();
}
GamePlayer
package com.peng.game;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class GamePlayer implements IGamePlayer {
private String name = "";
private IGamePlayer proxy = null;
public GamePlayer(String _name) throws Exception {
super();
this.name = _name;
}
@Override
public void login(String username, String password) {
if (isProxy()) {
System.out.println(username + "登录了!");
} else {
System.out.println("请使用指定的代理访问!");
}
}
@Override
public void killBoss() {
if (isProxy()) {
System.out.println(this.name + "在打怪!");
} else {
System.out.println("请使用指定的代理访问!");
}
}
@Override
public void upgrade() {
if (isProxy()) {
System.out.println(this.name + "又升一级!");
} else {
System.out.println("请使用指定的代理访问!");
}
}
@Override
public IGamePlayer getProxy() {
this.proxy = new GamePlayerProxy(this);
return this.proxy;
}
// 检验代理是否被访问
private boolean isProxy() {
if (this.proxy == null) {
return false;
} else {
return true;
}
}
}
GamePlayerProxy
package com.peng.game;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class GamePlayerProxy implements IGamePlayer {
private IGamePlayer gamePlayer = null;
// 通过构造函数对谁进行代练
public GamePlayerProxy(IGamePlayer _gamePlayer) {
this.gamePlayer = _gamePlayer;
}
// 代练登录
@Override
public void login(String username, String password) {
this.gamePlayer.login(username, password);
}
// 代练打怪
@Override
public void killBoss() {
this.gamePlayer.killBoss();
}
// 代练升级
@Override
public void upgrade() {
this.gamePlayer.upgrade();
}
@Override
public IGamePlayer getProxy() {
return this;
}
}
Client(测试1)
package com.peng.game;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class Client {
public static void main(String[] args) throws Exception {
// 创建游戏玩家
IGamePlayer gpp =new GamePlayer("kungfu~peng");
// 登录游戏系统
gpp.login("123", "***");
// 杀野怪
gpp.killBoss();
// 升级
gpp.upgrade();
}
}
//结果:
请使用指定的代理访问!
请使用指定的代理访问!
请使用指定的代理访问!
Client(测试2)
package com.peng.game;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class Client {
public static void main(String[] args) throws Exception {
// 创建游戏玩家
IGamePlayer gpp =new GamePlayer("kungfu~peng");
//代练者
IGamePlayer proxy =new GamePlayerProxy(gpp);
// 登录游戏系统
proxy.login("123", "***");
// 杀野怪
proxy.killBoss();
// 升级
proxy.upgrade();
}
}
//结果:
请使用指定的代理访问!
请使用指定的代理访问!
请使用指定的代理访问!
Client(测试3)
package com.peng.game;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class Client {
public static void main(String[] args) throws Exception {
// 创建游戏玩家
IGamePlayer gpp =new GamePlayer("kungfu~peng");
//代练者
IGamePlayer proxy =gpp.getProxy();// 自己指定代理者
// 登录游戏系统
proxy.login("123", "***");
// 杀野怪
proxy.killBoss();
// 升级
proxy.upgrade();
}
}
//结果:
kungfu~peng登录了!
kungfu~peng在打怪!
kungfu~peng又升一级!
例如代练打游戏要收费,升一级要5元
改动的类
IProxy
package com.peng.game;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public interface IProxy {
// 计算费用
public void count();
}
GamePlayProxy
package com.peng.game;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class GamePlayerProxy implements IGamePlayer, IProxy {
private IGamePlayer gamePlayer = null;
// 通过构造函数对谁进行代练
public GamePlayerProxy(IGamePlayer _gamePlayer) {
this.gamePlayer = _gamePlayer;
}
// 代练登录
@Override
public void login(String username, String password) {
this.gamePlayer.login(username, password);
}
// 代练打怪
@Override
public void killBoss() {
this.gamePlayer.killBoss();
}
// 代练升级
@Override
public void upgrade() {
this.gamePlayer.upgrade();
this.count();
}
@Override
public IGamePlayer getProxy() {
return this;
}
@Override
public void count() {
System.out.println("消费5元!");
}
}
kungfu~peng登录了!
kungfu~peng在打怪!
kungfu~peng又升一级!
消费5元!
类图
代码
GamePlayIH
package com.peng.game;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class GamePlayIH implements InvocationHandler {
// 被代理者
Class cls = null;//感觉这个多余...
// 被代理的实例
Object obj = null;
// 我要代理谁
public GamePlayIH(Object obj) {
super();
this.obj = obj;
}
// 调用被代理的方法
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = method.invoke(this.obj, args);
return result;
}
}
IGamePlayer
package com.peng.game;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public interface IGamePlayer {
// 登录系统
public void login(String username, String password);
// 杀怪
public void killBoss();
// 升级
public void upgrade();
// 返回代理
public IGamePlayer getProxy();
}
GamePlayer
package com.peng.game;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class GamePlayer implements IGamePlayer {
private String name = "";
private IGamePlayer proxy = null;
public GamePlayer(String _name) throws Exception {
super();
this.name = _name;
}
@Override
public void login(String username, String password) {
if (isProxy()) {
System.out.println(username + "登录了!");
} else {
System.out.println("请使用指定的代理访问!");
}
}
@Override
public void killBoss() {
if (isProxy()) {
System.out.println(this.name + "在打怪!");
} else {
System.out.println("请使用指定的代理访问!");
}
}
@Override
public void upgrade() {
if (isProxy()) {
System.out.println(this.name + "又升一级!");
} else {
System.out.println("请使用指定的代理访问!");
}
}
@Override
public IGamePlayer getProxy() {
this.proxy = new GamePlayerProxy(this);
return this.proxy;
}
// 检验代理是否被访问
private boolean isProxy() {
if (this.proxy == null) {
return false;
} else {
return true;
}
}
}
场景类Client
package com.peng.game;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class Client_IH {
public static void main(String[] args) throws Exception {
// 定义一个痴迷的玩家
IGamePlayer player = new GamePlayer("kungfu~peng");
// 定义一个Handler
InvocationHandler handler = new GamePlayIH(player);
// 获得类的class loader
ClassLoader cl = player.getClass().getClassLoader();
// 动态产生一个代理者
IGamePlayer proxy = (IGamePlayer) Proxy.newProxyInstance(cl,
new Class[] { IGamePlayer.class }, handler);
// 注意:这里还是用的强制代理---其他代码用强制代理模式
proxy = proxy.getProxy();
// 登录
proxy.login("kungfu~peng", "***");
// 开始杀怪
proxy.killBoss();
// 升级
proxy.upgrade();
}
}
执行结果
kungfu~peng登录了!
kungfu~peng在打怪!
kungfu~peng又升一级!
消费5元!
解释:动态代理模式中,既没有创建代理类,也没有实现IGamePlayer接口,这就是动态代理,别急,动态代理可不仅仅这么多内容,还有更重要的,如果想让游戏登录后就发一个信息给我们,防止账号被盗用。怎么办?当然是修正GamePlayIH类啦!!
代码如下
package com.peng.game;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class GamePlayIH implements InvocationHandler {
// 被代理者
Class cls = null;
// 被代理的实例
Object obj = null;
// 我要代理谁
public GamePlayIH(Object obj) {
super();
this.obj = obj;
}
// 调用被代理的方法
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = method.invoke(this.obj, args);
// 如果是登录方法则发送信息
if (method.getName().equalsIgnoreCase("login")) {
System.out.println("有人用我的账号登录!");
}
return result;
}
}
注:这里测试不能用强制代理了,因为获取的代理获取的是getProxy方法
package com.peng.game; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; /** * @author kungfu~peng * @data 2017年11月17日 * @description */ public class Client_IH { public static void main(String[] args) throws Exception { // 定义一个痴迷的玩家 IGamePlayer player = new GamePlayer("kungfu~peng"); // 定义一个Handler InvocationHandler handler = new GamePlayIH(player); // 获得类的class loader ClassLoader cl = player.getClass().getClassLoader(); // 动态产生一个代理者 IGamePlayer proxy = (IGamePlayer) Proxy.newProxyInstance(cl, new Class[] { IGamePlayer.class }, handler); // 这里还是用的强制代理 proxy = proxy.getProxy(); // 登录 proxy.login("kungfu~peng", "***"); // 开始杀怪 proxy.killBoss(); // 升级 proxy.upgrade(); } } //测试结果 getProxy kungfu~peng登录了! kungfu~peng在打怪! kungfu~peng又升一级! 消费5元!
代码
Subject
package com.peng.dynamicproxy;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public interface Subject {
// 业务操作
public void doSomething(String str);
}
RealSubject
package com.peng.dynamicproxy;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class RealSubject implements Subject {
@Override
public void doSomething(String str) {
// 业务操作
System.out.println("do Something~~" + str);
}
}
MyInvocationHandler
package com.peng.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class MyInvocationHandler implements InvocationHandler {
// 被代理的对象
private Object target = null;
// 通过构造函数传递一个对象
public MyInvocationHandler(Object _obj) {
super();
this.target = _obj;
}
// 代理方法
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return method.invoke(this.target, args);
}
}
DynamicProxy
package com.peng.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class DynamicProxy {
public static T newProxyInstance(ClassLoader loader,
Class>[] interfaces, InvocationHandler h) {
// 寻找JoinPoint连接点,AOP框架使用元数据定义
if (true) {
// 执行一个前置通知--切入
(new BeforeAdvice()).exec();
}
return (T) Proxy.newProxyInstance(loader, interfaces, h);
}
}
IAdvice
package com.peng.dynamicproxy;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public interface IAdvice {
// 通知方法只有一个
public void exec();
}
BeforeAdvice
package com.peng.dynamicproxy;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class BeforeAdvice implements IAdvice {
@Override
public void exec() {
System.out.println("执行了前置函数!");
}
}
Client
package com.peng.dynamicproxy;
import java.lang.reflect.InvocationHandler;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class Client {
public static void main(String[] args) {
// 定义一个主题
Subject subject = new RealSubject();
// 定义一个Handler
InvocationHandler handler = new MyInvocationHandler(subject);
// 定义主题的代理
Subject proxy = DynamicProxy.newProxyInstance(subject.getClass()
.getClassLoader(), subject.getClass().getInterfaces(), handler);
//代理行为
proxy.doSomething("Finish!!");
}
}
执行了前置函数!
do Something~~Finish!!
动态代理过程
继续扩展DynamicProxy类之SubjectDynamicProxy:
package com.peng.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class SubjectDynamicProxy extends DynamicProxy {
public static T newProxyInstance(Subject subject) {
// 获得ClassLoader
ClassLoader loader = subject.getClass().getClassLoader();
// 过的接口数组
Class>[] classes = subject.getClass().getInterfaces();
// 获得Handler
InvocationHandler handler = new MyInvocationHandler(subject);
// 寻找JoinPoint连接点,AOP框架使用元数据定义
return newProxyInstance(loader, classes, handler);
}
}
测试类更加简洁
package com.peng.dynamicproxy;
/**
* @author kungfu~peng
* @data 2017年11月17日
* @description
*/
public class Client {
public static void main(String[] args) {
// 定义一个主题
Subject subject = new RealSubject();
// 定义主题的代理
Subject proxy = SubjectDynamicProxy.newProxyInstance(subject);
// 代理行为
proxy.doSomething("Finish!!");
}
}