iOS项目的目录结构-原创

前言

这段时间一直在做iOS的项目(青桔音乐App),随着代码量的上升,逐渐意识到项目的整体目录结构划分是多么重要,清晰的目录结构,能够更好的应对新的需求,更容易重构。虽然一直都是一个人在做=。=,但是还是深深地体会到目录结构的重要性。

例子

说再多都不如来个例子实在,如下:(VC指的是viewController)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|---General
|---AppDelegate
|---Application
|---Constant
|---UI
|---View
|---VC
...
|---Category
...
|---Entity
|---BaseEntity
|---UserEntity
|---CommentEntity
...
|---Http
|---Api
|---Manager
|---CodeHandler
|---ErrorHandler
|---HttpHandler
|---UserHttpHandler
|---CommentHttpHandler
...
|---DB
|---DBHelper
|---DBService
...
|---Util
|---StringUtil
|---NumberUtil
|---TimeUtil
...
|---Service
|---AccountService
|---ShareService
...
|---Lib
|---Umeng
|---QQSDK
|---SVProgressHUD
...
|---Module
|---Login
|---View
|---VC
|---XIB
|---Comment
|---View
|---VC
|---XIB
|---Business
|---Feeds
...

乍一看好多,别被吓到=。=,容我细细讲解。

详细讲解

General

General好理解,放的就是如AppDelegate之类的、项目中最普通的、最常用的组件。

AppDelegate:

App的Delegate类实现,这个必须有,就不用说了吧。

Application:

如果自定义实现了Application类,就放在这里。

Constant:

顾名思义,常量,项目用到的所有公共常量,如enum枚举类型的、Notification的Tag,常用的颜色、字符串等等等,都可以按照自己的需求划分不同的Group,放到Constant里面。

UI:

项目中自定义的UIView、UIViewController子类之类的代码,就对应放在UI下的View、VC中。

Category:

对系统类做的扩展,各种Category,如NSString+XXXExtension这种,就统一放在Category目录下。

如还有其他的通用组件,也不妨放到这里,做统一的管理。


Entity

Entity,也有人喜欢叫Model(关于Entity和Model的区别,推荐看看这篇文章,个人觉得研究研究Entity和Model概念的区别还是很有好处的),就是程序中的“实体”,如一个用户、一条评论、一首歌等等,简单来说就是一个独立“个体”的集合、打包,具体的自己查查吧,网上一大堆的,感觉跟JavaBean的概念比较像。

通常来说,每个Entity类都比较简单,只包含若干个属性。但是有时候可能要做统一的处理,如,在从服务器取回的JSON数据解包成具体的Entity类,并且执行一系列初始化操作等等,所以可能要对所有的Entity类做统一处理。所以说,可以定制相应的BaseEntity基类,利用模板方法等办法,定制统一的初始化流程(好像扯远了=。=,这个后面会详细写篇东西分享给大家),BaseEntity就是放这些基类的东西的。

有了BaseEntity后,对应的各个业务中的具体Entity,如UserEntity、CommentEntity,就可以分门别类的建立单独的Group存放。


Http

这个Group里面放跟网络请求相关的东西,详细如下:

Api:

互联网应用少不了跟服务器打交道的各种网络接口,所以我在项目中把所有的API对应的相对URL地址、参数注释要求等等都放在了这里,好统一管理。

Manager:

定义最基本的网络请求,如GET、POST、PUT等请求的基本封装,获取图片的基本封装。
一般来说就是定制统一的基本请求接口,对上层提供一致、稳定的服务,真正的网络请求,可以自己用iOS原生的Api写,也可以用AFNetworking等第三方库做封装,图片也可以灵活的用AFNetworking、SDWebImage这些优秀的库实现。还有就是,可以方便的统一对请求做处理,如错误处理、Http的Code、状态处理等等。还可以统一的增加请求参数,如统一为每个请求都增加用户的ID、token什么的。

CodeHandler

