給某一對(duì)象提供代理,并由代理對(duì)象控制對(duì)原對(duì)象的引用姆吭。
Provide a surrogate or placeholder for another object to control access to it.
定義本身已經(jīng)很明確了,代理模式被用于我們想要提供一個(gè)受到訪問(wèn)控制的功能幼苛。
假設(shè)有個(gè)類負(fù)責(zé)執(zhí)行系統(tǒng)命令超全。正常使用是沒(méi)問(wèn)題的,但是一旦打算供客戶端調(diào)用穷绵,可能會(huì)導(dǎo)致比較麻煩的問(wèn)題轿塔,比如客戶端程序可能執(zhí)行一些問(wèn)題刪掉了一些系統(tǒng)文件或者修改了一些配置文件等。
這時(shí)可以創(chuàng)建一個(gè)代理類來(lái)提供程序的訪問(wèn)控制仲墨。
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
現(xiàn)在我們想讓管理員擁有全部的權(quán)限勾缭,非管理員僅可以執(zhí)行部分相對(duì)安全的命令。
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
客戶端測(cè)試程序
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());
}
}
}
測(cè)試程序的輸出為:
'ls -ltr' command executed.
Exception Message::rm command is not allowed for non-admin users.
總結(jié)一下
代理模式可以把權(quán)限系統(tǒng)等和具體業(yè)務(wù)代碼分開(kāi)目养、解耦俩由。