项目总结--Version 1.0(一)

  欢迎加入【iOS/Swift/OC开发交流群|127183325】交流学习。

 

  公司项目的1.0版本已经结束有一段时间了,2.0版本也逐渐进入尾声,从1.0版本结束就计划着写一下项目总结,一是对项目进行一下思路梳理,二是总结一下之前的工作,找到所遇到的问题和架构的不合理之处,为接下来的版本做准备。由于2.0版本的任务比较紧急,一直没有时间做个系统的整理,只是零零星星的做了一些备注、笔记什么的。因为个人原因,准备回济南发展,所以向公司提出了辞职。利用这段准备移交工作的时间做了一下项目版本1.0的总结,希望能为新来的iOS同事快速进入状态提供一些帮助。

  由于项目还没有上线,所以许多东西都需要保密,可能会有部分比较敏感的部分不会详说。另外,由于项目后台是公司内网,本文主要讲讲架构的设计思路,具体的技术细节和代码就不往上贴了,有时间可以另开一帖详谈。

  1.0版本的项目总结分成以下部分:

  一、从架构谈起--架构的分层和功能逻辑的细分。

  二、关于可复用性和可扩展性。

  三、Block和Delegate的抉择。

  四、关于第三方库

  五、框架的进化--框架的持续优化

 

