静态代理模式
什么是静态代理?
代理模式,顾名思义,就是找一个能代理自己工作的类来完成目标类的工作,这个代理类能在完成工作的同时对其进行验证和收尾工作。拿卖二手车做例子,当你的时间有限,可以找一个代理商帮你把车卖出去,代理商在帮你卖车的时候,能帮你完成诸如过户、注销等等手续,这就是代理商的作用。
而静态代理,就是为目标类定制的代理,如果需要完成其他性质的工作,还需重新设计代理类来完成代理工作。
如何实现静态代理?
例子:
假设我们有一个文档管理类,可以通过他来完成对文档的读写操作,为了在读写之前验证权限,在读写过程中输出日志,我们为他设计一个静态代理类,代替他完成工作。
权限类:privilege.java
package com.proxypattern;
public class Privilege {
//key为“root”时即有权限
private String key;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
}
日志类:Logger.java
package com.proxypattern;
public class Logger {
public void writeLog(String log){
System.out.println("日志输出:" + log);
}
}
目标类接口(文档管理接口):DocumentManager.java
package com.proxypattern;
public interface DocumentManager {
public void readDocument();
public void writeDocument();
}
目标类:DocumentManagerImpl.java
package com.proxypattern;
public class DocumentManagerImpl implements DocumentManager {
@Override
public void readDocument() {
System.out.println("读取文档...");
}
@Override
public void writeDocument() {
System.out.println("写入文档...");
}
}
代理类:DocumentManagerProxy.java
package com.proxypattern;
/**
* 代理类,顾名思义就是代替DocumentManager来完成任务的。
* 静态代理中代理类要实现目标类的接口,在构造函数中获取代理类需要用到的切入对象,如权限验证,日志。
* 在实现的接口方法中加入权限验证等切入操作。
*/
public class DocumentManagerProxy implements DocumentManager{
private DocumentManager documentManager;
private Logger loggeer;
private Privilege privilege;
public DocumentManagerProxy(DocumentManager documentManager, Logger loggeer, Privilege privilege) {
this.documentManager = documentManager;
this.loggeer = loggeer;
this.privilege = privilege;
}
@Override
public void readDocument() {
if (this.privilege.getKey().equals("root")){
this.loggeer.writeLog("权限验证通过!");
this.documentManager.readDocument();
this.loggeer.writeLog("读取成功!");
}else{
System.out.println("Error:没有权限,读取失败!");
this.loggeer.writeLog("没有权限,读取失败");
}
}
@Override
public void writeDocument() {
if (this.privilege.getKey().equals("root")){
this.loggeer.writeLog("权限验证通过!");
this.documentManager.readDocument();
this.loggeer.writeLog("写入成功!");
}else{
System.out.println("Error:没有权限,写入失败!");
this.loggeer.writeLog("没有权限,写入失败");
}
}
}
测试:
package com.proxypattern;
import org.junit.Test;
import sun.rmi.runtime.Log;
/**
* @author zdxie
* @Date 上午 8:28 2017/9/6
* @Description 测试代理类
*/
public class TestStaticProxy {
@Test
public void testDocument(){
DocumentManager manager = new DocumentManagerImpl();
Logger logger = new Logger();
Privilege privilege = new Privilege();
privilege.setKey("key");
DocumentManagerProxy proxy = new DocumentManagerProxy(manager,logger,privilege);
proxy.readDocument();
}
}
静态代理模式的优缺点
优点:
1. 能完成对目标类的各种切入操作。
2. 实现了代替目标类完成工作。
缺点:
1.目标接口如果方法有变动,对代理类也要做相应的变动。
2.一个代理类只对应一个目标类,其他工作需要重新设计代理。