设计模式(六)代理模式

——核心作用:通过代理,控制对对象的访问,可以详细控制访问某个(某类)对象的方法,在调用这个方法前做前置处理,从而实现将统一流程代码放到代理类中处理,调用这个方法后做后置处理。

——AOP(Aspect Oriented Programming面向切面编程)的核心实现机制

 

——核心角色:

  抽象角色:定义代理角色和真实角色的公共对外方法。

  真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。

       关注真正的业务逻辑。

  代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附                      加自己的操作。

       将统一的流程控制放到代理角色中处理。

 

——应用场景:

  安全代理:屏蔽对真实角色的直接访问。

  远程代理:通过代理类处理进程方法调用(RMI)。

  延迟加载:先加载轻量级的代理对象,真正需要再加载真实对象。

    (比如你要开发一个大文档查看软件,大文档中有大的图片,有可能一个图片有100MB,在打开文件时不可能将所有的图片都显示出来,这样就可以使用代理模式,当需要查看图片时,用Proxy来进行大图片的打开)

——分类:

  静态代理(静态定义代理类)

  动态代理(动态生成代理类)

    • JDK自带的动态代理
    • Javaassist字节码操作库实现
    • CGLIB
    • ASM(底层使用指令,可维护性较差)

 

静态代理:

1. 定义一个Star接口

 1 package com.ztq.proxy.staticProxy;
 2 
 3 public interface Star {
 4     /***
 5      * 面谈
 6      */
 7     void confer();
 8     
 9     /***
10      * 签合同
11      */
12     void signContract();
13     
14     /***
15      * 订票
16      */
17     void bookTicket();
18     
19     /***
20      * 唱歌
21      */
22     void sing();
23     
24     /***
25      * 收钱
26      */
27     void collectMoney();
28 }

 

2. 定义一个RealStar类

 1 package com.ztq.proxy.staticProxy;
 2 
 3 public class RealStar implements Star{
 4 
 5     @Override
 6     public void confer() {
 7         System.out.println("RealStar.confer()");
 8     }
 9 
10     @Override
11     public void signContract() {
12         System.out.println("RealStar.signContract()");
13     }
14 
15     @Override
16     public void bookTicket() {
17         System.out.println("RealStar.bookTicket()");
18     }
19 
20     @Override
21     public void sing() {
22         System.out.println("RealStar.sing()");
23     }
24 
25     @Override
26     public void collectMoney() {
27         System.out.println("RealStar.collectMoney()");
28     }
29     
30 }

 

3. 定义一个ProxyStar类

 1 package com.ztq.proxy.staticProxy;
 2 
 3 public class ProxyStar implements Star{
 4 
 5     private Star star;
 6     
 7     public ProxyStar(Star star){
 8         super();
 9         this.star = star;
10     }
11     
12     @Override
13     public void confer() {
14         System.out.println("ProxyStar.confer()");
15     }
16 
17     @Override
18     public void signContract() {
19         System.out.println("ProxyStar.signContract()");
20     }
21 
22     @Override
23     public void bookTicket() {
24         System.out.println("ProxyStar.bookTicket()");
25     }
26 
27     @Override
28     public void sing() {
29         star.sing();
30     }
31 
32     @Override
33     public void collectMoney() {
34         System.out.println("ProxyStar.collectMoney()");
35     }
36     
37 }

 

4. 定义一个客户端调用

 1 package com.ztq.proxy.staticProxy;
 2 
 3 public class Client {
 4     public static void main(String[] args) {
 5         Star real = new RealStar();
 6         Star proxy = new ProxyStar(real);
 7         
 8         proxy.confer();
 9         proxy.signContract();
10         proxy.bookTicket();
11         proxy.sing();
12         proxy.collectMoney();
13     }
14 }

 

 

运行结果:

ProxyStar.confer()
ProxyStar.signContract()
ProxyStar.bookTicket()
RealStar.sing()
ProxyStar.collectMoney()

 

 

UML图:

 


 

动态代理相比于静态代理的优点:抽象角色中(接口)声明的所有方法都被转移到调用处理器一个集中的方法中处理,这样我们可以更加灵活和统一的处理众多的方法。

 

JDK自带的动态代理:

  java.lang.reflect.Proxy 作用:动态生成代理类和对象

  java.lang.reflect.InvocationHandler(处理器接口)

    可以通过invoke方法实现对真实角色的代理访问。

    每次通过Proxy生成代理类对象时都要指定对应的处理器对象。

 

Star接口、RealStar类与静态代理一样,此处省略。

定义一个StarHandler类

 1 package com.ztq.proxy.dynamicProxy;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 
 6 public class StarHandler implements InvocationHandler{
 7 
 8     Star realStar;
 9     
10     public StarHandler(Star realStar) {
11         super();
12         this.realStar = realStar;
13     }
14 
15     @Override
16     public Object invoke(Object proxy, Method method, Object[] args)
17             throws Throwable {
18         Object object = null;
19         System.out.println("真正的方法执行前");
20         System.out.println("面谈,签合同,预付款,订机票");
21         if(method.getName().equals("sing")){
22             object = method.invoke(realStar, args);
23         }
24         System.out.println("真正的方法执行后");
25         System.out.println("收尾款");
26         return object;
27     }
28 
29 }

 

定义一个客户端调用类

 1 package com.ztq.proxy.dynamicProxy;
 2 
 3 import java.lang.reflect.Proxy;
 4 
 5 public class Client {
 6     public static void main(String[] args) {
 7         Star realStar = new RealStar();
 8         StarHandler handler = new StarHandler(realStar);
 9         Star proxy = (Star)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Star.class}, handler);
10         
11         proxy.bookTicket();
12         proxy.sing();
13     }
14 }

 

运行结果

真正的方法执行前
面谈,签合同,预付款,订机票
真正的方法执行后
收尾款
真正的方法执行前
面谈,签合同,预付款,订机票
RealStar.sing()
真正的方法执行后
收尾款

 

posted @ 2016-11-15 21:38  Chris_z  阅读(496)  评论(0编辑  收藏  举报