編輯:關於android開發
代理模式也稱委托模式,是結構型設計模式之一。是應用廣泛的模式之一。
為其他對象提供一種代理以控制對這個對象的訪問。
當無法或不想直接訪問某個對象或訪問某個對象存在困難時可以通過一個代理對象來間接訪問,為了保證客戶端使用的透明性,委托對象與代理對象需要實現相同的接口。
(1)Subject:抽象主題類,聲明真實主題與共同接口方法,該類可以是抽象類或接口。
(2)RealSubject:真實主題類(被委托類),尤其執行具體的業務邏輯方法。
(3)Proxy:代理類(委托類),該類持有一個對真實主題類的引用,在其所實現的接口方法中調用真實主題類中相應的接口方法執行,以此起到代理作用。
書中例子:以小民訴訟的流程舉例。那麼需要代理律師代理,訴訟簡單流程:提交申請–>進行舉證–>開始辯護–>訴訟完成。
訴訟接口類:
public interface ILawsuit {
/**
* 提交申請
*/
void submit();
/**
* 進行舉證
*/
void burden();
/**
* 開始辯護
*/
void defend();
/**
* 訴訟完成
*/
void finish();
}
具體訴訟人小民:
public class XiaoMin implements ILawsuit{
@Override
public void submit() {
//小民申請仲裁
System.out.println("老板年底拖欠工資,特此申請仲裁!");
}
@Override
public void burden() {
//小民提交證據
System.out.println("這是合同書和過去一年的銀行工資流水!");
}
@Override
public void defend() {
//鐵證如山
System.out.println("證據確鑿,不需要再說什麼!");
}
@Override
public void finish() {
//結果
System.out.println("訴訟成功,判決老板即日起七天內結算工資!");
}
}
代理律師:
public class Lawyer implements ILawsuit{
private ILawsuit mLawsuit; //持有一個具體被代理者的引用
public Lawyer(ILawsuit lawsuit) {
this.mLawsuit = lawsuit;
}
@Override
public void submit() {
mLawsuit.submit();
}
@Override
public void burden() {
mLawsuit.burden();
}
@Override
public void defend() {
mLawsuit.defend();
}
@Override
public void finish() {
mLawsuit.finish();
}
}
開始仲裁:
public class Client {
public static void main(String[] args) {
//構造出訴訟人小民
ILawsuit xiaomin = new XiaoMin();
//構造一個代理律師,並將小民傳遞進去
ILawsuit lawyer = new Lawyer(xiaomin);
//律師提交申請
lawyer.submit();
//律師進行舉證
lawyer.burden();
//律師代小民辯護
lawyer.defend();
//完成訴訟
lawyer.finish();
}
}
結果:
老板年底拖欠工資,特此申請仲裁!
這是合同書和過去一年的銀行工資流水!
證據確鑿,不需要再說什麼!
訴訟成功,判決老板即日起七天內結算工資!
同樣我們也可以代理其他人,只需要實現ILawsuit即可。上面的代理模式也叫靜態代理,也就是在代碼運行前代理類的class文件就已經存在。那麼相反,當然也會有動態代理,下面用動態代理實現上述例子:
Java提供了一個便捷的動態代理接口InvocationHandler,我們來實現它:
public class DynamicPorxy implements InvocationHandler{
private Object obj; //被代理類的引用
public DynamicPorxy(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// 調用被代理類對象的方法
Object result = method.invoke(obj, args);
return result;
}
}
這裡我們通過invoke方法來調用具體的被代理方法。
修改後的Client類:
public class Client {
public static void main(String[] args) {
//構造出訴訟人小民
ILawsuit xiaomin = new XiaoMin();
//1.靜態代理
//構造一個代理律師,並將小民傳遞進去
//ILawsuit lawyer = new Lawyer(xiaomin);
//--------------------------------------
//2.動態代理
//構造一個動態代理
DynamicPorxy proxy = new DynamicPorxy(xiaomin);
//獲取被代理類小民的ClassLoader
ClassLoader loader = xiaomin.getClass().getClassLoader();
//動態構造一個代理者律師
ILawsuit lawyer = (ILawsuit) Proxy.newProxyInstance(loader, new Class[]{ ILawsuit.class }, proxy);
//律師提交申請
lawyer.submit();
//律師進行舉證
lawyer.burden();
//律師代小民辯護
lawyer.defend();
//完成訴訟
lawyer.finish();
}
}
結果不變,由此可以看出動態代理通過一個代理類來處理N多個被代理類,其實質是對代理者與被代理者解耦。相對而言靜態代理則只能為給定接口下的實現類做代理,如果接口不同那麼就需要重新定義不同的代理類,較為復雜,但是靜態代理更符合面向對象原則。具體使用哪種方式,根據個人喜好。
ActivityManager是Android中管理和維護Activity的相關信息的類,為了隔離它與ActivityManagerService,有效降低二者的耦合,在這中間使用了ActivityManagerProxy代理類,所有對ActivityManagerService的訪問都轉換成對代理類的訪問,這樣ActivityManager就與ActivityManagerService解耦了。
(1)對代理者與被代理者進行解耦。
(2)代理對象在客戶端和目標對象之間起到一個中介的作用,這樣可以起到對目標對象的保護。
基本沒有缺點,真要說缺點就是設計模式的通病:對類的增加。
《Android源碼設計模式解析與實戰》讀書筆記(二十二) 第二十二章、享元模式 享元模式是結構型設計模式之一,是對對象池的一種實現。就像它的名字一樣,共享對象,避免重
利用bintray-release插件上傳到Bintray- HTTP/1.1 404 Not Found [message:Repo 'maven' w
開源圖表庫MPAndroidChart使用介紹之餅狀圖&折線圖&柱狀圖,圖表mpandroidchart MPAndroidChart開源圖表庫之餅狀
自定義可點擊的ImageSpan並在TextView中內置“View“,imagespantextview有的時候可能想在TextView中添加一些圖片,比如下圖,發短信