学习笔记 - iOS 应用架构谈_view层的组织和调用方案

2016-02-05  本文已影响115人  钱嘘嘘

非常感谢 Casa 老师的文章,让我长久以来的很多疑惑,很多看了又忘的知识得到了系统的整理和总结。文章很容易让我建立起自己的记忆模型。就我的感觉,作为iOS程序员,把这样的文章读上几十遍都不为过,有种醍醐灌顶的痛彻。其中还有一个很重要的点,作为架构师是为工程师服务的,这种想法尤其的纯粹,放到工程师身上,如果也想着自己的代码是给别人读的,自己的产品是给用户用的,相信世界将变得更美好,我们离梦想也会更近。

View代码结构的规定  --  life cycle --> delegate --> event response --> getter & setter  ❤❤❤

关于view的布局  --  masonry  ❤❤❤

何时使用storyboard,nib,coding

统一派生ViewController?  --  AOP ❤❤❤

方便View布局的小工具

MVC、MVVM、MVCS、VIPER  ❤❤❤

跨业务时View的处理  --  Mediator  ❤❤❤


1. Coding Guidelines

2. VC结构  

(1) 图

(2) ViewDidLoad --> addSubView

(2.5) viewWillLayoutSubview or didLayoutSubview --> 布局

(3) ViewDidAppear --> Notification,通知一类

(4) 属性初始化 --> getter & setter(or [self ~~])

life cycle --> delegate --> event response --> getter & setter

3. View布局

Masonry (UIView + LayoutMethod + AEBHandyAutoLayout)

4. Storyboard + nib + coding

(1) 改动

(2) link现 的 + -

5. 统一派生VC

(1) 使用成本

          <1> 集成成本

         <2> 上手成本

         <3> 架构维护

(2) 不使用派生也可以          

          AOP --> Method Swizzling(Aspects)   <1> VC拦截  <2> NSObject的+load

Method Swizzling只支持针对现有方法的操作

拓展方法 --> Category(化继承为组合)不推荐过度使用

6. MVC 

<1> MVC(Model - View - Controller):

其中Model是数据管理者,View是数据展示者,Controller是数据加工者。Model和View又都是由Controller来根据业务需求调配,所以Controller还负担了一个数据流调配的功能。

在 Cocoa 的模型-视图-控制器 (Model-view-controller)架构里,控制器负责让视图和模型同步。这一共有两步:当 model 对象改变的时候,视图应该随之改变以反映模型的变化;当用户和控制器交互的时候,模型也应该做出相应的改变。

<2> 服务器端 & Native(图)

UIViewController --> UIView(容器)(再看objccn的VC教程豁然开朗)

<3> 在iOS开发领域中,MVC划分

M:

给 VC 提供数据

给 VC 存储数据提供接口

提供经过抽象的业务基础组件,供 C 调度

C:

管理 VC 的生命周期

负责生成所有的 View 实例,并放入 VC

监听来自 View 与业务有关的事件,通过与 Model 的合作,来完成对应事件的业务

V:

响应与业务无关的事件,并因此引发动画效果,点击反馈(如果合适的话,尽量还是放在View去做)

界面元素表达

<4> MVCS

拆分的部分是 Model,拆出来一个 Store,专门负责数据存取。实际是拆分C。

7. 胖 Model && 瘦 Model

(1)胖 M包含了部分弱业务逻辑。目的:C从胖M这里拿到数据之后,不用额外做操作或者只要做非常少的操作,就能够将数据直接应用在View上。

强业务变动的可能性要比弱业务大得多,弱业务相对稳定。弱业务重复出现的频率要大于强业务。

缺点:相对比较难移植,拔出萝卜带出泥。违背MVC思想,Model是一个Layer,不应该做Object做的事情。软件成长,越来越胖,难维护。

(2)瘦 M只负责业务数据的表达,所有业务无论强弱一律给C。目的:尽一切可能去编写细粒度Model,然后配置各种helper类或方法来对弱业务做抽象,强业务 --> C。

缺点:一定程度违背了DRY的思路。C会膨胀。

MVCS是基于瘦Model的一种架构思路,把原本Model要做的很多事情中的其中一部分关于数据存储的代码抽象成了 Store,在一定程度上降低了 C 的压力。

