Java 設(shè)計模型--代理模式

代理模式就是:當(dāng)前對象不愿意干的,沒法干的東西委托給別的對象來做,我只要做好本分的東西就好了!

學(xué)習(xí)了下面兩篇文章
https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247484222&idx=1&sn=5191aca33f7b331adaef11c5e07df468&chksm=ebd7423fdca0cb29cdc59b4c79afcda9a44b9206806d2212a1b807c9f5879674934c37c250a1&scene=21#wechat_redirect

https://www.cnblogs.com/doucheyard/p/5737366.html

靜態(tài)代理

上面的文章挺好的,我就直接復(fù)用例子就好了

用小嬰兒說明,小baby只會吃和睡,拉了粑粑,但是自己不會擦屁股呀,然后他媽媽只能找個保姆,保姆就是被他媽媽代理來照顧嬰兒

public class Baby implements Human {
    
  @Override
    public void eat(){
        System.out.println("小嬰兒只能吃奶....");
    }

    @Override
    public void shit() {
        System.out.println("小嬰兒拉粑粑....");
    }

//保姆類---一個代理類
public class BabySitter implements Human {
  private Baby baby;

    //構(gòu)造函數(shù)
    public BabySitter(Baby baby){
        this.baby=baby;
    }

    public void wipeShit(){
        System.out.println("幫助嬰兒擦屁屁。。。。");
    }

    @Override
    public void eat() {

    }
    @Override
    public void shit() {
      baby.shit();
      //幫助嬰兒擦屁屁
      wipeShit();
    }
}

將嬰兒和保姆關(guān)聯(lián)起來,并在保姆類中添加幫助擦屁屁的方法

public class BabySitter implements Human {
     private Baby baby;

    //構(gòu)造函數(shù)
    public BabySitter(Baby baby){
        this.baby=baby;
    }
    
    @Override
    public void shit() {
      //拉粑粑
      baby.shit();
     //擦屁屁
      wipeShit();
    }

    
    public void wipeShit(){
        System.out.println("幫助嬰兒擦屁屁。。。。");
    }

媽媽調(diào)用

public class Mom {

    public static  void main(String [] args){
        Human human = new BabySitter(new Baby());
        human.shit();
    }
}
image.png

裝飾模式主要是強(qiáng)調(diào)對類中代碼的拓展,而代理模式則偏向于委托類的訪問限制。兩者都一樣擁有抽象角色(接口)、真實(shí)角色(委托類)、代理類 。

\color{red}{如靜態(tài)代理的內(nèi)容所描述的,靜態(tài)代理受限于接口的實(shí)現(xiàn)。動態(tài)代理就是通過使用反射,動態(tài)地獲取抽象接口的類型,從而獲取相關(guān)特性進(jìn)行代理}

動態(tài)代理

實(shí)現(xiàn)InvocationHandler

public class HealthHandle implements InvocationHandler {

    private Object proxyTarget;
    public Object getProxyInstance(Object target){
        this.proxyTarget = target;
//Proxy.newProxyInstance(Clas loader, Class<?>[] interfaces, InvocationHandler h)
        return Proxy.newProxyInstance(proxyTarget.getClass().getClassLoader(), proxyTarget.getClass().getInterfaces(), this);
    }

   @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object methodObject = null;
        if(method.getName().equals("shit")){
            methodObject = method.invoke(proxyTarget, args);
            System.out.println("幫助嬰兒擦屁屁.......");
        }else if(method.getName().equals("eat")){
            System.out.println("幫助嬰兒飯前洗手.......");
            methodObject = method.invoke(proxyTarget, args);
        }
        return methodObject;
    }

媽媽類調(diào)用,動態(tài)代理了兩個動作,在嬰兒拉粑粑后,幫他洗屁屁,在他吃飯前,幫他洗手,不再用保姆類了

    public static  void main(String [] args){
        HealthHandle h = new HealthHandle();
        Human human = (Human) h.getProxyInstance(new Baby());
        human.shit();
        human.eat();
    }

image.png

使用動態(tài)代理:
1.必須實(shí)現(xiàn)InvocationHandler接口,訂立一個契約標(biāo)識該類為一個動態(tài)代理執(zhí)行類
2.InvocationHandler接口內(nèi)有一實(shí)現(xiàn)方法簽名如下: public Object invoke(Object proxy, Method method, Object[] args) 。使用時需要重寫這個方法
3.獲取代理類,需要使用 Proxy.newProxyInstance(Clas loader, Class<?>[] interfaces, InvocationHandler h) 這個方法去獲取Proxy對象(Proxy類類型的實(shí)例,非BABY類類型實(shí)例)。
就是不能寫成 :
Baby baby = (Baby) h.getProxyInstance(new Baby());
要寫他的抽象類

 //Clas loader : 類的加載器

//Class<?>[] interfaces : 委托類實(shí)現(xiàn)的接口,保證代理類返回的是同一個實(shí)現(xiàn)接口下的類型,保持代理類與抽象角色行為的一致
  //invocationHandler, 該類最重要的一環(huán)。一個設(shè)計模式:策略模式.即告訴代理類,代理類遇到某個委托類的方法時該調(diào)用哪個類下的invoke方法。
  Proxy.newProxyInstance(Class loader, Class<?>[] interfaces, InvocationHandler h) 
     //第一個參數(shù)為Proxy類類型實(shí)例,如匿名的$proxy實(shí)例
  //第二個參數(shù)為委托類的方法對象
    //第三個參數(shù)為委托類的方法參數(shù)
  //返回類型為委托類某個方法的執(zhí)行結(jié)果
   public Object invoke(Object proxy, Method method, Object[] args)
  
   總的來說這個方法就是動態(tài)獲取委托類里面的方法,在調(diào)用委托類的方法時在這個方法內(nèi)進(jìn)行拓展。 通過上面的Proxy.newProxyInstance方法,告訴底層代碼,該去哪個類里面執(zhí)行invoke方法。
``



最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容