iOS 設(shè)計(jì)模式之十三(代理模式)

一绘证、概念

1、代理模式的動(dòng)機(jī)

? 隨著貿(mào)易的發(fā)展贿堰,網(wǎng)絡(luò)代購(gòu)成為一道亮麗的風(fēng)景線。顧客本地買不到需要的產(chǎn)品啡彬,便找代購(gòu)去外國(guó)把產(chǎn)品買回來(lái)羹与,也就是顧客只需要和代購(gòu)交流便可以買產(chǎn)品了。

? 在軟件開發(fā)中庶灿,也有一種設(shè)計(jì)模式可以提供與代購(gòu)類似的功能纵搁。由于某些原因,客戶端不想或不能直接訪問一個(gè)對(duì)象往踢,此時(shí)可以通過一個(gè)稱之為“代理”的第三者來(lái)實(shí)現(xiàn)間接訪問腾誉,該方案對(duì)應(yīng)的設(shè)計(jì)模式被稱為代理模式。

2峻呕、代理模式的定義

? 代理模式(Proxy Pattern):給某一個(gè)對(duì)象提供一個(gè)代理或占位符利职,并由代理對(duì)象來(lái)控制對(duì)原對(duì)象的訪問。

3瘦癌、代理模式的3個(gè)角色

1)Subject(抽象主題角色):它聲明了真實(shí)主題和代理主題的共同接口猪贪,這樣一來(lái)在任何使用真實(shí)主題的地方都可以使用代理主題,客戶端通常需要針對(duì)抽象主題角色進(jìn)行編程讯私。

2)Proxy(代理主題角色):它包含了對(duì)真實(shí)主題的引用哮伟,從而可以在任何時(shí)候操作真實(shí)主題對(duì)象;在代理主題角色中提供一個(gè)與真實(shí)主題角色相同的接口妄帘,以便在任何時(shí)候都可以替代真實(shí)主題。代理主題角色還可以控制對(duì)真實(shí)主題的使用池凄,負(fù)責(zé)在需要的時(shí)候創(chuàng)建和刪除真實(shí)主題對(duì)象抡驼,并對(duì)真實(shí)主題對(duì)象的使用加以約束。

3)RealSubject(真實(shí)主題角色):它定義了代理角色所代表的真實(shí)對(duì)象肿仑,在真實(shí)主題角色中實(shí)現(xiàn)了真實(shí)的業(yè)務(wù)操作致盟,客戶端可以通過代理主題角色間接調(diào)用真實(shí)主題角色中定義的操作碎税。

4、結(jié)構(gòu)圖
代理模式
5馏锡、常用的代理模式分類

1)遠(yuǎn)程代理(Remote Proxy):為一個(gè)位于不同的地址空間的對(duì)象提供一個(gè)本地的代理對(duì)象雷蹂,這個(gè)不同的地址空間可以是在同一臺(tái)主機(jī)中,也可是在另一臺(tái)主機(jī)中杯道,遠(yuǎn)程代理又稱為大使(Ambassador)匪煌。

2)虛擬代理(Virtual Proxy):如果需要?jiǎng)?chuàng)建一個(gè)資源消耗較大的對(duì)象,先創(chuàng)建一個(gè)消耗相對(duì)較小的對(duì)象來(lái)表示党巾,真實(shí)對(duì)象只在需要時(shí)才會(huì)被真正創(chuàng)建萎庭。

3)保護(hù)代理(Protect Proxy):控制對(duì)一個(gè)對(duì)象的訪問,可以給不同的用戶提供不同級(jí)別的使用權(quán)限齿拂。

4)緩沖代理(Cache Proxy):為某一個(gè)目標(biāo)操作的結(jié)果提供臨時(shí)的存儲(chǔ)空間驳规,以便多個(gè)客戶端可以共享這些結(jié)果。

5)智能引用代理(Smart Reference Proxy):當(dāng)一個(gè)對(duì)象被引用時(shí)署海,提供一些額外的操作吗购,例如將對(duì)象被調(diào)用的次數(shù)記錄下來(lái)等。

二砸狞、示例

