Java學習筆記之--------代理模式
代理模式
代理模式的定義:為其他物件提供一種代理以控制對這個物件的訪問。在某些情況下,一個物件不適合或者不能直接引用另一個物件,而代理物件可以在客戶端和目標物件之間起到中介的作用。
組成: 抽象角色:通過介面或抽象類宣告真實角色實現的業務方法。 代理角色:實現抽象角色,是真實角色的代理,通過真實角色的業務邏輯方法來實現抽象方法,並可以附加自己的操作。 真實角色:實現抽象角色,定義真實角色所要實現的業務邏輯,供代理角色呼叫。
代理模式的類圖
靜態代理模式的程式碼實現 下面模擬租房來實現一下靜態代理模式。Client代表房客,Proxy代表中介(代理角色),Host代表房東(真實角色)。Rent介面代表抽象角色。
public interface Rent {
public void rent();
}
public class Host implements Rent{
public void rent(){
System.out.println("房屋出租");
}
}
public class Proxy implements Rent{ private Host host; public Proxy() { } public Proxy(Host host) { this.host = host; } public void setHost(Host host) { this.host = host; } //租房 public void rent(){ seeHouse(); host.rent(); fare(); } //看房 private void seeHouse(){ System.out.println("帶房客看房"); } //收中介費 private void fare(){ System.out.println("收取中介費"); } }
public class Client {
public static void main(String[] args) {
Host host = new Host();
Proxy proxy = new Proxy(host);
proxy.rent();
}
}
執行結果如下所示:
由以上程式碼我們可以看出,使用靜態代理後,因為增加了代理類,我們的工作量變大了,開發效率就會降低。由此我們想到了——動態代理。
動態代理模式的程式碼實現 動態代理模式的代理類是動態生成的。動態代理大致分為兩類:基於介面的動態代理和基於類的動態代理。 jdk動態代理——Proxy類和InvocationHandler介面
-
InvocationHandler是代理例項的呼叫處理程式實現的介面。 每個代理例項都具有一個關聯的呼叫處理程式。對代理例項呼叫方法時,將對方法呼叫進行編碼並將其指派到它的呼叫處理程式的invoke方法。 invoke():在代理例項上處理方法呼叫並返回結果。在與方法關聯的代理例項上呼叫方法時,將在呼叫處理程式上呼叫此方法。
-
Proxy提供用於建立動態代理類和例項的靜態方法,它還是由這些方法建立的所有動態代理類的超類。 newProxyInstance():返回一個指定介面的代理類例項,該介面可以將方法呼叫指派到指定的呼叫處理程式。
動態代理的程式碼實現:
public interface UserService {
public void add();
public void update();
public void delete();
public void search();
}
public class UserServiceImpl implements UserService {
@Override
public void add() {
System.out.println("增加使用者");
}
@Override
public void update() {
System.out.println("修改使用者資訊");
}
@Override
public void delete() {
System.out.println("刪除使用者資訊");
}
@Override
public void search() {
System.out.println("查詢使用者資訊");
}
}
public class ProxyInovationHandler implements InvocationHandler{
private Object target;
public void setTarget(Object target) {
this.target = target;
}
/**
* 生成代理類
*/
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
/**
* proxy 代理類
* method 代理類的呼叫處理程式的方法物件
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
log(method.getName());
Object result = method.invoke(target, args);
return result;
}
//執行每個方法前列印日誌
public void log(String methodName){
System.out.println("執行" + methodName + "方法");
}
}
public class Client {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
ProxyInovationHandler pih = new ProxyInovationHandler();
pih.setTarget(userService);
UserService proxy = (UserService) pih.getProxy();
proxy.add();
proxy.delete();
}
}
執行結果如下圖: 代理模式的優缺點
-
優點 (1)職責清晰,真實的角色就是實現實際的業務邏輯,不用關心其他非本職責的事務,通過後期的代理完成一件完成事務,附帶的結果就是程式設計簡潔清晰。 (2)代理物件可以在客戶端和目標物件之間起到中介的作用,這樣起到了中介的作用和保護了目標物件的作用。 (3)高擴充套件性,擴充套件公共業務變得更加集中方便。
-
缺點 (1) 目標類必須實現某個介面,如果某個類沒有實現介面則不能生成代理物件。 (2)由於在客戶端和真實主題之間增加了代理物件,因此有些型別的代理模式可能會造成請求的處理速度變慢,例如保護代理。 (3) 實現代理模式需要額外的工作,而且有些代理模式的實現過程較為複雜,例如遠端代理。
-
其他 一個動態代理一般代理某一類業務。一個動態代理可以代理多個類。
代理模式的使用場景 1、遠端代理。 2、虛擬代理。 3、Copy-on-Write 代理。 4、保護(Protect or Access)代理。 5、Cache代理。 6、防火牆(Firewall)代理。 7、同步化(Synchronization)代理。 8、智慧引用(Smart Reference)代理。
注意事項: 1、和介面卡模式的區別:介面卡模式主要改變所考慮物件的介面,而代理模式不能改變所代理類的介面。 2、和裝飾器模式的區別:裝飾器模式為了增強功能,而代理模式是為了加以控制。
以上為【2天學會spring框架-鄒波】視訊中部分內容加自己整理的一些內容,侵刪。