利用 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 技术交流群: 691040931 群内提供数据结构与算法, 底层进阶, swift, 逆向, 底层面试题整合文档等免费资料!
喜欢晓雯就关注晓雯哟!! 晓雯微信: Pingwen20
来源: http://www.jianshu.com/p/8ebe8354374c