代理模式簡記

以NFC舉例,代碼不具備實操功能
接口:INFCService.java

    boolean isSupportNFC();
    boolean isOpen();

    void openNFC(Context context);

    void closeNFC(Context context);
    //通信交流
    void communication();

}

具體實現(xiàn)類:NfcDao.java

public class NfcDao implements INFCService {
    private static volatile NfcDao instance;
    private static NfcAdapter nfcAdapter;

    public NfcDao(Context context) {
        nfcAdapter = NfcAdapter.getDefaultAdapter(context);
    }

    public static NfcDao getInstance(Context context) {
        // 雙重檢查鎖定模式 Proxy.newProxyInstance()
        if (instance == null) {
            synchronized (NfcDao.class) {
                if (instance == null) {
                    instance = new NfcDao(context);
                }
            }
        }
        return instance;
    }

    @Override
    public boolean isSupportNFC() {
        if (nfcAdapter != null) {
            return true;
        }
        return false;
    }

    @Override
    public boolean isOpen() {
        if (nfcAdapter != null){
            return nfcAdapter.isEnabled();
        }
        return false;
    }

    @Override
    public void openNFC(Context context) {
        if (nfcAdapter != null && !nfcAdapter.isEnabled()) {
            // 創(chuàng)建一個意圖以打開 NFC 設置屏幕
            Intent intent = new Intent(Settings.ACTION_NFC_SETTINGS);
            // 啟動活動以打開 NFC 設置屏幕
            context.startActivity(intent);
        }
    }

    @Override
    public void closeNFC(Context context) {
        // 關閉 NFC
        try {
            Settings.Global.putInt(context.getContentResolver(), Settings.Global.RADIO_NFC, 0);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 請求關閉 NFC 的系統(tǒng)設置
        Intent intent = new Intent(Settings.ACTION_NFC_SETTINGS);
        context.startActivity(intent);
    }

    @Override
    public void communication() {

    }
}
  • 靜態(tài)代理
public class NFCProxy implements INFCService {
    private INFCService iNfcService;

    public NFCProxy(INFCService iNfcService) {
        this.iNfcService = iNfcService;
    }

    @Override
    public boolean isSupportNFC() {
        return iNfcService.isSupportNFC();
    }

    @Override
    public boolean isOpen() {
        return iNfcService.isOpen();
    }

    @Override
    public void openNFC(Context context) {
        iNfcService.openNFC(context);
    }

    @Override
    public void closeNFC(Context context) {
        iNfcService.closeNFC(context);
    }

    @Override
    public void communication() {
        iNfcService.communication();
    }
}
  • 動態(tài)代理
public class NFCDynamicProxy<T> {
    private T target;
    public NFCDynamicProxy(T target) {
        this.target = target;
    }
      //只能用于無參構造
    public NFCDynamicProxy(Class<T> target) {
        try {
            this.target = target.newInstance();
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        }
    }

    /*實驗性代碼,反射中的有參構造不要android中使用
    /,其參數(shù)類型無法精準獲取抽象類只能獲取其實現(xiàn)類類型
    ,在傳入Context后其類型可能是Application或Activity
結果:失敗,Type沒發(fā)強制轉(zhuǎn)換,構造參數(shù)類型沒發(fā)動態(tài)獲取,此處僅作保留*/
    public NFCDynamicProxy(Class<T> target, Object... params) {
        Constructor<?>[] constructors = target.getConstructors();
      //target.getConstructor(new Class[tClass])
        try {
            Class<?>[] clzTypeParams = new Class[params.length];
            for (int i = 0; i < params.length; i++) {
                clzTypeParams[i] = params[i].getClass();
                //實驗性代碼
                Type type = params[i].getClass().getGenericSuperclass();
                Class<T> tClass = (Class<T>) type;
                LogUtil.d("超類名:"+tClass.getName());
            }
            Constructor<T> constructor = target.getDeclaredConstructor(clzTypeParams);
            this.target = constructor.newInstance(params);
        }catch (Exception e){
            LogUtil.e(e.getMessage());
        }
    }

    public T getProxyInstance() {
        T iNfc = (T) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),   //ClassLoader 類加載器
                target.getClass().getInterfaces(),    //代理對象接口(必須是接口)
                new NfcClientInvocationHandler<T>(target));
        return iNfc;
    }
}

NfcClientInvocationHandler.java

public class NfcClientInvocationHandler<T> implements InvocationHandler {
    private T t;
    public NfcClientInvocationHandler(T t) {
        this.t = t;
    }

    //被代理的對象
    @Override
    public T invoke(Object proxy, Method method, Object[] args) throws Throwable {
        LogUtil.i("代理執(zhí)行方法:" + method.getName() + "=>");
        if (args != null && BuildConfig.DEBUG) {
            for (int i = 0; i < args.length; i++) {
                LogUtil.i("參數(shù)為:" + args.toString());
            }
        }

        if (method.getDeclaringClass() == t.getClass()) {
            return (T) method.invoke(this, args);
        }else {
            return (T) method.invoke(t, args);
        }
    }
}

代理模式好處:給對象套一層殼,便于AOP操作;將操作與調(diào)用分離,可以在執(zhí)行過程中靈活的切換操作對象而不需要改調(diào)用者

  • 優(yōu)點
    靈活性: 使用代理模式可以輕松地在運行時添加或修改目標對象的行為。
    解耦: 代理模式可以降低目標對象和客戶端之間的耦合度。
    代碼復用: 可以在不修改目標對象的情況下,為其添加額外的功能。
  • 缺點
    性能開銷: 由于所有的方法調(diào)用都需要通過代理對象進行,可能會導致一定的性能開銷。
    復雜性: 使用代理模式可能會增加代碼的復雜性,特別是當涉及到多個代理時
  • 場景,添加日志記錄、事務管理,給模塊之前的調(diào)用進行解耦
動態(tài)代理與靜態(tài)代理的優(yōu)劣:
  • 靜態(tài)代理:
    類的代碼在運行前就已經(jīng)存在,在動態(tài)代理中,代理對象是在運行時動態(tài)生成的。Java 的 java.lang.reflect.Proxy 類和 java.lang.reflect.InvocationHandler 接口提供了這種能力的基礎。
    優(yōu)點
    性能稍微好一些,因為沒有運行時的動態(tài)類加載和代理對象創(chuàng)建。
    代碼更簡單,易于理解和維護。
    缺點
    不夠靈活,如果需要為多個類添加相似的功能,會導致代碼重復。
    違反了開放/封閉原則,每次需要修改目標對象的行為時,都需要修改代理類的代碼。
  • 動態(tài)代理
    在動態(tài)代理中,代理對象是在運行時動態(tài)生成的。Java 的 java.lang.reflect.Proxy 類和 java.lang.reflect.InvocationHandler 接口提供了這種能力的基礎。
    優(yōu)點
    高度靈活,可以動態(tài)地為任何目標對象添加或修改功能。
    更符合開放/封閉原則,可以在不修改目標對象代碼的情況下,通過添加新的代理處理器來修改目標對象的行為。
    缺點
    性能可能稍差,因為所有的方法調(diào)用都需要通過代理對象進行,這增加了一層間接性。
    代碼可能更復雜,需要更多的理解和維護
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

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

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