给某一对象提供代理,并由代理对象控制对原对象的引用。
Provide a surrogate or placeholder for another object to control access to it.
定义本身已经很明确了,代理模式被用于我们想要提供一个受到访问控制的功能。
假设有个类负责执行系统命令。正常使用是没问题的,但是一旦打算供客户端调用,可能会导致比较麻烦的问题,比如客户端程序可能执行一些问题删掉了一些系统文件或者修改了一些配置文件等。
这时可以创建一个代理类来提供程序的访问控制。
Proxy Design Pattern – Main Class
CommandExecutor.java and CommandExecutorImpl.java
public interface CommandExecutor{
public void runCommand(String cmd) throws Exception;
}
public class CommandExecutorImpl implements CommandExecutor{
@Override
public void runCommand(String cmd) throws IOException{
//some heavy implementation
Runtime.getRuntime().exec(cmd);
System.out.println("'" + cmd + "' command executed.")
}
}
Proxy Design Pattern – Proxy Class
现在我们想让管理员拥有全部的权限,非管理员仅可以执行部分相对安全的命令。
CommandExecutorProxy.java
public class CommandExecutorProxy implements CommandExecutor{
private boolean isAdmin;
private CommandExecutor executor;
public CommandExecutorProxy(String user,String pwd){
if("Pankaj".equals(user) && "J@urnalD$v".equals(pwd)) isAdmin=true;
executor = new CommandExecutorImpl();
}
@Override
public void runCommand(String cmd) throws Exception {
if(isAdmin){
executor.runCommand(cmd)
}else{
if(cmd.trim().startsWith("rm")){
throw new Exception("rm command is not allowed for non-admin users");
}else{
executor.runCommand(cmd);
}
}
}
}
Proxy Design Pattern Client Program
客户端测试程序
public class ProxyPatternTest {
public static void main(String[] args){
CommandExecutor executor = new CommandExecutorProxy("Pankaj", "wrong_pwd");
try {
executor.runCommand("ls -ltr");
executor.runCommand(" rm -rf abc.pdf");
} catch (Exception e) {
System.out.println("Exception Message::"+e.getMessage());
}
}
}
测试程序的输出为:
'ls -ltr' command executed.
Exception Message::rm command is not allowed for non-admin users.
总结一下
代理模式可以把权限系统等和具体业务代码分开、解耦。
网友评论