静态代理模式
代理模式相当重要,无论生活中还是软件开发中,它使用的频率非常非常高。
1. 什么代理模式
1.1 代理模式详解:
代理在生活非常容易看见:我们买房,购票,出门旅游,结婚,歌手的经纪人等等,这些都是代理。
- 核心作用
- 通过代理,控制对对象的访问
- 可以详细控制访问某个(某类)对象的方法,在调用这个方法前做前置处理,调用这个方法后做后置处理(即:AOP的微观实现)。从而将同一流程的代码放到代理类中处理。
- 比如一个流行歌手,一个商家找他做广告,那个流行歌需要和商家进行面谈,合同起草,签字,安排机票等等一系列的安排工作。这只是一个客户时候的工作,但是如果有10个,100个客户呢?歌手是唱歌的,别的事情本来完全没有必要做。那么歌手是不是能够让别人来做呢?这样经纪人或者说代理,就产生了。在以后,如果客户需要找歌手做广告,那么客户就要去找代理或者经纪人,代理或者经纪人做哪些和歌手核心方法无关的哪些事情。到真正需要做歌手唱歌的时候,歌手才去唱歌。而且,代理还可以控制歌手什么时候去拍广告,也可以在歌手拍广告之前做一些前置(面谈,起草合同等)工作,在拍广告后的一些后置处理(收尾款等)。最后,你们发现,经纪人的实际的权利,比明星还大。一个经纪人可能到最后反客为主。在实际开发中,代理也有可能编程非常非常重要的角色。
- 通过代理,控制对对象的访问
- AOP(Aspect Oriented Programming 面向切片的编程)的核心实现机制。比如在spring等等一些很流行的框架,都用到了面向切片的编程。
2. 静态代理模式中的角色分类
核心角色:
- 抽象角色 - 公司的规章制度
- 定义代理角色和真实角色的公共对外方法。
- 真实角色 - 相当于明星
- 实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色使用。
- 关注真正的业务逻辑。
- 代理角色 - 相当于经纪人
- 实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑来实现实现抽象方法,并可以附加自己的操作。
- 将统一的流程控制放到代理角色中处理。
- 抽象角色 - 公司的规章制度
还是那之前的经纪人和明星的例子来做解释。抽象角色相当于拍广告这个选项(代理角色和真实角色之间的共同点),真实角色相当于明星,而代理角色相当于经纪人。由于明星(真实角色)和经纪人(代理角色)都可以谈拍广告(抽象角色),所以客户过来谈合作的时候,就很好谈。
2. 静态代理模式的实现
静态代理模式,就是代理类有程序员在程序执行之前,已经写完,在程序运行时直接使用的代理类,成为静态代理类。这次以歌手和经纪人之间的关系为例子显示静态代理类。
2.1 经纪人和歌手代理模式的实现
首先我们要写一个接口,并且经纪人(代理角色)和歌手(真实角色)都必须实现这个接口,以获得统一的方法。
public interface Star { /** * 面谈 */ void confer(); /** * 签合同 */ void signContract(); /** * 订票 */ void bookTicket(); /** * 唱歌 */ void sing(); /** * 收钱 */ void collectMoney(); }
然后,写真实角色,真实角色实现了 Star 这个接口,所以真实角色就拥有 Star 这个接口中定义的行为:
public class RealStar implements Star { public void confer() { System.out.println("RealStar.confer()"); } public void signContract() { System.out.println("RealStar.signContact()"); } public void bookTicket() { System.out.println("RealStar.bookTicket()"); } public void sing() { System.out.println("RealStar(周杰伦本人).sing()"); } public void collectMoney() { System.out.println("RealStar.collectMoney()"); } }
接着,编写代理类,实现 Star 接口的同时必须要注意什么方法是只有真实角色可以完成的,我们需要在代理类中创建一个真实角色对象,以引用只有真实角色可以实现的方法。
public class ProxyStar implements Star { // 创建一个 Star 对象 private Star star; // 可以传入任意一个真实对象,以获得真实角色中的独有方法 public ProxyStar(Star star) { this.star = star; } public void confer() { System.out.println("ProxyStar.confer()"); } public void signContract() { System.out.println("ProxyStar.signContact()"); } public void bookTicket() { System.out.println("ProxyStar.bookTicket()"); } // 调用真实角色中的独有的方法,并可以在其前后设置处理方法 public void sing() { System.out.println("设置舞台"); star.sing(); System.out.println("拆卸舞台"); } public void collectMoney() { System.out.println("ProxyStar.collectMoney()"); } }
之后再客户端进行调用就可以了。
public class Client { public static void main(String[] args) { Star real = new RealStar(); Star proxy = new ProxyStar(real); proxy.confer(); proxy.signContract(); proxy.bookTicket(); proxy.sing(); proxy.collectMoney(); } }
版权声明:本文为qq_41302594原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。