iOS:怎样创建一个好的App目录结构

一、引言

        经过前段时间的一番疯狂面试,终于算是安定下来了,刚入职一家感觉不错的公司。公司想要在原来产品的基础之上再做一个新的项目,之前在上一家公司做项目的时候总觉得app的一个层次不如意,但是在原有的项目上去改又比较费时费力,再加上公司项目不断的加需求,改需求,根本有多少时间去细化分析目录结构。这次正好借做新项目的机会,我就根据自己的经验从零开始搭建整个App的目录结构,当然这离项目架构来说还差很远,不过一个好的App目录结构不仅能使app有一个好的层次分级,使逻辑清晰,还便于维护,提高开发效率。

      当然,我在此只是说一下我个人的一些观点,毕竟每个人可能一些习惯或者思维方式是不一样的,加上我个人还算不上大神,所以只是把自己的经验与大家分享,以供我们相互借鉴,也希望大家提供宝贵意见。

二、开始前的思考

        既然从零开始,那么在创建项目目录结构的时候我考虑到的问题有:

1、项目中有哪些功能?

2、各功能如何实现?

3、怎么样能快速定位到要找功能?

万事开头难,在创建项目之前,我对比看了之前的项目目录结构,也从网上看了一些关于app目录结构的经验分享,想了很多方面,下面我们来看上面所列的问题:

1、项目中有哪些功能?

        这个问题其实就是看自己对要做的项目的一个整体了解,要知道所做App重点在什么地方,用到最多的是哪方面的知识,一个整体的交互是什么样的,因为不同功能的app无论是在功能还是交互上都是差别很大的,所以一定要清楚项目整体功能,知道项目中有哪些模块,你可以把不同模块作为不同层次的分类依据,这样App就可以按照不同模块分成若干层级,然后再具体实现。当然我们也可以找到不同模块中相同的地方,再来按照他们的业务层次来划分层级,不管我App中有多少功能,那都离不开我们三层架构,那好,我就按照不同业务层次给你划分模块,这样也可以。

2、各模块如何实现?

      说完了第一个问题,接着上一个问题我们再来说各模块如何实现?有些人可能会说,这怎么说,项目开发过程中一步步实现就行了啊。其实我想说的并不是每个模块如何具体实现,更准确地是想说如何实现各个模块之间高效的交流,如何避免冗余代码,如何让程序更健壮,更轻量级。模块之间高效交流指的就是跨层、跨模块访问,避免冗余代码就提现了封装等思想,所以要实现这些模块的功能,我们就一定会用到一些额外的功能来解决这些问题。无论是在问题1中提到的是以模块来作为划分依据还是以业务层次来作为划分依据,都少不了这些额外的功能,比如我们会用到很多第三方,那么我们可以吧这些第三方统一放到一个地方,这样可以更好地管理。此外,在不同模块实现的时候我们很可能会用到同样的方法,那我们就可以进行封装作为工具类,还有想自定义的控件等等。。。

3、如何快速定位到要找的功能(类)?

        当项目出现问题或者需求改变的时候,我们如何能快速定位到目标类,个人感觉也算是一个要考虑的地方,问题1和2中所考虑的会直接影响这一步,我的想法是先找到目标所对应的模块或者所对应的业务层次,再找具体实现点。对于频繁接触的地方如我们项目中的网络请求和接口这样的单独分层。

三、具体实现

考虑了以上问题,对于项目结构我们可以从以下方面着手:

1、主项目目录先按照MVC层次划分,内层目录再按照项目功能模块划分;

2、主项目目录先按照功能划分,内层目录再按照MVC层次划分。

3、辅助功能单独划分层级。

4、内容较多时,采用1和2结合的方式。

方式一:主项目目录先按照MVC层次划分,内层目录再按照项目功能模块划分


图片发自笔记App

采用这种分类方式我们可以直接将项目分Model Controller View三层,然后Model里面存放各个模块的model,所有控制器全放在Controller里面,视图放在View里面,然后在相应的业务层次里面再根据MVC方式进行划分业务层次。

优点:业务层次之间结构清晰明了

缺点:当项目较大时不容易找到相应的模块,每个模块之间太过于分散,开发起来不是很方便。

