资讯专栏INFORMATION COLUMN

代理模式

_ang / 1086人阅读

摘要:定义代理类的接口计算费用定义代理类通过构造函数传递对谁代练代练代练登录代练升级计算费用在上方中先实现了接口,然后再调用该接口中的方法,完成结算动态代理动态代理在实现阶段不用关系代理谁。在运行阶段指定代理那个对象。

栗子

定义一个游戏者接口

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...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/73152.html

相关文章

  • 我的Java设计模式-代理模式

    摘要:下面总结了它俩的异同相同点都需要实现同一个接口或者继承同一个抽象类,并且代理角色和装饰角色都持有被代理角色和构件角色的引用。 写完上一篇之后有小伙伴问我有没有写过代理模式,想看看我的理解。原本我的设计模式系列是按照创建型-行为型-结构型的顺序写下去的,既然小伙伴诚心诚意了,我就大发慈悲的穿插一篇代理模式。开玩笑,题外话。 说起代理模式,就不由得想起经纪人,说起经纪人,就想起了...对,...

    makeFoxPlay 评论0 收藏0
  • 我的Java设计模式-代理模式

    摘要:下面总结了它俩的异同相同点都需要实现同一个接口或者继承同一个抽象类,并且代理角色和装饰角色都持有被代理角色和构件角色的引用。 写完上一篇之后有小伙伴问我有没有写过代理模式,想看看我的理解。原本我的设计模式系列是按照创建型-行为型-结构型的顺序写下去的,既然小伙伴诚心诚意了,我就大发慈悲的穿插一篇代理模式。开玩笑,题外话。 说起代理模式,就不由得想起经纪人,说起经纪人,就想起了...对,...

    BWrong 评论0 收藏0
  • 设计模式|代理模式

    摘要:三二模式分析代理模式的示意图结构比较简单一般可以简化如下图所示。五总结在代理模式中,要求给某一个对象提供一个代理,并由代理对象控制对原对象的访问,其英文为是一种结构型模式。 一、写在前面 代理模式是常用的结构型设计模式之一、当我们直接访问某些对象存在问题时可以通过代理模式来间接访问,为了保证客户端使用的透明性、所访问的真实对象和代理对象都必须实现同一个接口。 二、代理模式动机与定义 某...

    QiShare 评论0 收藏0
  • 代理模式和装饰者模式

    摘要:简介代理模式和装饰者模式是两种常见的设计模式。这里通过构造函数的参数将被代理对象传入到代理中,也可以通过其它方式,如提供一个方法。下面是的代码输出首先依然是先创建一个需要被代理的对象,然后把它传入到的构造函数中。 简介 代理模式和装饰者模式是两种常见的设计模式。代理模式是为其它对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以...

    NusterCache 评论0 收藏0
  • js设计模式 --- 代理设计模式

    摘要:代理设计模式代理模式为其他对象提供一种代理以控制对这个对象的访问。代理模式是常见的设计模式之一是指不直接调用实际的对象,而是通过代理对象,来间接的调用实际的对象。对象类定义了代理对象所代表的目标对象。 代理设计模式 代理模式:为其他对象提供一种代理以控制对这个对象的访问。代理模式是常见的设计模式之一,是指不直接调用实际的对象,而是通过代理对象,来间接的调用实际的对象。为什么要采用这种间...

    Tonny 评论0 收藏0
  • 深入理解代理模式

    摘要:代理模式代理类中创建一个真实对象的实例模式的核心装饰者强调的是增强自身,在被装饰之后你能够在被增强的类上使用增强后的功能。 代理模式 在详细了解代理模式之前,可能对于像小秋一样的小白,只知道一些很浅显的概念,或者就知道远程代理啊,静态代理啊,动态代理啊,这些看似可以望文生义的专业名词,但是如果我告诉你代理模式贯穿了我们生活的方方面面,就比如你现在刷着公众号的时候,实际上就用了远程代理模...

    testHs 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<