上一节 23种设计模式之适配器模式
代理模式(Proxy pattern)
核心作用:通过代理,控制对对象的访问!
可以详细控制访问某个(某类)对象的方法,在调用这个方法前做前置处理,调用这个方法后做后置处理(即:AOP的微观实现)
AOP(Aspect Oriented Programming面向切面编程)的核心实现机制。
应用场景:
安全代理:屏蔽对真实角色的直接访问。
远程代理:通过代理类处理远程方法调用(RMI)
延迟加载:先加载轻量级的代理对象,真正需要再加载真实对象。
分类:
1、静态代理(静态定义代理类)
2、动态代理(动态定义代理类)
- JDK自带的动态代理;
- javaassist字节码操作库实现;
- CGLIB;
- ASM(底层使用指令,可维护性较差)
核心角色
- 抽象角色
定义代理角色和真实角色的公共对外方法
- 真实角色
实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。
关注真正的业务逻辑!
- 代理角色
实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法实现抽象方法,并可以附加自己的操作。
将统一的流程控制放到代理角色中处理。
类图
静态代理代码实现
接口:
public interface Star {
void confer(); //面谈
void signContract(); //签订合同
void bookTicket(); //订机票
void sing(); //唱歌
void collectMoney(); //尾款
}
真实角色:
public class RealStar implements Star{
@Override
public void confer() {
System.out.println("RealStra.confer");
}
@Override
public void signContract() {
System.out.println("RealStra.signContract");
}
@Override
public void bookTicket() {
System.out.println("RealStra.bookTicket");
}
@Override
public void sing() {
System.out.println("RealStra(真实角色).sing");
}
@Override
public void collectMoney() {
System.out.println("RealStra.collectMoney");
}
}
代理角色:
public class ProxyStar implements Star{
private Star star;
public ProxyStar(Star star) {
super();
this.star = star;
}
@Override
public void confer() {
System.out.println("ProxyStar.confer");
}
@Override
public void signContract() {
System.out.println("ProxyStar.signContract");
}
@Override
public void bookTicket() {
System.out.println("ProxyStar.bookTicket");
}
@Override
public void sing() {
star.sing();
}
@Override
public void collectMoney() {
System.out.println("ProxyStar.collectMoney");
}
}
测试类:
public class Client {
public static void main(String[] args) {
Star real=new RealStar();
Star proxy=new ProxyStar(real);
proxy.confer();
proxy.signContract();
proxy.bookTicket();
proxy.sing();
proxy.collectMoney();
}
}
测试结果:
ProxyStar.confer
ProxyStar.signContract
ProxyStar.bookTicket
RealStra(真实角色).sing
ProxyStar.collectMoney
动态代理代码实现
接口及真实角色同上(静态代理代码实现)!
代理角色:
public class StarHandler implements InvocationHandler{
private Star star;
public StarHandler(Star star) {
super();
this.star = star;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object obj=null;
//其他前置代理方法
System.out.println("面谈、签合同、订机票");
if(method.getName().equals("sing")){
obj=method.invoke(star, args);
}
//其他后置代理方法
System.out.println("尾款");
return obj;
}
}
测试类:
public class Client {
public static void main(String[] args) {
//动态模板
Star real=new RealStar();
StarHandler starHandler=new StarHandler(real);
Star proxy=(Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),new Class[]{Star.class},starHandler);
proxy.sing();
}
}
测试结果:
面谈、签合同、订机票
RealStra(真实角色).sing
尾款
代理模式的优点
- 职责清晰
真实的角色就是实现实际的业务逻辑,不用关心其他非本指责的事务,通过后期代理完成一件事务,附带结果就是编程简洁清晰。
- 高扩展性
具体主题角色是随时都会发生变化的,只要它实现了接口。
下一节 23种设计模式之组合模式 待续......