• Java 实现代理(Proxy)模式


    类图


    /**
     * 游戏者接口
     * @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 又升了一级!




  • 相关阅读:
    three.js中 用 鼠标点击+呼吸灯
    socket.io学习以及在vuehtml使用,node搭建的后台
    网路在线古诗文免费阅读网站
    vue-element-admin默认加载Dashboard更改
    vue-element-admin后台框架侧边蓝图标添加自定义
    吸顶操作vue
    对图片进行裁剪(vueCropper)图片不显示
    ucharts使用内容
    文字转换为语音在线免费工具连接
    tree.js外部骨骼动画
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/6894195.html
Copyright © 2020-2023  润新知