利用 AOP 模組化細節業務,確實有趣。因為我們通常情況下說起 AOP,都會想起比如“埋點”、“method swizzing”等字眼,角度比較巨集觀,起到了解耦的作用;本文從另一個角度出發,使用 AOP 思想對細節業務做模組分離的工作。
AOP簡介 面向切面程式設計(也叫面向方面):Aspect Oriented Programming(AOP),是目前軟體開發中的一個熱點。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程式的可重用性,同時提高了開發的效率。
主要的功能是:日誌記錄,效能統計,安全控制,事務處理,異常處理等等。
主要的意圖是:將日誌記錄,效能統計,安全控制,事務處理,異常處理等程式碼從業務邏輯程式碼中劃分出來,通過對這些行為的分離,我們希望可以將它們獨立到非指導業務邏輯的方法中,進而改 變這些行為的時候不影響業務邏輯的程式碼。
AOP實際是GoF設計模式的延續,設計模式孜孜不倦追求的是呼叫者和被呼叫者之間的解耦,AOP可以說也是這種目標的一種實現。在實際業務需求中,出場率很高的是UITalbeView和UICollecitonView等需要用大量代理方法配置的檢視,當然這是蘋果程式設計的慣例。當UI介面很複雜,業務邏輯相當多的時候,雖然把網路請求、資料處理、檢視封裝等都模組分離出去了,但是配置代理裡面的邏輯太多,我們想要每一個類處理一部分代理方法。
首先,建立實現 UITableView 代理的三個類:
@implementation TestTableViewDigitConfig
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 20;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 80;
}
@end
複製程式碼
@implementation TestTableViewClickConfig
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"click -- section:%ld, row:%ld", indexPath.section, indexPath.row);
}
@end
複製程式碼
@implementation TestTableViewCellConfig
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass(UITableViewCell.class)];
if (!cell) {
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:NSStringFromClass(UITableViewCell.class)];
}
cell.textLabel.text = [NSString stringWithFormat:@"第%ld行", indexPath.row];
return cell;
}
@end
複製程式碼
如程式碼所見,這裡將 tableView 的代理用三個類來分別實現,然後在 UIViewController 裡面只需要寫這些程式碼:
@interface TestVC ()
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) YBAOPManager *aopManager;
@property (nonatomic, strong) TestTableViewDigitConfig *digitConfig;
@property (nonatomic, strong) TestTableViewClickConfig *clickConfig;
@property (nonatomic, strong) TestTableViewCellConfig *cellConfig;
@end
@implementation TestVC
#pragma mark life cycle
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.tableView];
}
#pragma mark getter
- (UITableView *)tableView {
if (!_tableView) {
_tableView = [[UITableView alloc] initWithFrame:[UIScreen mainScreen].bounds style:UITableViewStylePlain];
_tableView.tableFooterView = [UIView new];
_digitConfig = [TestTableViewDigitConfig new];
_clickConfig = [TestTableViewClickConfig new];
_cellConfig = [TestTableViewCellConfig new];
_aopManager = [YBAOPManager new];
[_aopManager addTarget:_digitConfig];
[_aopManager addTarget:_clickConfig];
[_aopManager addTarget:_cellConfig];
_tableView.delegate = _aopManager;
_tableView.dataSource = _aopManager;
}
return _tableView;
}
@end
複製程式碼
核心程式碼就是將 YBAOPManager 類的使用:
當你需要使用多個物件(target)來承接一些方法的實現,初始化 YBAOPManager 例項,將這些物件例項新增到 YBAOPManager 例項中(addTarget),最後將 YBAOPManager 例項作為這些方法的第一承接者。剩下的方法分發工作就交給該類了。
給大家推薦一個iOS技術交流群!763164022群內提供資料結構與演算法、底層進階、swift、逆向、底層面試題整合文件等免費資料!