本文用于记录一些零碎的设计思路。不定时更新中......
1.库的传参
封装库即封装第三方,当需要让外界定制时(类似页面的跳转传参,只是项目中页面的跳转一般参数不多),主要有以下几种方式:
① 参数直接传入
参数直接传入适用于大部分场景,不过参数多了也显得繁琐,所以可能会通过分成多个Config模型类传入。参数传参的时机也是即时的。
参数可能通过属性,也可能通过函数参数,在Swift中,函数参数提供的扩展性很强,你可以通过枚举数组[options]
达到自定义的效果。
② 通过协议数据源传入
参数传入是即时的,通过数据源是在必要的时候从外界获取。这个的好处是可以再适当的时机去处理需要的数据传入。同时作为一个封装库,也是需要通过代理回调给外界,这边不赞同使用闭包(代码块)。
协议可以作为数据源和代理的桥梁,在适当时机获取需要的参数,在多个时机获取对应回调。
③ 通过模型类传入
模型类传入,有点参数传入的意思,这边的模型类不仅仅是我们常见的Model,也比如Moya中的Target、CTNetworking中的BaseManager,将特异性的参数封在内部。
2.协议的使用
在OC中,协议似乎和代理绑在一起,其实不然。无论在OC还是Swift中,协议的用处都是很大的:
① 代理回调和数据源
UITableView是最典型的例子,TableView在适当时机从ViewController获取需要的参数,在多个时机回调给ViewController,让它去做事情。
(比如在我们不想把数据带过去处理或者数据带来带去,就可以在原本界面处理给下一个界面。)
② 约束类
这边有两种场景:
- 一个是约束函数的参数,只能传入符合该协议的对象,比如在设置代理的时候。
- 一个是约束类的方法,在AFNetWorking中,
AFURLRequestSerialization
是一个协议,规范类的主要功能。无论是AFHTTPRequestSerializer还是它的子类AFJSONRequestSerializer,都会去实现这个功能。
@interface AFHTTPRequestSerializer : NSObject
@interface AFJSONRequestSerializer : AFHTTPRequestSerializer
在Swift中,这种规范就更加常见了,比如Moya的Target协议规范了作为一个Request模型类该实现的功能。
另外,多层回调传递(比如cell中的view代理要传递方法至cell所在的vc)可以通过两层Delegate(ViewDelegate,CellDelegate(继承于ViewDelegate))。
3.区分类的职责
封装一个库,除了考虑怎么传参和回调,更重要的是库的设计。库的设计简单说就是分成几个类?每个类担任什么职责?每个类的关系是怎么样?
在CTNetworking的设计中,简单的请求集合着不同的扮演者,有的负责提供数据(数据源),有的负责校验(检验者),有的负责回调(回调者),有的负责处理数据(适配器)。
4.ViewController继承的使用
ViewController的继承要分离好子类和父类各自的职责。
比如ImagePickerPreviewViewController(大图浏览界面)的父类用于封装ImagePreviewView的手势操作和动画。ImagePickerPreviewViewController自身用于添加外表的ToolBar,处理数据,处理代理方法。
当然使用继承有3大要点:
1.父类只是给子类提供服务,并不涉及子类的业务逻辑。
2.层级关系明显,功能划分清晰,父类和子类各做各的。
3.父类的所有变化,都需要在子类中体现,也就是说此时耦合已经成为需求。
其他情况下优先考虑组合。
5.配置类的设计
配置类(比如Config)大多数也是当作参数注入我们的项目模块,实现自定义设置的。
在UICollectionView中,Layout类本身也是类似配置类(通过协议限定我们实现的方法),负责提供布局所需要的信息。简单理解就是,我需要这些配置信息,你实现给我。
一个好的庞大的配置类,需要将配置做分割,将对应小模块的配置分配到各自的小配置中。比如网易云信的NIMKitConfig这个类就设计得不错,多而不杂。
6.相似界面的设计
相似界面的设计主要有两种思路,一种是继承,一种是配置。当然混合起来也是可以的。
继承主要应用于两个界面的控件有递进的关系。基类搭建基础控件,子类添加个性化的控件。
配置主要用于两个界面比较相似,界面控件、控件布局或界面参数通过配置类的方法来决定。
7.聊天界面的设计
聊天界面要想实现自定义,解耦,首先有UI层面和数据层面的区分。UI层面当然在ViewController去实现,自定义的内容可以通过配置类来提供,不同的配置类决定这个界面的一些不同之处。比如聊天界面的背景图,icon,或者聊天菜单选项,转发菜单选项,当然还有最重要的数据提供者(主要负责提供下拉请求聊天数据)。不同的数据提供者提供的数据也是不一样的,很明显的数据和UI做了解耦。