代理模式是最常用的模式之一,用一个代理来隐藏具体实现类的实现细节,通常还用于在真实的实现的前后添加一部分功能。在细节一点说,就是我们使用代理对象来代替对真实对象的访问,这样可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能。
代理模式的主要作用是扩展目标对象的功能,比如说在目标对象的某个方法执行前后可以增加一些自定义的操作。
既然是代理,那就表示要对客户端隐藏真实实现,由代理来负责客户端的所有请求。当然,代理只是一个代理,它不会完成实际的业务逻辑,而只是一个外壳。但是对于客户端来说,它必须表现得就是客户端需要的真实实现。
静态代理
我们这里只讲静态代理,因为本篇文章主旨就是介绍设计模式。
静态代理实现步骤:
- 定义一个接口
- 创建一个目标类实现此接口
- 创建一个代理类同样实现这个接口
- 将目标对象注入进代理类,然后在代理类的对应方法调用目标类中的对应方法。这样我们就可以通过代理类屏蔽对目标对象的访问,并且可以在目标方法执行前后增加自定义操作。
创建接口
public interface SmsService {
String send(String message);
}
创建目标类实现此接口
public class SmsServiceImpl implements SmsService{
@Override
public String send(String message) {
System.out.println("send message:"+message);
return message;
}
}
创建代理类同样实现此接口
public class SmsProxy implements SmsService{
private final SmsService smsService;
public SmsProxy(SmsService smsService){
this.smsService=smsService;
}
@Override
public String send(String message) {
System.out.println("before method send()");
smsService.send(message);
System.out.println("after method send()");
return null;
}
}
client端调用代理类使用send功能
public class client {
public static void main(String[] args) {
SmsService smsService = new SmsServiceImpl();
SmsProxy smsProxy = new SmsProxy(smsService);
smsProxy.send("java");
}
}
代理模式说白了就是做方法包装或者方法增强。在面向切面编程中,其实就是动态代理的过程。比如在Spring中,我们自己不定义代理类,但是Spring会帮我们动态定义代理,然后把我们定义在@Before、@After、@Around中的代码逻辑动态添加到代理中。