转自: http://www.cnblogs.com/mengdd/archive/2013/01/30/2883468.html

代理模式

  代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。

  在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

 

代理模式一般涉及到的角色

  抽象角色:声明真实对象和代理对象的共同接口。

  代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能够代替真实对象。

  同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。

  真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。

 

用实例来说明

  首先是抽象角色类,可以定义一个接口或者抽象类: 

复制代码
/**
 * 真实对象和代理对象的共同接口
 * 
 */
public abstract class Subject
{
    public abstract void request();
}
复制代码

  之后是真实角色的类,实现接口,并完成实际工作:

复制代码
/**
 * 真实角色
 */
public class RealSubject extends Subject
{
    @Override
    public void request()
    {
        System.out.println("From Real Subject!");
    }
}
复制代码

  然后定义代理角色,内部包含对真实角色对象的引用,并且封装功能:

 

复制代码
/**
 * 代理角色
 * 
 */
public class ProxySubject extends Subject
{
    //代理角色对象内部含有对真实对象的引用
    private RealSubject realSubject;

    @Override
    public void request()
    {
        //在真实角色操作之前所附加的操作
        preRequest();
        if(null == realSubject)
        {
            realSubject = new RealSubject();
        }
        
        //真实角色所完成的事情
        realSubject.request();
        //在真实角色操作之后所附加的操作
        postRequest();
    }
    
    private void preRequest()
    {
        System.out.println("Pre Request.");
    }
    private void postRequest()
    {
        System.out.println("Post Request");
    }
}
复制代码

  在客户端进行调用时:

复制代码
/**
 * 客户类
 *  
 */
public class Client
{
    public static void main(String[] args)
    {
        Subject subject = new ProxySubject();
        subject.request();        
    }    
}
复制代码

  

问题

  如果要按照上述的方式(静态代理)使用代理模式,那么真实角色必须是实现已经存在的,并将其作为代理对象的内部属性。

  但是实际使用时,一个真实角色必须对应一个代理角色,但如果大量使用会导致类的急剧膨胀;此外,如果事先并不知道真实角色,该如何使用代理呢?这个问题可以通过Java的动态代理类来解决。