[iOS-Practice] 项目结构

总结时读到的一系列文章

iOS应用架构谈 开篇
我的iOS工程结构
iOS项目的目录结构-原创
iOS 项目的目录结构能看出你的开发经验
iOS项目的目录结构

分层

三层架构 / MVC模式

Cocoa Core Competencies > Model-View-Controller
Concepts in Objective-C Programming > Model-View-Controller
浅谈三层结构与MVC模式的区别

三层架构是一种软件抽象的层次结构,是对复杂软件的一种纵向切分,每一层次中完成同一类型的操作,以代码的功能作为依据来分割,以降低软件的复杂度,提高其可维护性。一般来说,层次之间是向下依赖的,下层代码未确定其接口前,上层代码是无法开发的,下层代码接口的变化将使上层的代码一起变化。

三层架构一般分别是数据访问层、逻辑业务层和展示层。数据访问层直接跟数据库交互,负责数据的管理,与上层业务逻辑层交流时,通过数据对应的实体模型(model 类)。逻辑业务层则根据业务需求再对数据实体进行加工处理。而展示层则是面对用户的,是加工过后的数据的外壳。展示层可能是 web 页面,也有可能是其他客户端,比如移动应用。服务端通过提供 API 接口,更多的承担的是数据访问层和逻辑业务层的角色。

而 MVC 则是针对展示层的一种复合设计模式。它通过数据在展示层的流动方向来将代码分离成各个层次模块。首先是 Model 层,它对接了获取数据的 API 接口,即服务器端的逻辑层,这里 Model 层区别于三层架构中数据载体的实体模型 model,Model 层通过网络请求或者从本地获取数据,之后再对数据进行相关业务逻辑和其他的公共处理(如转换为实体类),然后交给 Controller。其实如果是调用 API 网络请求获取数据时,主要的逻辑操作可能是在服务端完成的,本地
Model 层的作用有时候可能仅仅是转换数据类型。View 层的任务是单纯的渲染出界面展示数据,或提供界面改变展示方式(如动画)的接口供给 Controller 调用。所以 Controller 就成为了 Model 层和 View 层之间的桥梁,数据从 Model 层流向 Controller,Controller 层决定如何调用 Model 层来获取或修改数据,并最终让 View 层展示数据,即数据最终流向 View 层。用户通过界面和系统交互后的数据反馈给服务器或持久化存储在本地,则是上述流向的逆过程。所以,一般 Controller 应该是小巧,简单的,它主要的功能应该是负责数据与展示引擎之间的调度。MVC 模式中的三个层间其实并不存在明显的层次结构,没有明显的向下依赖关系,他们更像是横向的切分。

iOS 中的分层

作为客户端开发的 iOS 应用,苹果公司本身通过 SDK 就已经将 MVC 模式的思想植入其中。

Controller

通过 UIViewController 作为基类,实现了界面的控制器。

View

通过 .xib 或 .storyboard 文件和继承 UIView 基类的视图类来实现 View 层。

Model

一般应用对于数据的处理,主要分为两部分,网络请求和本地数据。网络请求就是把数据的逻辑处理放在了服务器端,然后通过提供 API 接口给客户端来进行数据交换。而本地数据的处理相当于是要在客户端本地做类似服务器端的数据维护的工作,当然客户端的复杂度级别要比服务端低很多。

所以在分模块时,我们首先应把代码职责分为网络请求模块和本地数据模块。网络请求模块内封装了请求 API 的代码。而本地数据模块可以考虑像服务器端一样采用三层架构思想,数据访问层 Dao 只负责数据的存取,向上层屏蔽掉具体的存储方式,对于 iOS 来说包括NSUserDefault、.plist 文件和数据库等,在逻辑业务层 Service 根据业务需求再对数据加工处理。

网络请求模块和本地数据模块相当于是 Model 层,它们负责了数据的逻辑处理。这两个模块返回的逻辑处理后的数据都应该是原始的类型,并不转换为实体类,这种把职责分离的设计使得 Controller 层的操作更灵活。可以根据需求实现不同的适配器,以用来转换数据,比如当不同的 Controller 从同一个 Model 拿到数据后,可以通过不同的适配器转换为最终需要提供给 View 层的数据格式,可能是实体类,也可能是其他数据结构。这种方式并没有使 Model 层的代码侵入到 Controller 层内,Controller 层仍只是负责调配,适配器其实也属于 Model 层的一部分,只是这样的实现提高了灵活性。Controller 层从 Model 层获取数据的方式就是,先拿到原始数据,再按照需要组装合适的适配器,最终输出提供给 View 层的数据。

目录结构划分

iOS 工程中没有严格的分包机制,一般通过 Group 的方式在工程中实现逻辑目录划分,方便代码的组织和管理,使工程结构清晰和易于理解。应该在项目目录中建立与 Group 对应的目录,使代码文件的划分更清晰。一种快捷的操作是,先在磁盘上创建对应的文件夹,再把文件夹拖进 Xcode 项目中对应的位置,并选择 Create groups for any added folders,这样就创建了对应目录的 Group。

根据上述对 MVC 模式的理解,以其为基础可细分为:

  • Application,与整个应用相关的文件,包括 AppDelegate 文件,main.m,项目配置文件(Info.plist),自定义的配置文件(.plist),老项目中的预编译文件。
  • Module,按功能模块划分,每一个模块内再根据 MVC 模式分出 Controller 和 View 目录。View目录中存放的就是自定义的 view 类和 .xib 或 .storyboard 文件。除了功能模块,还需要有一个 Base 模块,用来存放一些需要继承的 base 类以及一个 Common 模块,用来存放一些各模块共用的组件。实体类并不属于某一个界面,所以应该单独放在外层。如果是某一个 Controller 不使用实体类,而是需要定制的适配器,可以在模块内添加 Adaptor 目录,目录内实现 Controller 对应的适配器。
  • Network,主要是对使用 AFNetworking 进行 API 请求的封装。
  • Persistence,本地持久化数据的处理,如上所述分为 Dao 和 Service 两层
  • Model,数据的实体模型类,描述系统中的一些角色和业务,同时可作为适配器类,提供与网络请求层或数据持久化层提供的原始数据相互转换的方法。
  • Category,存储对现有系统类和自定义类的扩展。同一个类的扩展也尽量按处理的方向不同分为多个扩展来写,这样使模块粒度更小,使用更方便。
  • Utility,系统常用工具类。同样应该按处理的方向不同尽量拆分为更小的模块。
  • Constant,只有一对 Constant 文件,用来存放项目中一些公用的常量。使用某一个类时才会用到的常量不放在这个文件里,而是应放在对应类的文件中。
  • Localizable,存放所有的用于国际化的 .strings 文件,一般主要分为各功能模块,common,network提示信息等几部分。
  • Vendor,存放不支持 Cocoapods 的第三方类库。
  • Resource,存放多媒体资源,非 .png 格式的图片文件。图片资源用 Asset Catalog 管理(ios开发-图片资源管理)
功能模块与 MVC

在主体功能代码与 MVC 模式划分的层级关系上,除了上述使用的外层以功能模块分组,每一个功能分组内,再划分为 View 层和 Controller 层的方式外,还有另一种是外层以 Model、View、Controller 划分,在 View 层和 Controller 层内再以功能模块对代码分组。选择先按照功能模块分组的原因是,这样的划分粒度更细,更便于组织管理。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容