原文地址:http://te-amo.site/user/article/info/ARTICLE20180422043104194
文章中部分定义和解释性文字,都是引用百度百科,主要的代码及场景应用为本人原创
代理模式为其他对象提供一种代理以控制对这个对象的访问。代理对象在客户端和目标对象之间起到中介的作用。
场景:在一个系统中有个统计服务,当进行统计服务之前需要检查并开启需要统计的资源,统计完成后需要关闭不必要的资源,避免浪费服务器资源。对于这一个需求可以使用代理模式来设计,在统计之前和之后所做的事情很统计服务本身没有太多关系,采用这种模式可以解耦,同时也使得需要统计的资源可配置,提高灵活性。
构成
- 抽象角色:通过接口或抽象类声明真实角色实现的业务方法。(Statistics)
- 代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。(ProxyStatistics)
- 真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。(RealStatistics)
设计
实现
代码地址:https://github.com/telundusiji/designpattern
抽象角色 统计接口
public interface Statistics {
void statistics();
}
真实角色 统计实现
@Slf4j
public class RealStatistics implements Statistics {
@Override
public void statistics() {
log.info("开始统计......");
log.info("统计完成!");
}
}
静态代理的方式 代理角色 统计代理
@Slf4j
public class ProxyStatistics implements Statistics{
private RealStatistics realStatistics;
public ProxyStatistics(RealStatistics realStatistics){
this.realStatistics = realStatistics;
}
@Override
public void statistics() {
log.info("统计前,开启需要统计的服务");
realStatistics.statistics();
log.info("统计结束,关闭服务!");
}
}
动态代理方式(代理角色是动态生成,所以这并不是代理角色)
@Slf4j
public class DynamicProxyStatisticsHandler implements InvocationHandler {
private RealStatistics realStatistics;
public DynamicProxyStatisticsHandler(RealStatistics realStatistics) {
this.realStatistics = realStatistics;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object result = method.invoke(realStatistics,args);
after();
return null;
}
private void before() {
log.info("统计前,开启需要统计的服务");
}
private void after() {
log.info("统计结束,关闭服务!");
}
}
优点
- 职责清晰:真实的角色是实现实际的业务逻辑,不用关心其他非本职责的事务。
- 代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介的作用和保护了目标对象的作用。
java中的静态代理和动态代理可以阅读以下文章: