之前说了基本的代理模式和普通代理模式。接下来开始看下强制代理模式和虚拟代理模式
三,强制代理模式:
一般的代理模式都是通过代理类找到被代理的对象,从而调用被代理类中的方法(即完成被代理类中的任务)。
而,强制代理模式则是先找到被代理类自己去完成事情,然后被代理类又将该做的事情转交到代理类中,让代理类来完成。
假如:你有事求助于某位名人。
你告诉名人说有事想请他帮忙,然后他说最近一段时间比较忙,要不你找我的经纪人来办吧。
(本来找名人办事,事情由他来完成的,即 表示 真实主题类。然而,他要将事情转交给自己的经纪人(即代理类),这时该名人就是被代理者)。
代码实现如下
抽象主题类或者接口:
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 //击杀Boss 11 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 }