iOS架构:Proxy实现局部模块化(附Demo)

博客更新记录:首先感谢 Casa Taloyum 前辈对该篇博客错误的指出(或者说打脸😭哈哈),笔者对 AOP 理解错误影响到各位读者的阅读体验,在此深表歉意。Casa Taloyum 前辈指出该玩儿法应该叫做 Proxy 模式,笔者对其了解了一番,深以为然。 ———— 2018-4-24

一、写在前面

Proxy 设计模式:为其他对象提供一种代理以控制对这个对象的访问。

在 iOS 开发中,Proxy 设计模式的体现更多的是以单个代理的方式,笔者为了优雅的达到更深层次的模块化,基于消息转发间接的实现多代理。

喜欢看代码的可直接看 DEMO

Proxy 局部模块化 DEMO

二、更深层次模块化

在 iOS App 中,MVC 和 MVVM 是比较流行的架构模式,而当某个界面业务量达到一个程度过后,MVVM 甚至是 VIPER 模式都显得有些力不从心。

为了达到更高层次的模块化,往往会做其他方面的工作,比如将UITableView等代理方法的实现独立出,然而代理方法里面的逻辑太多会导致独立出来的类仍然臃肿;更细化一点的法子是在代理方法里面将具体实现分离出去,由其他类完成。

不过,这些方式都不够优雅。

所以,这就是本文的目的,提供一种更深层次的模块化的方案。

三、实际应用

Proxy设计模式,在笔者之前的框架中已经有了应用,实现该框架难点就是:利用方法重定向实现多接收者的消息转发。

详情可看这篇文章,文章中间部分有对消息转发流程的简述:

iOS解决方案:文本输入控制(献上框架)

本文就不讲解消息发送机制了,在 Demo 中有封装 —— YBProxyManager,我们将利用它来做局部模块化。

在实际业务需求中,出场率很高的是UITalbeView和UICollecitonView等需要用大量代理方法配置的视图,当然这是苹果程序设计的惯例。当UI界面很复杂,业务逻辑相当多的时候,虽然把网络请求、数据处理、视图封装等都模块分离出去了,但是配置代理里面的逻辑太多,我们想要每一个类处理一部分代理方法。

Demo 以 UITableView 为例。

首先,创建实现 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) YBProxyManager *proxyManager;
@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];
        
        _proxyManager = [YBProxyManager new];
        [_proxyManager addTarget:_digitConfig];
        [_proxyManager addTarget:_clickConfig];
        [_proxyManager addTarget:_cellConfig];
        
        _tableView.delegate = _proxyManager;
        _tableView.dataSource = _proxyManager;
    }
    return _tableView;
}
@end

核心代码就是将 YBProxyManager 类的使用:

当你需要使用多个对象(target)来承接一些方法的实现,初始化 YBProxyManager 实例,将这些对象实例添加到 YBProxyManager 实例中(addTarget),最后将 YBProxyManager 实例作为这些方法的第一承接者。剩下的方法分发工作就交给该类了。

代码请看 DEMO,不复杂。

Proxy 局部模块化 DEMO

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏令仔很忙

新手学HighCharts(一)----基本使用

最近做的项目需要用到数据分析,图表显示,之前做项目的时候用到过highcharts,不过也只是简单的会用而已,然后再网上查了查highcharts的优点:

17610
来自专栏栗霖积跬步之旅

Springboot的默认定时任务——Scheduled注解

本博客参考博文地址。 1.pom依赖: 引入springboot starter包即可 <dependencies> <dependency> ...

38890
来自专栏转载gongluck的CSDN博客

波形音频(WAVE)底层接口的学习与使用

在WINDOWS下,音频函数有多种类型,如MCI、多媒体OLE控制、高级音频等,使用方法都比较简单。 但如果想编写一个功能较强大的音频处理程序,那...

1.3K50
来自专栏Albert陈凯

2018-06-18 自动化测试selenium在小公司的成功实践自动化测试selenium在小公司的成功实践前言背景相关知识正式实践github项目运行写在最后

43770
来自专栏小文博客

良心压缩软件Bandizip——无广告超精简

10.7K50
来自专栏Guangdong Qi

小Q-百度定位及递增递减的Label数字未完待续,持续更新中

21550
来自专栏Web 开发

又是一年PC操作系统三国鼎立的时刻~

Win8 在今早零时,发布开发者预览版,Lion已经发布多时,Ubuntu11.10的正式版也已经逼近

8800
来自专栏转载gongluck的CSDN博客

SAPI SDK的介绍

我们都使用过一些某某词霸的英语学习工具软件,它们大多都有朗读的功能,其实这就是利用的Windows的TTS(Text To Speech)语音引擎。它包含在Wi...

50570
来自专栏Android小菜鸡

Android Touch事件传递机制

  Touch事件的传递机制与生活贴近,从父布局开始一步一步的向下分发事件。分发事件时调用boolean dispatchTouchEvent(MotionEv...

28130
来自专栏Objective-C

iOS-MVVM 模式简单演练

30650

扫码关注云+社区

领取腾讯云代金券