代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介
优缺点
优点
- 职责清晰
- 高扩展性
- 智能化
缺点
- 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢
- 实现代理模式需要额外的工作,有些代理模式的实现非常复杂
角色
- Subject:抽象主题角色,是一个接口。该接口是对象和它的代理共用的接口
- RealSubject:真实主题角色,是实现抽象主题接口的类
- Proxy:代理角色,内部含有对真实对象RealSubject的引用,从而可以操作真实对象。代理对象提供与真实对象相同的接口,以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装
实现动态代理的关键技术是反射
静态代理
首先是一个抽象主题角色1
2
3public interface Subject {
void request();
}
然后是具体主题角色1
2
3
4
5
6public class RealSubject implements Subject{
public void request() {
System.out.println("真正的角色");
}
}
最后是代理角色1
2
3
4
5
6
7
8
9
10
11
12public class StaticProxy implements Subject{
private Subject subject;
public StaticProxy(Subject subject) {
this.subject = subject;
}
public void request() {
System.out.println("before");
subject.request();
System.out.println("after");
}
}
测试1
2
3
4
5
6
7
8public class Test {
//静态代理
public static void main(String[] args) {
Subject subject = new RealSubject();
StaticProxy proxy = new StaticProxy(subject);
proxy.request();
}
}
动态代理
在动态代理模式中,抽象代理者和具体代理者是相同的,不同的是代理角色1
2
3
4
5
6
7
8
9
10
11
12
13public class DynamicProxy implements InvocationHandler{
private Object target;
public DynamicProxy(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
Object result = method.invoke(target, args);
System.out.println("after");
return result;
}
}
测试1
2
3
4
5
6
7
8
9
10
11public class Test {
//动态代理
public static void main(String[] args) {
Subject subject = new RealSubject();
DynamicProxy handler = new DynamicProxy(subject);
Subject proxy = (Subject) Proxy.newProxyInstance(
Thread.currentThread().getContextClassLoader(),
subject.getClass().getInterfaces(), handler);
proxy.request();
}
}