一、从架构谈起--架构的分层和功能逻辑的细分。

  对于第一款从零开始主导开发的项目,在开始之前做足了功课。虽然还是有缺陷,但是架构不就是在不断的试错改错中逐渐完善的嘛(给自己找了一个好借口。。。)。

  先说一下架构的原则,参考之前看到的一篇文章,文章里面比较详细的讨论了在架构设计中的一些关键原则。对此做的总结如下:

  1.需要分层,将复杂的系统分解成比较容易实现的较小系统。

  2.层内部高内聚,层与层之间低耦合,层与层之间的访问是透明的,不需要了解实现过程。

  3.职责单一原则,职责分工需要明确,逻辑尽量细分,依赖关系尽量少。

  4.敏捷开发中需要思维收敛,不要做过多的发散,只设计必须的内容。

  5.功能模块化,模块与模块之间也不需要了解实现细节。

  6.优先考虑项目的扩展性和可伸缩性,性能在初期不必过多考虑。

 

  分层可以将复杂的系统细分成多个较为简单的系统,每一层只负责实现本层的功能,而不用去关心其它层的实现细节,开发人员只关注本层的实现即可,功能实现上变得简单,也提高了系统的伸缩性和扩展性。职责单一原则要求的功能细分的粒度尽量的小,功能实现不重复,不越权,对于相对底层的模块,可以更好的进行复用。对于敏捷开发,前期由于需求的不明确和不稳定,我们可能注重的是功能的实现而不是大量的预先设计,所以我们尽量只设计必须的内容,避免陷入多度设计的坑。对于最后一点不同的开发人员可能有不同的想法,个人认为在开发的初期优先考虑扩展性和伸缩性可以更快的进行版本迭代,不断地试错,更快的做出一款用户喜欢的产品,而性能瓶颈在初期并不明显,只有在用户达到一定数量的时候才会出现性能问题,而我们可以在逐步完善产品的过程中可以不断地优化,逐步的提高软件的性能。

  先看一下此次项目的分层架构设计图。

  从上图可以看出,各层之间数据的流动严格遵守着规则,就是必须要通过业务逻辑层来进行交流。而各层的功能都是基于底层的功能之上,层与层之间的交流通过设计好的具有一定规则的接口来进行,不用关心具体的实现,因此在业务逻辑发生变化的时候就可以将修改的范围降到最少。层与层之间只能与邻近的层进行交互,不能跨层调用。每一层内部又进行功能模块的细分,模块与模块之间的交互也必须有一定的规则,模块内部高内聚,模块之间低耦合,模块与模块之间关注接口,模块内部关注实现,模块内部的修改不会影响其他的模块。

  分好层之后就可以着手进行具体的开发了。一般是从底层开始,最后实现View层。本项目中每层的实现的功能:

  1、DataPresentation(数据持久层):数据的来源。数据来源有数据库、服务器和内存缓存,根据数据来源设计DAO、NET和DataCache三个模块,三个模块分别有自己的实现数据访问的接口,然后通过统一的DataPresentation层向上部提供数据访问的接口。上层不需要了解数据是怎么获取到的。

  2、BusinessLogic(业务逻辑层):核心业务逻辑,一般需要很高的复用性。业务逻辑层用来处理从View层传过来的数据,处理完成后或者从底层数据层获取相关数据然后更新到View层,或者直接更新View层,或者将相关数据存储到网络服务器或本地持久化或者缓存到内存中。

  3、View(视图层/表示层):数据的展示,处理绘图、点击或者手势等事件。

  

  下图体现了在此项目中实现数据持久层各模块之间的逻辑关系。

  数据持久化的可选方案主要有属性列表、对象归档、SQLite数据库和Core Data(实质上也是SQLite)。此次的项目选择使用SQLite数据库,使用FMDB这个十分优秀的第三方库。顺便说一下,在敏捷开发中,非常重要的一点是产品的快速迭代,然后不断地试错,不断地进化,速度是很重要的,所以可以选择一些比较成熟的框架来用,这比自己重新实现来的要快。在使用第三方库的时候有一点需要切记,由于第三方库是由其他的开发者开发的,第三方库提供的一些接口有可能在将来会发生改变,所以我们不能将第三方库的接口散落到项目的各处,我们需要在它们的上面封装一层自己的接口,以备将来第三方库的接口改变或者替换其他的第三方库。

  网络模块的设计需要根据项目的具体需求来选择HTTP协议或者TCP/IP协议。本项目因为需要远程遥控和WAN/LAN文件传输,另外还需要和web服务器进行通讯,所以项目中用到的协议有HTTP、TCP。另外,发现局域网内的硬件设备使用了UDP协议。相关的协议就不在这详说了,只说一下用在了什么地方。

  1.HTTP,主要用在了和服务器的交互,由于一开始看的MJ大神的教程,所以在设计这一模块的时候深受其影响。因为感觉Block是如此的好用,所以就在此处大量的使用了类方法和Block,导致1.0版本在扩展性上大打折扣,后期更改需求的时候明显感觉到困难。也因为如此,在进行2.0版本设计的时候基本上是对这一模块进行了完全的重构,明确了哪些地方用Block,哪些地方用Delegate。所以,虽然Block和Delegate在功能和所要解决的问题比较相似,特别是Block在可读性方面可能比Delegate更有优势,但Block并不能完全替代Delegate。更详细的用法可以参看这篇文章

  2.Socket,这一部分用在了两个地方,一是远程遥控,对控制命令的实时性要求比较高,需要使用TCP;二是在局域网内的文件传输,也是用的TCP;三是用于发现局域网内的硬件设备,根据定义好的协议,手机端需要在局域网内广播UDP包,硬件端收到UDP包后也在局域网内广播自己的UDP包,手机端对收到的包进行过滤后就可以发现所有在线的设备了。想快速实现这一模块的话可以使用CocoaAsyncSocket

  内存缓存在1.0版本中设计的比较简单,使用了单例设计模式,看下图:

  有内存缓存机制的时候,必须要考虑内存警告和缓存数据过期的情况。

  因为在数据持久层有三种途径可以获取数据,所以就得设计一种存取数据的机制,或者说规则,比较通用的机制如下:

  这张图只是展示了获取数据的一个过程,在从服务器获取数据后需要将数据在本地缓存,缓存两种途径,一个是本地持久化,即存入SQLite数据库,一个是内存缓存。

  好了,数据持久层的设计就到此为止了。当然,这样的设计肯定会有缺陷存在,但是不怕,我们可以在以后的版本迭代升级中逐步的进行完善,我相信,只要我们不断的找出在设计上的问题然后改正,最终我们会构建出一个优秀的框架。

 

posted @ 2015-11-02 18:06  驴车手  阅读(391)  评论(0编辑  收藏  举报