代理模式

来源:互联网 发布:java程序开发培训机构 编辑:程序博客网 时间:2024/06/12 20:28

  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方法前后做一些操作达到一定的控制作用,这也是面向切面编程的关键。

0 0