1)先創(chuàng)建一個(gè)BuySomething協(xié)議捻勉,協(xié)議有兩個(gè)買東西的方法,表示抽象主題角色趾代;

2)然后創(chuàng)建一個(gè)Person類贯底,遵守BuySomething協(xié)議,表示真實(shí)主題角色撒强;

3)最后創(chuàng)建一個(gè)Proxy類禽捆,里面有一個(gè)Person對(duì)象,也遵守BuySomething協(xié)議飘哨,表示代理主題角色胚想;

BuySomething協(xié)議:

@protocol BuySomething <NSObject>
- (void)buyLV; //購(gòu)買LV
- (void)buyChanel; //購(gòu)買香奈兒
@end

Person類:

@interface Person : NSObject<BuySomething>
@property (nonatomic, copy) NSString *name;
- (instancetype)initWithName:(NSString *)name;
@end

@implementation Person
- (instancetype)initWithName:(NSString *)name {
    self = [super init];
    if (self) {
        _name = name;
    }
    return self;
}

- (void)buyLV {
    NSLog(@"%@購(gòu)買了LV包包", self.name);
}

- (void)buyChanel {
    NSLog(@"%@購(gòu)買了香奈兒香水", self.name);
}
@end

Proxy類:

// 代購(gòu)商
// .h文件
@interface Proxy : NSObject<BuySomething>
- (instancetype)initWithPerson:(Person *)person;
@end

// .m文件
@interface Proxy ()
@property (nonatomic, strong) Person *person;
@end

@implementation Proxy
- (instancetype)initWithPerson:(Person *)person {
    self = [super init];
    if (self) {
        _person = person;
    }
    return self;
}

- (void)buyLV {
    [self.person buyLV];
    NSLog(@"%@買包包送手環(huán)", self.person.name); //可以增加額外的操作
}

- (void)buyChanel {
    [self.person buyChanel];
}
@end

運(yùn)行代碼:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    Person *xiaoHong = [[Person alloc] initWithName:@"小紅"];
    Proxy *proxy1 = [[Proxy alloc] initWithPerson:xiaoHong];
    [proxy1 buyChanel];
    [proxy1 buyLV];
    NSLog(@"--------------");
    
    Person *xiaoFang = [[Person alloc] initWithName:@"小芳"];
    Proxy *proxy2 = [[Proxy alloc] initWithPerson:xiaoFang];
    [proxy2 buyChanel];
}

打印結(jié)果:

小紅購(gòu)買了香奈兒香水
小紅購(gòu)買了LV包包
小紅買包包送手環(huán)
--------------
小芳購(gòu)買了香奈兒香水

三、總結(jié)

? 代理模式為對(duì)象的間接訪問提供了一個(gè)解決方案芽隆,可以對(duì)對(duì)象的訪問進(jìn)行控制浊服。

1、優(yōu)點(diǎn)

共同優(yōu)點(diǎn)

1胚吁、能夠協(xié)調(diào)調(diào)用者和被調(diào)用者牙躺,在一定程度上降低了系統(tǒng)的耦合度。

2腕扶、客戶端可以針對(duì)抽象主題角色進(jìn)行編程孽拷,增加和更換代理類無(wú)須修改源代碼,符合開閉原則半抱,系統(tǒng)具有較好的靈活性和可擴(kuò)展性脓恕。

不同類型的代理模式的獨(dú)特優(yōu)點(diǎn)

1膜宋、遠(yuǎn)程代理為位于兩個(gè)不同地址空間對(duì)象的訪問提供了一種實(shí)現(xiàn)機(jī)制,可以將一些消耗資源較多的對(duì)象和操作移至性能更好的計(jì)算機(jī)上炼幔,提高系統(tǒng)的整體運(yùn)行效率秋茫。

2、虛擬代理通過一個(gè)消耗資源較少的對(duì)象來(lái)代表一個(gè)消耗資源較多的對(duì)象乃秀,可以在一定程度上節(jié)省系統(tǒng)的運(yùn)行開銷肛著。

3、緩沖代理為某一個(gè)操作的結(jié)果提供臨時(shí)的緩存存儲(chǔ)空間环形,以便在后續(xù)使用中能夠共享這些結(jié)果策泣,優(yōu)化系統(tǒng)性能,縮短執(zhí)行時(shí)間抬吟。

