代理模式學習
阿新 • • 發佈:2020-09-20
代理模式
代理模式是結構型模式,相當於給一個物件生成一個代理物件,我們去訪問的時候直接面對的是代理物件。在平時的生活中也有類似的例子,比如房產中介,我們在租房的時候面對的不是真正的房東而是中介,這個中介就相當於房東的代理物件。代理物件可以對原物件的功能進行增強。下面通過一張圖來展示下代理模式。
在上圖中,我們可以看到代理類和被代理類都需要繼承同一個介面,然後代理類又繼承了被代理類,這樣就可以對被代理類進行功能增強。然後我們使用者訪問的是代理類。
代理型別的分類:
- 靜態代理
- 動態代理
靜態代理
靜態代理:相當於提前實現好代理類,在需要的時候直接建立例項即可。靜態代理存在一些侷限,比如一些被代理類需要相同的功能增強邏輯,靜態代理就需要一個個去實現這些類的代理類,非常的麻煩,編碼量大,同時也不易管理。
靜態代理程式碼實現
場景描述:使用者去租房,租房找的都是中介而並非房東
- 實現租房介面
//租房介面
public interface Rent {
void rentHouse();
}
- 房東類的實現(也就是被代理類),需要實現介面
//房東類實現了租房的介面
public class Host implements Rent {
@Override
public void rentHouse() {
System.out.println("我是房東,我要出租房子");
}
}
- 中介類的實現(也就是代理類),需要實現介面
//中介類,同樣實現了租房介面,並且需要加入房東類,呼叫房東類中的功能 public class RentProxy implements Rent { private Host host; public RentProxy(Host host) { this.host = host; } @Override public void rentHouse() { System.out.println("我是中介,帶著客戶去看房子"); host.rentHouse(); } }
- 測試程式碼
public class ProxyTest {
public static void main(String[] args) {
//呼叫中介的租房方法
RentProxy proxy = new RentProxy(new Host());
proxy.rentHouse();
}
}
動態代理
動態代理,相對於靜態代理來說就是代理類是動態生成的而不是提前編碼好。動態代理,減少了編碼量以及方便管理。這裡動態代理的實現是基於介面的實現。動態代理的有兩種常見的實現:
- Jdk動態代理:基於介面的實現。
- cglib動態代理:基於類的實現。
下面的程式碼實現是基於介面的實現,也就是jdk動態代理
動態代理程式碼實現
- 同靜態代理第一步:實現租房介面
- 同靜態代理第二步:實現房東類
- 實現代理handler,這裡沒有實現代理類,區別於靜態代理
//實現代理handler
public class RentProxyHandler implements InvocationHandler {
private Object rent;
public RentProxyHandler(Object rent) {
this.rent = rent;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws
Throwable {
//功能增強
System.out.println("中介帶著客戶去看房子");
//呼叫被代理類中的方法
method.invoke(rent,args);
return null;
}
}
- 測試程式碼
public class ProxyTest {
public static void main(String[] args) {
//建立需要被代理的物件,這裡就是房東
Host host = new Host();
//建立代理handller,然後將需要被代理的物件傳入到handller中
RentProxyHandler proxyHandler = new RentProxyHandler(host);
//這裡用於動態的生成代理物件,也就是相當於我們之前寫RentProxy,不過這裡我們是自動生成的
Rent rentProxy = (Rent) Proxy.newProxyInstance(host.getClass().getClassLoader(),
host.getClass().getInterfaces(), proxyHandler);
rentProxy.rentHouse();
}
}