首页 > 代码库 > 23种设计模式----------代理模式(二)

23种设计模式----------代理模式(二)

(上一篇)23种设计模式----------代理模式(一)

之前说了基本的代理模式和普通代理模式。接下来开始看下强制代理模式和虚拟代理模式

三,强制代理模式:

一般的代理模式都是通过代理类找到被代理的对象,从而调用被代理类中的方法(即完成被代理类中的任务)。

而,强制代理模式则是先找到被代理类自己去完成事情,然后被代理类又将该做的事情转交到代理类中,让代理类来完成。

假如:你有事求助于某位名人。

你告诉名人说有事想请他帮忙,然后他说最近一段时间比较忙,要不你找我的经纪人来办吧。

(本来找名人办事,事情由他来完成的,即 表示 真实主题类。然而,他要将事情转交给自己的经纪人(即代理类),这时该名人就是被代理者)。

代码实现如下

抽象主题类或者接口:

 1 package com.yemaozi.proxy.force; 2  3 public interface IGamePlayer { 4     //登录游戏 5     public void login(String username, String password); 6      7     //击杀Boss 8     public void killBoss(); 9     10     //升级11     public void upGrade();12     13     //获取代理14     public IGamePlayer getProxy();15 }16 //由于要通过主题类找代理类,所以在此添加getProxy()方法,获取代理。

需要被代理类:

 1 package com.yemaozi.proxy.force; 2  3 public class GamePlayer implements IGamePlayer{ 4     private String name = ""; 5  6     private IGamePlayer proxyGp = null; 7      8     public GamePlayer(String name){ 9         this.name = name;10     }11 12     //获取代理。13     public IGamePlayer getProxy() {14         this.proxyGp = new ProxyGamePlayer(this);15         return this.proxyGp;16     }17 18     public void login(String username, String password) {19         //只有是自己指定的代理人才给办事,别人的代理也不搭理咱啊,所以判断是否为自己的代理,若是,则正常执行。20         if(this.isProxy()){21             System.out.println("登录名为 "+username+" 进入游戏," + name + " 登录成功!");22         }else{23             System.out.println("请使用制定代理访问!");24         }25     }26 27     public void killBoss() {28         if(this.isProxy()){29             System.out.println(this.name + " 击杀了Boss!");30         }else{31             System.out.println("请使用制定代理访问!");32         }33     }34 35 36     public void upGrade() {37         if(this.isProxy()){38             System.out.println(this.name + "升级了!");39         }else{40             System.out.println("请使用制定代理访问!");41         }42     }43     44     //判断是否是代理45     public boolean isProxy(){46         if(this.proxyGp!=null){47             return true;48         }else {49             return false;50         }51     }52     53 }

代理类:

 1 package com.yemaozi.proxy.force; 2  3 //强制代理的代理类。 4 public class ProxyGamePlayer implements IGamePlayer{ 5      6     private IGamePlayer proxyGp = null; 7      8     public ProxyGamePlayer(IGamePlayer gp){ 9         this.proxyGp = gp;10     }11     12     public void login(String username, String password) {13         System.out.println("代理登录游戏!");14         this.proxyGp.login(username, password);15     }16 17     public void killBoss() {18         this.proxyGp.killBoss();19     }20 21 22     public void upGrade() {23         this.proxyGp.upGrade();24     }25 26     public IGamePlayer getProxy() {27         return this;28     }29 }

这次设计的是只有自己指定的代理类才能正常执行方法。

场景类一:不通过代理来执行。

 1 package com.yemaozi.proxy.force; 2  3 public class Client { 4     public static void main(String[] args) { 5          6         IGamePlayer gp = new GamePlayer("张三"); 7          8         gp.login("zhangsan", "123456"); 9         gp.killBoss();10         gp.upGrade();11     }12 }13 14 执行结果:15 请使用制定代理访问!16 请使用制定代理访问!17 请使用制定代理访问!18 19 //很显然,不用代理,是不能正常执行。

场景类二:用不是指定的代理类来执行。

 1 package com.yemaozi.proxy.force; 2  3 //直接访问代理类(非真实用户制定的代理) 4 public class ProxyClient { 5     public static void main(String[] args) { 6         IGamePlayer proxy = new ProxyGamePlayer(new GamePlayer("张三")); 7          8         proxy.login("zhangsan", "123456"); 9         proxy.killBoss();10         proxy.upGrade();11     }12 }13 14 执行结果:15 代理登录游戏!16 请使用制定代理访问!17 请使用制定代理访问!18 请使用制定代理访问!19 20 //显然虽然代理登录了,但是由于是非法的(有可能属于盗号行为),所以下面还是执行不了。

场景类三:使用真实主题类指定的代理。

 1 package com.yemaozi.proxy.force; 2  3 //通过真是类去访问代理类。 4 public class SpecificProxyClient { 5     public static void main(String[] args) { 6         IGamePlayer gp = new GamePlayer("张三"); 7         IGamePlayer proxyGp = gp.getProxy(); 8          9         proxyGp.login("zhangsan", "123456");10         proxyGp.killBoss();11         proxyGp.upGrade();12     }13 }14 15 执行结果:16 代理登录游戏!17 登录名为 zhangsan 进入游戏,张三 登录成功!18 张三 击杀了Boss!19 张三升级了!20 21 //这次终于可以顺利的执行了。

强制代理模式的概念就是要从真是角色那里查找到代理角色,不允许直接访问真实角色。上层模块只需要调用getProxy()获取代理来访问真实角色的所有方法,它根本就不需要产生一个代理角色,代理的管理已经由真实角色自己来完成。

 

四,虚拟代理模式:

虚拟代理:其实就是在需要的时候再初始化主题角色。

  1,优点:可以避免被代理对象过多,而带来的初始化缓慢。

  2,缺点:需要在每个方法上判断主题对象是否被创建。

代码实现如下

抽象主题类或者接口:

 

 1 package com.yemaozi.proxy.virtual; 2  3 //虚拟代理:就是需要初始化的时候才进行初始化主题     4 //优点:可以避免由于被代理对象过多,而引起的初始化缓慢的问题, 5 //缺点:需要在每个方法中判断对象主题是否已被创建。 6 public interface IGamePlayer { 7     //登录游戏 8     public void login(String username, String password); 9     10     //击杀Boss11     public void killBoss();12     13     //升级14     public void upGrade();15 }

 

需要被代理的类:

 1 package com.yemaozi.proxy.virtual; 2  3 public class GamePlayer implements IGamePlayer { 4  5     private String name = ""; 6      7     public GamePlayer(String name){ 8         this.name = name; 9     }10     11     public void login(String username, String password) {12         System.out.println("登录名为 "+username+" 进入游戏," + name + " 登录成功!");13     }14         15     public void killBoss() {16         System.out.println(this.name + " 击杀了Boss!");17     }18 19     public void upGrade() {20         System.out.println(this.name + "升级了!");21     }22 23 }

代理类:

 1 package com.yemaozi.proxy.virtual; 2  3 public class ProxyGamePlayer implements IGamePlayer { 4  5     //声明要代理的对象。 6     private IGamePlayer gp; 7      8     public void login(String username, String password) { 9         //都需要判断真实主题类的存在与否。10         if(gp==null){11             gp = new GamePlayer("张三");12         }13         gp.login(username, password);14     }15 16     public void killBoss() {17         //都需要判断真实主题类的存在与否。18         if(gp==null){19             gp = new GamePlayer("张三");20         }21         gp.killBoss();22     }23 24     public void upGrade() {25         //都需要判断真实主题类的存在与否。26         if(gp==null){27             gp = new GamePlayer("张三");28         }29         gp.upGrade();30     }31 }

 

(下一篇)种设计模式----------代理模式(三)

23种设计模式----------代理模式(二)