代理模式的定义:由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。代理模式的特点就是控制对象的访问。
代理模式的结构:
- 抽象主题(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。
- 真实主题(Real Subject)类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
- 代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。
结构图:
代码实现:
建立抽象主题类(Subject):可以使接口活抽象类声明方法,这里我们定义为接口。
public interface Subject {
void Request();
}
建立真实主题类(Realsubject):实现抽象主题类(Subject)。
public class RealSubject implements Subject {
@Override
public void Request() {
System.out.println("访问真实主题方法...");
}
}
建立代理类(Proxy):要行使代理的职责了,内部对真实类进行了引用,通过引用可以调用真实主题的方法,也可以进行拓展、控制真实主题的功能。
public class Proxy implements Subject {
private RealSubject realSubject;
@Override
public void Request() {
if (realSubject==null)
{
realSubject=new RealSubject();
}
preRequest();
realSubject.Request();
postRequest();
}
public void preRequest()
{
System.out.println("访问真实主题之前的预处理。");
}
public void postRequest()
{
System.out.println("访问真实主题之后的后续处理。");
}
}
我们在这里增加preRequest()、postRequest()方法可以理解为拓展。你也可以加入一些逻辑来控制访问真实主题的方法。
加入测试类(ProxyTest)
public class ProxyTest extends Application {
public static void main(String[] args) {
Proxy proxy=new Proxy();
proxy.Request();
}
}
输出结果:
代理模式的扩展:动态代理
Java在java.lang.reflect包中有自己的代理支持,利用这个包你可以在运行时动态的创建一个代理类,实现一个或多个接口,并将方法的调用转发到你所指定的类。因为实际的代理类是在运行时创建的,我们称这个java技术为:动态代理。
结构图:
在上面的例子的基础上,增加DynamicProxy实现InvocationHandler接口
public class DynamicProxy implements InvocationHandler {
private Object obj=null;
public DynamicProxy(Object obj){
this.obj=obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
method.invoke(obj,args);
return null;
}
}
增加一个RealSubject2的主题类
public class RealSubject2 implements Subject {
@Override
public void Request() {
System.out.println("访问真实主题方法2...");
}
}
修改ProxyTest类
public class ProxyTest extends Application {
public static void main(String[] args) {
Subject subject=null;
InvocationHandler handler=null;
handler=new DynamicProxy(new RealSubject2());
subject= (Subject) Proxy.newProxyInstance(Subject.class.getClassLoader(),new Class[]{Subject.class},handler);
subject.Request();
}
@Override
public void start(Stage primaryStage) {
}
}
输出结果: