代理模式
栗子
定义一个游戏者接口
public interface IGamePlayer{
// 登录游戏
public void login(String user, String password);
// 杀怪
public void killBoss();
// 升级
public void upgrade();
}
定义游戏着类,实现游戏者接口
public class GamePlay 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("登录");
}
// 升级
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;
// 构造函数注入
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 = "";
// 构造函数传递姓名
public GamePlayer(IGamePlayer _gamePlayer, String _name)throws Exception{
if(_gamePlayer == null){
throw new Exception("不能创建真实角色");
}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;
// 构造函数注入
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;
// 构造函数传递用户名
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();
}
}
代理需要拥有个性
即一个类可以实现多个接口,完成不同任务的整合。
// 定义代理类的接口
public interface IProxy{
// 计算费用
public void count();
}
// 定义代理类
public class GamePlayerProxy implements IGamePlayer, IProxy{
private IGamePlayer gamePlayer = null;
// 通过构造函数传递对谁代练
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(){
}
}
在上方中先实现了IProxy接口,然后再调用该接口中的方法,完成结算.
动态代理
动态代理在实现阶段不用关系代理谁。在运行阶段指定代理那个对象。
即,在实现的时候不用关心代理谁,只需要在运行的时候指定代理那个对象
// 动态代理类
public class GamePlayIH implements invocationHandler{
// 被代理着
Class cls = null;
// 被代理的实例
Object obj = null;
// 我要代理谁
public GamePlayerIH(Object _obj){
this.obj = _obj;
}
// 调用被代理的方法
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable{
Object result = method.invoke(this.obj, args);
return result;
}
}
// 动态代理场景类
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();
// 动态产生代理者
IGamePlayer proxy = (IGamePlayer)proxy.newProxyinstance(cl, new Class[]{IGamePlayer.class}, handler);
// 登录
proxy.login("zhangsan", "password");
// 开始
proxy.killBoss();
// 升级
proxy.upgrade();
// 记录结束时间
}
}
ps 动态代理直接在需要代理的时候直接动态生成代理
此时,如果需要登录的时候发送消息,此时修改如下
public class GamePlayIH implements invocationHandler {
// 被代理着
Class cls = null;
// 被代理的实例
Object obj = null;
// 我要代理谁
public GamePlayIH(Object _obj){
this.obj = _obj;
}
// 调用代理的方法
public Object invoke(Object proxy, Method method, Object[] args){
Objetc result = method.invoke(this.obj, args);
// 如股票是登录方法,发送消息
if(method.getName().equalslgnoreCase("login")){
}
return result;
}
}
这样就完成的消息的发送
最后
// 抽象主题
public interface Subject{
// 业务操作
public void doSomething(String str);
}
// 真实主题
public class RealSubject implements Subject{
// 业务操作
public void doSomething(String str){
/// 业务操作
}
}
下面是动态代理类该动态代理类通过构造函数将将对象传入。
由于实现了invoke方法,此时会被调度到该方法
public class MyinvocationHandler implements invocationHandler{
// 被代理的对象
private Object target = null;
// 构造函数传递
public MyInvocationHandler(Object _obj){
this.target = _obj;
}
// 代理方法
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable{
// 执行被代理的方法
return method.invoke(this.target, args);
}
}
下面是动态代理类
public class DynamiProxy{
public static T newProxyinstance(ClassLoader loader, Class<?>[] interfaces, invocationHandler h){
// 寻找JoinPoint连接点
// 寻找连接点,即方法执行前后的连接点
if(true){
// 执行一个前置通知
new BeforeAdvice().exec();
}
// 执行切面
// 并返回结果
return (T)Proxy.newProxyinstance(loader.interfaces, h);
}
}
下面实现通知
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);
// 最后执行这个代理的接口
proxy.doSomething("Finish");
}
}
总结 程序的执行的过程,在DynamicProxy类中,使用newProxyinstance方法重写生成一个对象,这个对象是其代理对象,一个类的动态代理是这样的过程
先场景类需要调用doSomething方法的时候,进入动态代理类,当动态代理类调用Proxy.newProxyinstance的时候,会调度到代理方法,由代理方法再执行method.invoke(this.target, args);完成对代理的调用。
在无知的道路上缓步前行