iOS数据层处理

前言

  刚毕业就做iOS开发,到现在也有些年头了,感觉自己在工作中慢慢摸索、总结出了一套自己的程序设计思路,而且这套思路也不错的经受住了很多个不同类型项目、不同团队的实际考验,一直都有着不错的表现,最近不是很忙,借着博客记录一下在程序设计上自己的收获与心得。

  个人总结,app客户端程序可以划分为两个部分,下层部分与数据打交道,包含网络请求与本地数据操作(存取);上层部分就是应用层部分,负责UI交互与业务逻辑的串联,如下图:


   一般在项目实施时,我们第一步都会先商量、定义好底层的数据模型、本地数据存储接口以及网络层接口(本地的+服务器的)。然后,两组人同时起头并进进行开发,负责上层的同事完全不用关心下层(数据相关)的具体实现(数据是怎么从网上请求回来的;请求返回后如何处理、存储数据;本地数据是如何存储获取的;底层的存储是怎么实现的,等等),他们只需要知道之前定义好的本地网络层及数据层接口就行了,在合适的时机去调用即可。而下层开发的同事,也是不用去考虑上层的具体实现,两拨人的工作是不会产生任何冲突的。一般情况下,下层的开发工作会相对更快的完成,然后下层的开发同事就可以返过头来去参与上层同事的开发工作,最终完成项目。

  当然,要达到上面所说的效果,就离不开前期一定的设计工作,下面就从数据层、网络层和应用层三个层次讲一下我一直以来采用的设计方法。

  总的来说,明确职责,各司其职,尽力而为,是我在程序设计时的基本指导思想;

  点到为止、量力而行,不要过度设计、过度模式是我的设计原则,够用就行。其实设计的目的主要就是为了让代码有更高的独立性、纯粹性(不臃肿、职责明确)、通用性和扩展性,手段一般也就是不断的换着花样分层或解藕。个人感觉,这部分工作在大型互联网企业、大团队、特大项目中还是很有必要的,是可以不断追求的,因为大团队人多,业务繁杂,如果设计层面上不做好,不花精力去实现、改进,都揉杂在一起,团队间相互牵制,基本无法配合,而且还会带来后续扩展性差、可能会重复实现、重复造轮子等问题;但是,设计都是需要花费精力去思考和实现的,同时往往也会在某种程度上增加代码的"复杂性"与代码量,像中小型团队(非特大型项目),人不多,项目相对独立、业务也不是太过庞杂等,沟通与后续开发修改成本本身不会太大,所以权衡设计、把握设计的尺度就显的尤为重要。

数据层设计

1.基本设计

数据层负责模型定义+本地数据存取(数据操作),其实看看realm或者coredata这类框架的设计,当你定义好模型后,数据的存取操作也随之完成,也印证了我们对这个层次在职责划分上的合理性。这个层次可以说是最最单纯的一层,在代码层面上与其他层次完全没有任何缠绕,在实现上可以做到完全的独立,有着很好的复用与迁移性。

这个层次位于整个架构的最底层,是其它所有层次的根基与"工具"。

在数据层里定义好项目中所有可能用到的模型类,同时还要实现好每种模型对应的所有数据操作


