代理模式

  LOL相信大家都玩过吧,我大学同学现在已经是最强王者了,在学校段位重置时都会叫他帮我们代打定位赛,前期定位段位越高爬坑越简单,如今大学毕业,大家都各奔东西,但这段经历还是记忆犹新,下面通过代码来演示这个代打定位赛的过程吧。

英雄联盟游戏:

public interface  LOLPlayer
{
    //登录LOL
    public void login(String user,String password);
    //打定位赛
    public void play();
}

英雄联盟玩家(我的账号):

public class MyPlayer implements LOLPlayer
{
    private String name="";
    public MyPlayer(String name)
    {
        this.name = name;
    }
    @Override
    public void login(String user,String password)
    {
        // TODO Auto-generated method stub
        System.out.println(this.name+"登录LOL成功");
    }


    @Override
    public void play()
    {
        // TODO Auto-generated method stub
        System.out.println(this.name+"打定位赛");
    }

}

代练玩家(我同学):

public class ProxyPlayer implements LOLPlayer
{
    LOLPlayer lolPlayer =null ;

    public ProxyPlayer(LOLPlayer lolPlayer)
    {
        this.lolPlayer = lolPlayer;
    }

    //代练登录
    @Override
    public void login(String user,String password)
    {
        // TODO Auto-generated method stub
        this.lolPlayer.login(user,password);
    }
    //代打定位赛
    @Override
    public void play()
    {
        // TODO Auto-generated method stub
        this.lolPlayer.play();
    }

}

场景类:

public class Client
{
        public static void main(String[] args)
        {
            //我的账号
            LOLPlayer player = new MyPlayer("xiaoxsen");
            //代练者
            LOLPlayer proxy = new ProxyPlayer(player);
            System.out.println("======代打开始====");
            //代练登录
            proxy.login("xiaoxsen","123");
            //代打定位赛
            proxy.play();
            System.out.println("======代打结束====");
        }
}

代打定位赛过程执行结果:

======代打开始====
xiaoxsen登录LOL成功
xiaoxsen打定位赛
======代打结束====

定位赛打完了,但是自己没有打一把,段位就有了,这就是代理模式

代理模式定义
  代理模式是一种使用率非常高的模式,其定义如下:
Provide a surrogate or placeholder for another object to contrl access to it.(为其他对象提供一种代理以控制这个对象的访问。)
  代理模式有以下3个角色:
  Subject抽象主题角色:抽象主题角色可以是抽象类也可以是接口,是一个最普通的业务类型定义,比如上述的LOLPlayer类。
  RealSubject具体主题角色:也叫做被委托角色,被代理角色,他是业务的具体执行者,比如上述的MyPlayer类。
  Proxy代理主题角色:也叫做委托类,代理类。他负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实的主题角色实现,比如上述的ProxyPlayer类。
  
代理模式的优点:
  职责清晰
  高扩展性
  智能化

代理模式的扩展:

普通代理:要求客户端只出现代理类,不能访问真实角色,我们需要做如下的修改:

英雄联盟游戏玩家(我的账号):

public class MyPlayer implements LOLPlayer
{
    private String name="";
    public MyPlayer(LOLPlayer player,String name)
    {
        if(player==null)
        {
            System.out.println("不能创建真实角色");
        }else {
            this.name = name;
        }
    }
    @Override
    public void login(String user,String password)
    {
        // TODO Auto-generated method stub
        System.out.println(this.name+"登录LOL成功");
    }

    @Override
    public void play()
    {
        // TODO Auto-generated method stub
        System.out.println(this.name+"打定位赛");
    }

}

代练玩家(我同学):

public class ProxyPlayer implements LOLPlayer
{
    LOLPlayer lolPlayer =null ;

    public ProxyPlayer(String name)
    {
        lolPlayer = new MyPlayer(this,name);
    }
    //代练登录
    @Override
    public void login(String user,String password)
    {
        // TODO Auto-generated method stub
        this.lolPlayer.login(user,password);
    }
    //代打定位赛
    @Override
    public void play()
    {
        // TODO Auto-generated method stub
        this.lolPlayer.play();
    }

}

代打场景:

public class Client
{
        public static void main(String[] args)
        {
            //代练者
            LOLPlayer proxy = new ProxyPlayer("xiaoxsen");
            System.out.println("======代打开始====");
            //代练登录
            proxy.login("xiaoxsen","123");
            //代打定位赛
            proxy.play();
            System.out.println("======代打结束====");
        }
}

代打定位赛结果:

======代打开始====
xiaoxsen登录LOL成功
xiaoxsen打定位赛
======代打结束====

效果是一样的,只是隐藏了真实角色,屏蔽了真实角色变更对高层的影响。

动态代理:面向切面编程(AOP)其核心就是动态代理机制,下面我们用动态代理来实现这个代打过程。

动态代理类:

public class DynamicProxy implements InvocationHandler
{
    //被代理者的实例
    Object object =null;
    public DynamicProxy(Object obj)
    {
        object = obj;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable
    {
        // TODO Auto-generated method stub
        Object ob = method.invoke(object, args);
        return ob;
    }

}

动态代理场景类:

public class Client1
{
        public static void main(String[] args)
        {
            LOLPlayer player = new MyPlayer("xiaoxsen");
            InvocationHandler handle = new DynamicProxy(player);
            //获得类加载器
            ClassLoader cl = player.getClass().getClassLoader();
            //代练者
            LOLPlayer proxy = (LOLPlayer) Proxy.newProxyInstance(cl, new Class[]{LOLPlayer.class}, handle);
            System.out.println("======代打开始====");
            //代练登录
            proxy.login("xiaoxsen","123");
            //代打定位赛
            proxy.play();
            System.out.println("======代打结束====");
        }
}

执行结果:

======代打开始====
xiaoxsen登录LOL成功
xiaoxsen打定位赛
======代打结束====

  发现结果是一样的,我们并没有创建代理类,我们在代码中动态生成代理类,完成代打过程,这就是动态代理模式,当然我们可以在invoke方法前后做一些操作达到一定的控制作用,这也是面向切面编程的关键。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值