大部分的API设计都会有相应的状态码、Code,为了方便扩展,可以把这些处理Code的类单独放在这里。

ErrorHandler

这个就少不了了,对Http的错误进行单独处理,加Log什么的。

HttpHandler

这个Group里面放的是真正实现接口的类,如什么UserHttpHandler、CommentHttpHandler之类的,就是具体实现了接口调用、处理返回数据、回调的类。

Http里面的各个Group的类其实都是相互关联的,设计的时候可以定制统一的接口(Protocol),然后创建类实现(conform)这些接口,也就是面向接口的编程,以最大限度的减少接口层的各个职能之间的耦合,方便扩展。


DB

介于iOS的SQLite不是那么好用,所以非常有必要为操作数据库的类建立单独的地盘=。=

DBHelper:

放基础的操作数据库的类,如简单的查找、插入、更新、事务更新等等操作,为负载的数据库业务逻辑封装底层接口。比如对流行的FMDB进行封装等等。

DBService:

这里放具体的数据库业务实现类,至于为什么叫“Service”,因为我也想不出什么好的名字了=。= 按照自己的业务逻辑组织即可。


Util

放常用的工具类的地方。如字符串操作的类StringUtil、时间计算格式化类TimeUtil等,按具体需求而定,这个就不用多说了吧。


Service

项目的需求多了,业务逻辑的代码就会越来越多,总不能都放在view controller里面吧。一些多处用到的,或者非常独立的业务代码,完全可以抽离出来,实现为单独的、跟界面无关的业务类。因为做的事很杂,所以干脆就叫Service了。

AccountServiceShareService就是这种类。而且大部分的Service都应该是单例类,如AccountService类可能维护着程序运行期间的账户信息,ShareService对程序的分享功能做了统一处理等等,具体怎么用就随各位了。


Lib

Lib,放各种第三方库,因项目需要修改过的第三方组件等,像什么友盟、QQSDK之类的就可以放这。当然,一些不会做改动的库最好还是用CocoaoPod做统一管理。


Module

终于讲到了最重要的地方。

iOS工程中最多的文件往往就是各种View、ViewController类,以前总是看到有人只创建两个Group,一个叫Views,另一个叫ViewControllers,然后所有的Views、ViewController都往里面塞,然后随着需求的增加,这两个Group也臃肿不堪。。。

办法总是有的。就是为工程划分模块-Module

如何划分Module?我认为,可以按照以下两点建立:

  1. 以页面跳转分支划分。
  2. 以功能划分。

以页面跳转分支划分

就是按照应用的页面设计与业务逻辑,从最顶级开始,一级一级页面往下跳转,找出其中的独立分支,归为一个Module模块。
举例来说,应用主界面有4个Tab页,就先分出四个Module,然后一级一级往下跳转,遇到分支就建立新的Module,如此递归的建立,就能大致划分出各个Module。当然,这么做是最粗糙的,还要根据情况,将不同的分支Module合并成一个Module,简化代码的组成。我在这只是提供个划分Module的方法,具体怎么设计就看各位读者了=。=

以功能划分

这个好理解,无非就是根据前期项目的功能模块划分工程的代码Module组成。如什么用户设置Module、评论Module、登录Module等等。

总的来数,就是要用Module将工程的代码分类管理,每个Module具有大致相同的结构,如都可能有本Module用到的View、ViewController,自定义的类Class等等,就是说,按照职能对代码划分,避免将所有的类都堆在一起,也好应对新的需求。

总结

啰啰嗦嗦说了一大堆,想必各位都看烦了吧=。=刚开始写博客,写到一个地方,又会引出另一块,写着写着容易写偏了。

写之前我也大致搜了一下,发现网上相关的资料好少,但是实际的经验告诉我,项目工程的目录结构非常重要,无论是对开发还是对后期的维护,所以想着应该写篇东西,分享我自己的经验给大家,有啥问题,多提意见啊~~~


当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器