Java设计模式之代理模式的静态代理
前言
代理模式分为静态和动态。同时静态代理又分为普通代理和强制代理。因此本文会通过示例的方式详细介绍着静态的两种代理模式。我们依然以网上购物为例。
普通代理
定义:要求客户端只能访问代理角色,而不能直接访问真实角色。我们需要修改真实角色:
1 public class RealConsumer implements IConsumer { 2 3 private String name = null; 4 5 public RealConsumer(IConsumer consumer, String name) throws Exception{ 6 if(consumer == null) { 7 throw new Exception("不能创建真实角色"); 8 } 9 this.name = name; 10 } 11 12 @Override 13 public void login(String name, String password) { 14 System.out.println("登录用户["+name+"]登陆成功"); 15 } 16 17 @Override 18 public void order() { 19 20 System.out.println("登录账号:"+ this.name +"生成订单成功"); 21 22 } 23 24 @Override 25 public void pay() { 26 27 System.out.println("登录账号:"+ this.name +"订单支付成功"); 28 29 } 30 }
第5行-10行:限制了谁能够创建真实对象,同时传递登录账号。
再来修改一下代理角色。代码图如下所示:
1 public class ProxyConsumer implements IConsumer { 2 3 private IConsumer consumer = null; 4 5 public ProxyConsumer(String name) { 6 try { 7 consumer = new RealConsumer(this, name); 8 } catch (Exception e) { 9 10 } 11 } 12 13 @Override 14 public void login(String name, String password) { 15 consumer.login(name, password); 16 } 17 18 @Override 19 public void order() { 20 consumer.order(); 21 22 } 23 24 @Override 25 public void pay() { 26 consumer.pay(); 27 } 28 }
最后再修改一下场景类,能够满足场景类不再直接使用真实角色。
1 public class Client { 2 3 public static void main(String[] args) { 4 5 IConsumer proxyCosumer = new ProxyConsumer("shujin"); 6 7 proxyCosumer.login("抒尽", "123456"); 8 proxyCosumer.order(); 9 proxyCosumer.pay(); 10 11 } 12 }
打印出来的结果如下图所示:
1 登录用户[抒尽]登陆成功 2 登录账号:shujin生成订单成功 3 登录账号:shujin订单支付成功
普通代码模式,调用者只需要知道代理,而不需要知道代理了谁,屏蔽了真实角色的暴露。真实角色的修改不会对高层产生任何的影响
强制代理
定义:强制代理和普通代理刚好相反。强制代理是通过真实角色找到代理角色。
首先我们在接口中新增一个getProxy方法。
1 public interface IConsumer { 2 3 public void login(String name, String password); 4 5 public void order(); 6 7 public void pay(); 8 9 public IConsumer getProxy(); 10 11 }
修改一下真实角色。
1 public class RealConsumer implements IConsumer { 2 3 private String name = null; 4 private IConsumer proxy = null; 5 6 public RealConsumer(String name){ 7 this.name = name; 8 } 9 10 @Override 11 public void login(String name, String password) { 12 if(!isProxy()) { 13 System.out.println("请使用代理访问。"); 14 return; 15 } 16 17 System.out.println("登录用户["+name+"]登陆成功"); 18 } 19 20 @Override 21 public void order() { 22 23 if(!isProxy()) { 24 System.out.println("请使用代理访问。"); 25 return; 26 } 27 28 System.out.println("登录账号:"+ this.name +"生成订单成功"); 29 30 } 31 32 @Override 33 public void pay() { 34 35 if(!isProxy()) { 36 System.out.println("请使用代理访问。"); 37 return; 38 } 39 40 System.out.println("登录账号:"+ this.name +"订单支付成功"); 41 42 } 43 44 @Override 45 public IConsumer getProxy() { 46 this.proxy = new ProxyConsumer(this); 47 return this.proxy; 48 } 49 50 private boolean isProxy() { 51 if(this.proxy == null) { 52 return false; 53 } 54 return true; 55 } 56 }
第45行-48行,通过真实对象找到代理对象。
第50行-55行,判断对象必须要持有代理对象才能访问。
我们再来看一下代理对象。
1 public class ProxyConsumer implements IConsumer { 2 3 private IConsumer consumer = null; 4 5 public ProxyConsumer(IConsumer consumer) { 6 this.consumer = consumer; 7 } 8 9 @Override 10 public void login(String name, String password) { 11 consumer.login(name, password); 12 } 13 14 @Override 15 public void order() { 16 consumer.order(); 17 18 } 19 20 @Override 21 public void pay() { 22 consumer.pay(); 23 } 24 25 @Override 26 public IConsumer getProxy() { 27 return this; 28 } 29 }
第26行-28行,代理对象没有代理对象,因此它的代理对象默认是它本身。
修改一下场景类:
1 public class Client { 2 3 public static void main(String[] args) { 4 5 IConsumer consumer = new RealConsumer("抒尽"); 6 7 IConsumer proxy = consumer.getProxy(); 8 proxy.login("shujin", "123456"); 9 proxy.order(); 10 proxy.pay(); 11 12 13 } 14 }
第5行:找到真实对象。
第7行:通过真实对象得到代理对象。
第8行:使用代理对象进行访问。
强制代理的特点是从真实角色出发找到代理对象进行访问,代理对象交给了真实对象来控制。