4萨咕、保護(hù)代理可以控制對(duì)一個(gè)對(duì)象的訪問權(quán)限,為不同用戶提供不同級(jí)別的使用權(quán)限火本。

2危队、缺點(diǎn)

1、由于在客戶端和真實(shí)主題之間增加了代理對(duì)象钙畔,因此有些類型的代理模式可能會(huì)造成請(qǐng)求的處理速度變慢茫陆,例如保護(hù)代理。

2擎析、實(shí)現(xiàn)代理模式需要額外的工作簿盅,而且有些代理模式的實(shí)現(xiàn)過程較為復(fù)雜,例如遠(yuǎn)程代理揍魂。

3午绳、適用場(chǎng)景

1栋豫、當(dāng)客戶端對(duì)象需要訪問遠(yuǎn)程主機(jī)中的對(duì)象時(shí)可以使用遠(yuǎn)程代理蝇棉。

2俐末、當(dāng)需要用一個(gè)消耗資源較少的對(duì)象來(lái)代表一個(gè)消耗資源較多的對(duì)象,從而降低系統(tǒng)開銷庄蹋、縮短運(yùn)行時(shí)間時(shí)可以使用虛擬代理瞬内,例如一個(gè)對(duì)象需要很長(zhǎng)時(shí)間才能完成加載時(shí)。

3限书、當(dāng)需要為某一個(gè)被頻繁訪問的操作結(jié)果提供一個(gè)臨時(shí)存儲(chǔ)空間虫蝶,以供多個(gè)客戶端共享訪問這些結(jié)果時(shí)可以使用緩沖代理。通過使用緩沖代理倦西,系統(tǒng)無(wú)須在客戶端每一次訪問時(shí)都重新執(zhí)行操作能真,只需直接從臨時(shí)緩沖區(qū)獲取操作結(jié)果即可。

4、當(dāng)需要控制對(duì)一個(gè)對(duì)象的訪問舟陆,為不同用戶提供不同級(jí)別的訪問權(quán)限時(shí)可以使用保護(hù)代理

5耻矮、當(dāng)需要為一個(gè)對(duì)象的訪問(引用)提供一些額外的操作時(shí)可以使用智能引用代理秦躯。

4、iOS應(yīng)用舉例

? 大家都很熟悉UITableView的delegate和dataSource裆装,都是通過代理對(duì)象來(lái)控制對(duì)UITableView的訪問踱承。

Demo地址:iOS-Design-Patterns

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市哨免,隨后出現(xiàn)的幾起案子茎活,更是在濱河造成了極大的恐慌,老刑警劉巖琢唾,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件载荔,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡采桃,警方通過查閱死者的電腦和手機(jī)懒熙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)普办,“玉大人工扎,你說我怎么就攤上這事∠味祝” “怎么了肢娘?”我有些...
    開封第一講書人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)舆驶。 經(jīng)常有香客問我橱健,道長(zhǎng),這世上最難降的妖魔是什么贞远? 我笑而不...
    開封第一講書人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任畴博,我火速辦了婚禮,結(jié)果婚禮上蓝仲,老公的妹妹穿的比我還像新娘俱病。我一直安慰自己,他們只是感情好袱结,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開白布亮隙。 她就那樣靜靜地躺著,像睡著了一般垢夹。 火紅的嫁衣襯著肌膚如雪溢吻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音促王,去河邊找鬼犀盟。 笑死,一個(gè)胖子當(dāng)著我的面吹牛蝇狼,可吹牛的內(nèi)容都是我干的阅畴。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼迅耘,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼贱枣!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起颤专,我...
    開封第一講書人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤纽哥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后栖秕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體春塌,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年累魔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了摔笤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡垦写,死狀恐怖吕世,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情梯投,我是刑警寧澤命辖,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站分蓖,受9級(jí)特大地震影響尔艇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜么鹤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一终娃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蒸甜,春花似錦棠耕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至恨憎,卻和暖如春蕊退,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工瓤荔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留净蚤,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓输硝,卻偏偏與公主長(zhǎng)得像塞栅,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子腔丧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容