代理模式为其它对象提供了一个代理来控制对对象的访问。
代理对象和实际对象通过实现相同的接口,其它类通过访问代理对象,代理对象将请求转发给实际对象来实现对实际对象的访问。
//代理接口
interface Interface
{
void doSomething();
void doElse();
}
//实际对象
class RealObject implements Interface
{
public void doSomething()
{
System.out.println("real object do something.");
}
public void doElse()
{
System.out.println("real object do else.");
}
}
//代理对象
public class SimpleProxy implements Interface
{
private Interface real;
public SimpleProxy(Interface real)
{
this.real = real;
}
//代理对实际对象功能的扩展
public void doSomething()
{
System.out.println("---------before-------");
real.doSomething();
System.out.println("---------after-------");
}
public void doElse()
{
System.out.println("---------before-------");
real.doElse();
System.out.println("---------after-------");
}
public static void main(String[] args)
{
}RealObject real = new RealObject();
//直接访问实际对象
real.doSomething();
real.doElse();
SimpleProxy proxy = new SimpleProxy(real);
//访问代理对象
proxy.doSomething();
}proxy.doElse();
运行结果:
real object do something.
real object do else.
---------before-------
real object do something.
---------after-------
---------before-------
real object do else.
---------after-------
代理模式的应用场景有,远程代理、智能指针、事务、权限等。但针对一个功能,对每一个接口都需要实现一个代理,当需要实现的功能和接口较多时,代理的数量会很大。
interface Interface1//接口1
{
void doSome();
}
interface Interface2//接口2
{
void doElse();
}
class RealObject implements Interface1, Interface2//实现接口1和接口2
{
public void doSome()
{
System.out.println("real object do some.");
}
public void doElse()
{
System.out.println("real object do else.");
}
}
class TimeProxy1 implements Interface1//对接口1的时间代理
{
private Interface1 real;
public TimeProxy1(Interface1 real)
{
this.real = real;
}
public void doSome()
{
System.out.println("---------start time-------");
real.doSome();
System.out.println("---------end time-------");
}
}
class TimeProxy2 implements Interface2//对接口2的时间代理
{
private Interface2 real;
public TimeProxy2(Interface2 real)
{
this.real = real;
}
public void doElse()
{
System.out.println("---------start time-------");
real.doElse();
System.out.println("---------end time-------");
}
}
public class SimpleProxy
{
public static void main(String[] args)
{
RealObject real = new RealObject();
real.doSome();
real.doElse();
Interface1 proxy1 = new TimeProxy1(real);//对接口1的时间代理
proxy1.doSome();
Interface2 proxy2 = new TimeProxy2(real);//对接口2的时间代理
proxy2.doElse();
}
}
示例代码对接口1和接口2都需要实现时间代理。
动态代理相对于普通的代理模式又向前了一步,对一个功能只需要实现一个调用处理器即可,对不同的接口会动态生成不同的代理。
class TimeInvocationHandler implements InvocationHandler//时间调用处理器
{
private Object real;
public TimeInvocationHandler(Object real)
{
this.real = real;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
System.out.println("---------start time-------");
Object obj = method.invoke(real, args);
System.out.println("---------end time-------");
return obj;
}
}
public class DynamicProxy
{
public static void main(String[] args)
{
RealObject real = new RealObject();
real.doSome();
real.doElse();
//生成接口1的代理
Class proxyClass = Proxy.getProxyClass(Interface1.class.getClassLoader(), new Class[] {Interface1.class});
//通过反射获得构造函数,生成代理类
Interface1 proxy1 = (Interface1) proxyClass.getConstructor(new Class[] {InvocationHandler.class})
.newInstance(new Object[] {new TimeInvocationHandler(real)});
//生成接口2的代理类
Interface2 proxy2 = (Interface2) Proxy.newProxyInstance(Interface2.class.getClassLoader(),
new Class[] {Interface2.class},
new TimeInvocationHandler(real));
proxy2.doElse();
}
}
对于时间功能只需要实现一个时间调用处理器就可以使用JDK的动态代理对不同接口生成代理类。同样,对事务、日志等功能只需要实现一个调用处理器即可,代理对所有的请求都会转发到调用处理器。