8. MVVM

数据加工的任务从 C 中解放了出来,使得 C 只需要专注于数据调配的工作,ViewModel则去负责数据加工并通过通知机制让 View 响应 ViewModel的改变。ViewModel就是把RawData变成直接能被View使用的对象的一种Model。

MVVM是基于胖Model的架构思路建立的,然后在胖Model中拆分两部分:Model && ViewModel。

reformer == ViewModel  --  API -> View方向

ReactiveCocoaRACSignal  --  View -> API & Con方向

8.5 ReactiveCocoa

不用RAC也能MVVM,用RAC能更好地体现MVVM的精髓。前面的例子是 数据从API到View的方向,View的操作也会产生数据,数据更多体现在表达用户的操作上,比如输入内容,就是text,选择cell,就是indexPath。那么数据从View走向API 或者 C。就是RAC发挥的地方。

View <--> ViewModel <--> Model

View <--> C <--> ViewModel <--> Model  =  MVCVM

C夹在V 和 VM之间,是将V 和 VM进行绑定。逻辑上,C 知道要展示哪个View,也知道应该使用哪个VM,但是V和VM互相不知道对方。所以要绑定。

在MVC的基础上,把C拆出一个ViewModel专门负责数据处理的事情,就是MVVM。还有一种说法是本身有胖Model,用于处理弱业务逻辑的事情,是对胖Model中数据加工的功能进行了分离。

在iOS领域里KVO,Notification,block,delegate 和 target-action 都可以用来做数据通信,实现绑定。但都不如RAC提供的RACSignal来的优雅,不用RAC,绑定关系可能做不到那么松散。

9. VIPER (View - Interactor - Presenter - Entity - Routing)


10. 拆分:

第一心法:保留最重要的任务,拆分其他不重要的任务。

第二心法:拆分后的模块要尽可能提高可复用性,尽量做到DRY  --  IOP

第三心法:要尽可能提高拆分模块后的抽象度

发送文本和图片逻辑  --  对枚举的应用

即使拆分粒度因为客观原因无法细化,那也能把复杂的判断逻辑和调度逻辑从 C 中抽出来,真正的为 C 做到了减负。总之能够做到大粒度就尽量大粒度,实在做不到那也行,用Strategy把它hold住。

Strategy模式  --  拆分粒度无法细化,用于处理复杂的判断逻辑和调度逻辑。

10.5 设计:

一:尽可能减少继承层级,涉及苹果原生对象的尽量不要继承

二:做好代码规范,规定好代码在文件中的布局,尤其是VC中

三:能不放在C做的事情就尽量不要放在C里面去做

跨业务页面调用方案的设计

依赖关系下沉 -- Mediator模式

11. objc并没有像java那么严格的私有概念。但在实际工作中,我们并不太会去操作头文件里面没有的变量,这是在规范上就被禁止的。

高度的封装性。getter事实上是工厂方法,有了getter之后,业务逻辑可以更加专注于调用,而不必担心当前变量是否可用。

12. View层架构:

(1)制定良好的规范

(2)选择好合适的模式(MVC、MVCS、MVVM、VIPSER)

(3)根据业务情况针对 VC 做好拆分,提供一些小工具方便开发


13. AOP:

面向切面(切片)的编程,任务一般分为1 2 3 4步,针对每个步骤间隙的编程。

AOP一般都是需要有一个拦截器,然后在每一个切片运行之前和之后(任何你希望的地方),通过调用拦截器的方法来把这个 jointpoint 扔到外面,在外面获得这个 jointpoint 的时候,执行相应的代码。

iOS中,用 Method Swizzling。第二种是使用 protocol。对比MS额外好处是,可以通过拦截器来给实现者提供更多的信息,便于外部实现更加了解当前切片的情况。另外,可以更精细地对切片进行划分。MS的切片粒度是函数粒度的,自己实现的拦截器的切片粒度可以比函数更小,更加精细。

缺点就是,你得自己在每个插入点把调用拦截器方法的代码写上。通过Aspects(MS)来实现的AOP,就轻松一些。

上一篇下一篇

猜你喜欢

热点阅读