[objc]  view plain  copy
  1. //模型定义  
  2. @interface JHSMS : NSObject  
  3.   
  4. @property (nonatomic,copyNSString *uniqueId;  
  5. @property (nonatomic,copyNSString *phoneNum;  
  6. @property (nonatomic,copyNSString *content;  
  7. @property (nonatomic,copyNSString *relatedWorkNum;  
  8. @property (nonatomic,strongNSDate *msgDate;  
  9. @property (nonatomic,assign) BOOL isInComing;  
  10. @property (nonatomic,assign) SMS_SENDSTATUS sendStatus;  
  11. ........  
  12.   
  13. //数据操作  
  14. +(void)saveSmsAry:(NSMutableArray *)smsAry;  
  15. +(BOOL)saveSingleSms:(JHSMS *)sms;  
  16. +(void)updateMsgStatus:(SMS_SENDSTATUS)sendStatus uniqueId:(NSString *)uniqueId;  
  17. +(NSMutableArray *)getRecentlySMSs:(NSString *)phoneNum;  
  18. +(NSMutableArray *)getSMSs:(NSString *)phoneNum beforeSms:(JHSMS *)sms;  
  19. +(void)resendSms:(JHSMS *)sms;  
  20. .......  
  21. @end  
具体数据操作实现
[objc]  view plain  copy
  1. +(BOOL)saveSingleSms:(JHSMS *)sms  
  2. {  
  3.     BOOL __block result = YES;  
  4.     [_shareQueue inTransaction:^(FMDatabase *db, BOOLBOOL *rollback) {  
  5.           
  6.         @try {  
  7.             NSString *insertStr = @"insert into 'SMS'('uniqueID','appUserWorkId','phoneNum','content','msgDate','contactType','friendContactId','relatedWorkNum','isInComing','sendStatus') values (?,?,?,?,?,?,?,?,?,?)";  
  8.             CONATACT_TYPE contactType;  
  9.               
  10.             FMResultSet *rs = [db executeQuery:@"select relatedWorkId from PhonesInCorpContacts where phoneNum = ?",sms.phoneNum];  
  11.             if ([rs next])  
  12.             {  
  13.                 sms.friendContactId = [rs stringForColumn:@"relatedWorkId"];  
  14.                 contactType = CORP_CONTACT;  
  15.             }  
  16.             else  
  17.             {  
  18.                 FMResultSet *rs2 = [db executeQuery:@"select relatedRecordId from PhonesInLocalContacts where appUserWorkId = ? and phoneNum = ?",appUserWorkId,sms.phoneNum];  
  19.                 ..............  
  20.                 [rs2 close];  
  21.             }  
  22.             ............  
  23.         }  
  24.     }];  
  25.     return result;  
  26. }  

2.数据层的设计改进

数据层的设计改进主要针对的是数据操作部分,上面的设计中存在两个问题,导致了模型类的过于臃肿和耦合性过大

(1)模型定义与数据操作耦合性过大

数据的本地存取操作可能会有很多不同方式(nsuerdefault、数据库、文件等等)及不同的业务需求,如果按照上面的实现,我们没有一个单独的层次去分离出数据操作的具体实现,那么如果以后要更换底层的存储方式,或是修改、添加数据操作实现时,那么就会对模型类造成影响,导致模型类的暴露与修改。所以我们还可以在数据层里单独划分出模型层+数据操作层.



  在另一个项目中,我加入saver层,在这个层次里完成具体的数据存储操作,可以是数据库操作,也可以文件操作或是别的,甚至我还完成过同时支持多种存储形式,然后交由调用者选择的需求,无论怎样,这些不同的底层实现都封装可以在这个层次中单独的处理,对使用者透明,修改、实现时不会对模型类产生任何影响,同时大大减少了模型类的代码体量与功能承载压力

(2)数据操作与业务有缠绕

第二个问题是,针对每种模型(数据),其实最最纯粹根本的操作就是对一个(一组)数据的增、删、改、查,而在我上面的代码示例中

[objc]  view plain  copy
  1. +(void)updateMsgStatus:(SMS_SENDSTATUS)sendStatus uniqueId:(NSString *)uniqueId;  
  2. +(void)resendSms:(JHSMS *)sms;  
  3. +(NSMutableArray *)getRecentlySMSs:(NSString *)phoneNum;  
这些操作明显是依据业务而定义(衍生)的,不具备普遍的通用性,没有复用的价值,同时造成了数据操作层与业务的耦合,于是我们可以对数据操作层再细分


划分后,基础操作层可能包含下列这类函数实现,分离后它们具有很好的"原子性"、通用性与复用性

[objc]  view plain  copy
  1. +(BOOL)saveSmsAry:(NSMutableArray *)smsAry;  
  2. +(BOOL)saveSingleSms:(JHSMS *)sms;  
  3. +(BOOL)deleteSms:(JHSMS *)sms;  
  4. +(NSMutableArray *)getSMSsWithCondition:(NSString *)condition;  
  5. +(BOOL)updateSmsForProperty:(NSString *)property value:(NSString *)value;  

而业务操作层则是根据你具体的项目业务需求,对基础操作层进行不同的组合、调用


在数据层的实际设计开发中,我大部分情况下都是按基础设计去做的,除非有特殊需要,比较少的对数据操作层进行进一步细分.数据层比较单纯、独立、基础,其实修改、实现成本本身就不大,除非有特殊需求,一般我也就模型、数据操作写一起了,这样开发起来速度最快,复用、修改起来的工作量与难度也并不会很大.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值