方式二: 主项目目录按照模块功能划分,内层目录再按照MVC层次划分


图片发自笔记App

这一种方式再实际开发过程中应该用的比较多,我个人也是比较习惯用这一种方式,这样的分类方式需要我们对项目的一个结构有一个整体的了解,项目一共有几个主要模块,每个模块都有什么功能,每个模块之间会有哪些交互,清楚了这些,我们在做项目目录的时候就容易多了,比如我现在要做一个微信的项目,那我可以首先将其分为“消息”、“通讯录”、“发现”、和“我的”四大模块,然后在这四大模块中再次进行小模块的划分,如“我的”模块中有“钱包”、“收藏”、“相册”等,再次作为一个小模块,在小模块中再进行业务层次划分。当然这种方式也有其优缺点,。

优点:从目录结构就能清晰看出整个项目的层次,能快速找到对应的功能

缺点:模块比较分散,不同模块用到相通类时不好归类。

三、总结

      以上两种方式是比较常见的两种思路,当然也绝不只有这两种方式,在以上两种方式中没有绝对的熟好熟劣,只是各有优点,在开发中我们可以将二者优点结合起来,比如我可以先将项目主目录结构按照模块功能划分,这一分级是针对项目主要功能,还是拿微信举例,对于微信来说,下面TabBar上这4大功能显然是最主要的分级,那么我们可以按照此分级现将项目分为这四个模块。然后对于消息这样的模块,子模块较少,我们可以直接在这个模块下将其按照业务层次划分,将所有的Controllers、Models、Views归类,对于像“我的”这个模块,里面还会有很多模块,比如“钱包”、”收藏“、“设置”等,可以再将其按照模块分类,然后第三级再按业务层次分类。个人觉得这样的方式结合更方便一些,当然这样看每个人的开发习惯。不过不论按照哪种方式分类,分类的层级建议不要超过三级,除非一些特别复杂,内容特别多的模块,否则会让项目感觉比较杂,物极必反,太细分一个结构,反而会降低开发的效率。


图片发自笔记App

        以上说的目录形式,指的都是针对项目中的主要功能,一些具体的模块,一个项目,无论其大其小,总有些类或者模块是为整个项目服务的,像这样的我们不论按照哪种分级方式都不是很合理,单独给他们做分级是比较好的选择,因为他们是整个项目中用的最多,跨度最广的。比如说有些工具类,我们用到的网路封装、宏定义、延展,或者自己公司的一些Custom等我们就可以单独拿出来,还有一些虽然不常用但是比较重要的比如说AppDelegate,一些Base基类,frame,sdk等也可以单独为他们做一个目录。还有一个我们项目中很有可能会用到第三方,对于第三方的管理我们该怎么去做,是手动管理还是用cocopods管理等这些都需要考虑,另外比较容易忽略的一点在Xcode中我们建目录的时候在项目中是不会创建文件夹的,我们最好是在项目中创建文件夹把响应分级对应到不同的文件夹中而不是仅仅Xcode中创建的分组。


图片发自笔记App

Class:存放的是App中所有的模块功能

Base:存放一些基类,比如BaseViewController,BaseModel等,共性直接在基类中去修改

Vendor:三方,因为我的项目中使用cocopods管理三方,所以这个文件夹中我在此放的是一些比较小的功能的第三方

Framework:存放一些类库或者自己封装的一些静态库

Resource:存放app中一些索引资源,比如图片,文本等,或者将图片打包的Bundle

Custom:这个文件夹我用来存放自己项目或者公司自己风格的一些自定义的视图,比如我们常见的上拉加载,下拉刷新的自定义头部空间等

API:这个只专门用来做网络处理的,因为这个项目基本上都会用到网络请求,算是比较重要的一个部分,所以在此单独拿出来作为一个分类

Support:这个用来存放一些比较小的模块,比如常用的一些工具类,分类,宏定义,PCH文件等

Main:专门存放AppDelegate或者AppDelegate的Category

        以上就是个人对于项目目录结构的一些看法,没有说绝对好的目录结构,只有我们不断优化的目录结构,在开发中我们更重要的还是要结合自己项目本身,具体情况具体分析,当然思想才是最重要的,希望大家多提宝贵意见,一起进步。