zoukankan      html  css  js  c++  java
  • 代理模式

    栗子

    定义一个游戏者接口

    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);完成对代理的调用。

    https://www.iming.info/dai-li-mo-shi/
    图片描述

    在无知的道路上缓步前行
  • 相关阅读:
    setMonth 疑问
    asp.net数据格式的Format DataFormatString (备忘录)
    在日常维护中,如何实现Microsoft Lync Server 2010自动启用和同步Active Directory 域服务中所有用户帐户的信息?
    关于聊天记录的管理与查询
    DBImpExp.exe工具
    用户的批量处理
    设计模式 学习笔记(3)装饰模式、代理模式
    设计模式 学习笔记(1)简单工厂模式、策略模式
    设计模式 学习笔记(5)迪米特法则、外观模式、建造者模式
    设计模式 学习笔记(2)单一职责原则、开放封闭原则、依赖倒转原则
  • 原文地址:https://www.cnblogs.com/melovemingming/p/10306987.html
Copyright © 2011-2022 走看看