玩轉iOS開發:《iOS設計模式 — 代理模式》
目錄
作者感言
上次我們知道了單例模式是怎麼回事, 現在我們來探討一下什麼叫做
單例模式
.其實所謂的代理模式在我們日常生活中非常的常見, 比如買車, 各式各樣的牌子都有, 但這些汽車生產商又不可能自己掏錢在每個城市的每個角落都開一家自己的直營店, 所以他們會去招一些第三方的代理商進行分銷, 而這個就是我們今天所要說的
代理模式
.最後:
如果你有更好的建議或者對這篇文章有不滿的地方, 請聯絡我, 我會參考你們的意見再進行修改, 聯絡我時, 請備註代理模式
, 如果覺得好的話, 希望大家也可以打賞一下~嘻嘻~祝大家學習愉快~謝謝~
Cain(羅家輝)
聯絡方式: [email protected]
騰訊QQ: 350116542
簡介
這是一張
代理模式
的UML圖, 同樣也很簡單的講解了代理模式
到底是怎麼回事順序如下:
- 1.
Client(客戶)
向Subject(代理店)
發起購買汽車的請求- 2.
Subject(代理店)
會向Proxy(生產商)
進行提單- 3.
Proxy(生產商)
按照提單進行交貨給Subject(代理店)
- 4.
Subject(代理點)
再交付給Client(客戶)
,
建立工程
開啟我們自己建立的
DesignPatternWork
資料夾, 裡面有我們之前所建立的DesignPatternWorkSpace
新增我們所要建立的新工程, 命名為
ProxyPattern
建立代理類
宣告代理類
這裡我們就拿奧迪這個汽車生產商來進行演示, 原諒我是個奧迪控~~
宣告代理方法
在這裡宣告兩個代理方法, 但他們有所區別, 一個是必須實現, 一個是可選型別的, 由於方法名自注釋, 我這裡就不添加註釋了.
@required
- (void)audiManufacturer:(AudiManufacturer *)audiManufacturer
orderQuantity:(NSInteger)orderQuantity;
@optional - (void)audiManufacturer:(AudiManufacturer *)audiManufacturer audiDelegateInfo:(NSString *)audiDelegateInfo;
解釋一下, 為什麼我們需要在代理方法中提供代理類, 其實這個很好理解, 打個比方, 就拿奧迪來說吧, 一個品牌的車子, 肯定有不同的型號, 而每個型號不一定都是在同一家工廠裡生產的, 這個時候我們就需要區分生產地, 所以我們為了提供外部去區分, 就需要在代理方法中提供代理類
(個人理解, 不是官方語言哈)
.
#import <Foundation/Foundation.h>
@class AudiManufacturer;
@protocol AudiManufacturerDelegate <NSObject>
@required
- (void)audiManufacturer:(AudiManufacturer *)audiManufacturer
orderQuantity:(NSInteger)orderQuantity;
@optional
- (void)audiManufacturer:(AudiManufacturer *)audiManufacturer
audiDelegateInfo:(NSString *)audiDelegateInfo;
@end
@interface AudiManufacturer : NSObject
@property (nonatomic, weak) id<AudiManufacturerDelegate> delegate;
- (void)buyCarCount:(NSInteger)count;
- (void)buyCarModel:(NSString *)model;
@end
內部實現代理方法
在內部實現兩個對方開放的方法
#import "AudiManufacturer.h"
@implementation AudiManufacturer
- (void)buyCarCount:(NSInteger)count {
if (self.delegate && [self.delegate respondsToSelector:@selector(audiManufacturer:orderQuantity:)]) {
[self.delegate audiManufacturer:self orderQuantity:count];
}
}
- (void)buyCarModel:(NSString *)model {
if (self.delegate && [self.delegate respondsToSelector:@selector(audiManufacturer:audiDelegateInfo:)]) {
[self.delegate audiManufacturer:self audiDelegateInfo:model];
}
}
@end
外部呼叫代理
代理類以及代理方法我們已經完成了, 接下來我們就要在外部去實現了
#import "ViewController.h"
#import "AudiManufacturer.h"
@interface ViewController () <AudiManufacturerDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
AudiManufacturer *audiManufacturer = [[AudiManufacturer alloc] init];
audiManufacturer.delegate = self;
[audiManufacturer buyCarCount:2];
[audiManufacturer buyCarModel:@"Q7"];
}
#pragma mark - 必須實現的方法
- (void)audiManufacturer:(AudiManufacturer *)audiManufacturer
orderQuantity:(NSInteger)orderQuantity {
NSLog(@"奧迪生產商為: %@", audiManufacturer);
NSLog(@"購買的數量為: %zd", orderQuantity);
}
#pragma mark - 可選實現的方法
- (void)audiManufacturer:(AudiManufacturer *)audiManufacturer
audiDelegateInfo:(NSString *)audiDelegateInfo {
NSLog(@"奧迪生產商為: %@", audiManufacturer);
NSLog(@"購買的型號為: %@", audiDelegateInfo);
}
@end
代理與協議的區別
代理與協議
到這裡, 我們已經完成了整個代理模式的所有要求了, 但還有一些小細節需要提提.
代理職能:
降低物件與物件之間的耦合度
協議職能:
主要是用來約束物件或篩選物件
代理與協議的相似:
代理與協議都是使用@protocol
來進行宣告, 並且提供方法的一種模式, 看起來沒啥不一樣.
代理與協議的不同:
其實就如同它們的職能所說,代理
是為了降低物件與物件之間的耦合度,協議
是用來約束物件或篩選物件
建立協議
這裡我們用程式碼演示一下吧, 這樣子更加的簡單明瞭, 不過這裡要注意一下,
Protocol
是沒有.m
檔案的
#import <Foundation/Foundation.h>
@protocol AudiCustomerProtocol <NSObject>
@required
- (NSString *)isEnoughBuyCar:(NSInteger)money;
@end
建立顧客類
建立完協議就要建立顧客了, 並且這個顧客類是必須遵守我們建立的
Protocol
, 然後在這個Protocol
里加個判斷.
#import <Foundation/Foundation.h>
#import "AudiCustomerProtocol.h"
@interface Customer : NSObject <AudiCustomerProtocol>
@end
#import "Customer.h"
@implementation Customer
- (NSString *)isEnoughBuyCar:(NSInteger)money {
if (money >= 1000000) {
return @"您的錢足夠購買Q7";
}
return @"您的錢不足以購買Q7";
}
@end
現在我們來初始化一下這個顧客類, 並且校驗一下我們所寫的
Protocol
是否生效.
#import "ViewController.h"
#import "AudiManufacturer.h"
#import "Customer.h"
@interface ViewController () <AudiManufacturerDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
AudiManufacturer *audiManufacturer = [[AudiManufacturer alloc] init];
audiManufacturer.delegate = self;
[audiManufacturer buyCarCount:2];
[audiManufacturer buyCarModel:@"Q7"];
Customer *customer = [[Customer alloc] init];
NSString *string = [customer isEnoughBuyCar:輸入你想要的數值];
NSLog(@"%@", string);
}
#pragma mark - 必須實現的方法
- (void)audiManufacturer:(AudiManufacturer *)audiManufacturer
orderQuantity:(NSInteger)orderQuantity {
NSLog(@"奧迪生產商為: %@", audiManufacturer);
NSLog(@"購買的數量為: %zd", orderQuantity);
}
#pragma mark - 可選實現的方法
- (void)audiManufacturer:(AudiManufacturer *)audiManufacturer
audiDelegateInfo:(NSString *)audiDelegateInfo {
NSLog(@"奧迪生產商為: %@", audiManufacturer);
NSLog(@"購買的型號為: %@", audiDelegateInfo);
}
@end
先輸入
10000
再輸入
1000000
補充一點
其實在iOS中, 就有一個類叫做
NSProxy
, 它也可以用來實現代理模式
, 但在這裡先不做介紹, 後面有時間再另外寫一篇文章去講解怎麼用NSProxy
去實現代理模式, 如果有好奇心特別重的朋友, 也可以自行去翻查一下資料~
最後總結
經過上面的演示, 就知道
代理模式
並沒有想象中那麼複雜, 說白了, 所謂的代理模式
就是為了降低物件與物件之間的耦合度, 為了方便維護罷了, 同時我們也知道了代理
與協議
之間的區別, 這篇文章就到了, 謝謝大家的觀看~
GitHub工程地址: https://github.com/CainRun/DesignPattern