iOS开发那些事-移动平台架构设计

献给喜欢ios的同学

 

低耦合企业级系统架构设计

我们往往称JavaEE或.Net 开发的产品为“系统”,而移动平台(主要是:Android、iOS和Window Phone)开发的产品为“应用”。“系统”比较复杂,需要架构设计,而“应用”相对比较简单,这是不是意味着我们不需要考虑架构问题呢?

 

我们首先了解一下企业级系统架构设计。软件设计的原则是提高软件系统的“可复用性”和“可扩展性”,系统架构设计采用层次划分方式,这些层次之间是 松耦合的,层次的内部是高内聚的。降低耦合是软件设计的目标,能够设计出低耦合的系统,就意味着我们的系统具有“可复用性”和“可扩展性”。通用低耦合 JavaEE和.Net企业级系统架构图。

6

表示层是用户与系统交互的组件集合,用户通过这一层向系统提交请求或发出指令,系统通过这一层接收用户请求或指令,然后,将指令消化吸收后调用下一层,再将调用的结果展现到这一层。表示层应该是轻薄的不应该具有业务逻辑。

业务层是系统的核心业务处理层,负责接收表示层的指令和数据,消化吸收后,进行组织业务逻辑的处理,并将结果返回给表示层。

数据持久层是服务层用于访问数据库层,从设计规范上讲为了降低耦合度,服务层不应该具有访问数据库的代码,访问数据库的代码应该放到数据持久层中。

信息系统层,是系统的数据来源,可以是数据库、文件、遗留系统和网络数据。

移动平台的分层架构设计

移动平台的应用是缩小版本的系统,它也需要架构设计,但并非所有的应用都一定基于通用低耦合企业级系统架构,一般而言主要是涉及信息处理的应用才使用这种架构设计模式,例如:一些游戏有自己的游戏引擎,引擎也属于架构设计。iOS平台一般信息处理应用分层架构设计图。

7

表示层,iOS中的表示层是由UIKit Framework构成的,它包括我们前面学习的视图、控制器、控件和事件处理等内容;

业务逻辑层,采用什么框架要据具体的业务而定,但一般是具有一定业务处理功能的Objective-C和C++封装的类,或者是C封装的函数。

数据持久层,提供本地或网络数据访问,它可能是访问SQLite数据API函数,也可能是CoreData技术,或是访问文件的NSFileManager,或是网络通信等技术,采用什么方式要看信息系统层是什么。

信息系统层,就iOS而言它的信息来源分为:本地和网络。本地数据可以放入文件中也可以放在数据库中,目前iOS本地数据库采用SQLite3。网络可以是某个云服务,也可以是一般的Web服务。

基于同一工程的分层

架构对于我们iPhone和iPad开发有着很现实的意义。如果我们要编写一个基于iOS(iPhone和iPad两个平台)“My备忘录”应用, 它具有:增加、删除和查询备忘录的基本功能, “备忘录”应用用例图,分层设计之后,表示层可以有不同iPhone版和iPad版本,而且业务逻辑层、数 据持久层和信息系统层都可以公用。这样可以大大减少我们的工作量,这就是分层设计的好处。

8

iOS考虑iPhone和iPad两个平台,我们绘制了设计原型草图, iPhone版本的“My备忘录”应用设计原型草图。iPad版本的“My备忘录”横屏设计原型草图, iPad版本的“My备忘录”竖屏设计原型草图。

91011

 

 

在iOS平台分层的具体做法有多种模式:基于同一工程的分层、基于一个工作空间不同工程的分层和静态链接库分层。本小节介绍基于同一工程的分层。

我们在前文中已经介绍了构建自适应iPhone和iPad工程,就是我们现在要讲的基于同一工程的分层模式。请读“备忘录”应用的代码,实现过程这 里不做介绍,打开“MyNotes”工程,在Xcode工程导航面板有3个组:PresentationLayer、 BusinessLogicLayer和PersistenceLayer。创建这3个组的目的是把不同层中类放到对应的组中便于管 理, PresentationLayer是放置的表示层相关类,BusinessLogicLayer是放置的业务逻辑层的相关 类,PersistenceLayer是放置持久层相关类。

12

各个层的下面再如何划分呢?我们可以按照业务模块划分,也可以按照组件功能划分。本应用中PersistenceLayer层就还要分成dao和 domain两个组,dao是放置数据访问对象的,该对象中有对数据访问的CRUD四类方法,为了降低耦合度dao一般要设计成为协议(或Java接 口),然后根据不同的数据来源采用不同的实现方式。domain组是实体类,实体是应用中的“人”、“事”、“物”等。

dao组中NoteDAO.h代码如下:

  1. @interface NoteDAO : NSObject  
  2.   
  3. //保存数据列表  
  4.   
  5. @property (nonatomic,strong) NSMutableArray* listData;  
  6.   
  7. + (NoteDAO*)sharedManager;  
  8.   
  9. //插入Note方法  
  10.   
  11. -(int) create:(Note*)model;  
  12.   
  13. //删除Note方法  
  14.   
  15. -(int) remove:(Note*)model;  
  16.   
  17. //修改Note方法  
  18.   
  19. -(int) modify:(Note*)model;  
  20.   
  21. //查询所有数据方法  
  22.   
  23. -(NSMutableArray*) findAll;  
  24.   
  25. //按照主键查询数据方法  
  26.   
  27. -(Note*) findById:(Note*)model;  
  28.   
  29. @end  
@interface NoteDAO : NSObject

//保存数据列表

@property (nonatomic,strong) NSMutableArray* listData;

+ (NoteDAO*)sharedManager;

//插入Note方法

-(int) create:(Note*)model;

//删除Note方法

-(int) remove:(Note*)model;

//修改Note方法

-(int) modify:(Note*)model;

//查询所有数据方法

-(NSMutableArray*) findAll;

//按照主键查询数据方法

-(Note*) findById:(Note*)model;

@end



 

listData属性用于保存数据表中的数据,其中每一个元素都是Note对象,一个Note对象代表数据表中的一条数据。+ (NoteDAO*)sharedManager方法用于获得NoteDAO单例对象。dao组中NoteDAO.m代码如下:

  1. @implementation NoteDAO  
  2.   
  3. static NoteDAO *sharedManager = nil;  
  4.   
  5. + (NoteDAO*)sharedManager  
  6.   
  7. {  
  8.   
  9. static dispatch_once_t once;  
  10.   
  11. dispatch_once(&once, ^{  
  12.   
  13. NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];  
  14.   
  15. [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];  
  16.   
  17. NSDate *date1 = [dateFormatter dateFromString:@"2010-08-04 16:01:03"];  
  18.   
  19. Note* note1 = [[Note alloc] init];  
  20.   
  21. note1.date = date1;  
  22.   
  23. note1.content = @”Welcome to MyNote.”;  
  24.   
  25. NSDate *date2 = [dateFormatter dateFromString:@"2011-12-04 16:01:03"];  
  26.   
  27. Note* note2 = [[Note alloc] init];  
  28.   
  29. note2.date = date2;  
  30.   
  31. note2.content = @”欢迎使用MyNote。”;  
  32.   
  33. sharedManager = [[self alloc] init];  
  34.   
  35. sharedManager.listData = [[NSMutableArray alloc] init];  
  36.   
  37. [sharedManager.listData addObject:note1];  
  38.   
  39. [sharedManager.listData addObject:note2];  
  40.   
  41. });  
  42.   
  43. return sharedManager;  
  44.   
  45. }  
  46.   
  47. //插入Note方法  
  48.   
  49. -(int) create:(Note*)model  
  50.   
  51. {  
  52.   
  53. [self.listData addObject:model];  
  54.   
  55. return 0;  
  56.   
  57. }  
  58.   
  59.    
  60.   
  61. //删除Note方法  
  62.   
  63. -(int) remove:(Note*)model  
  64.   
  65. {  
  66.   
  67. for (Note* note in self.listData) {  
  68.   
  69. //比较日期主键是否相等  
  70.   
  71. if ([note.date isEqualToDate:model.date]){  
  72.   
  73. [self.listData removeObject: note];  
  74.   
  75. break;  
  76.   
  77. }  
  78.   
  79. }  
  80.   
  81. return 0;  
  82.   
  83. }  
  84.   
  85.    
  86.   
  87. //修改Note方法  
  88.   
  89. -(int) modify:(Note*)model  
  90.   
  91. {  
  92.   
  93. for (Note* note in self.listData) {  
  94.   
  95. //比较日期主键是否相等  
  96.   
  97. if ([note.date isEqualToDate:model.date]){  
  98.   
  99. note.content = model.content;  
  100.   
  101. break;  
  102.   
  103. }  
  104.   
  105. }  
  106.   
  107. return 0;  
  108.   
  109. }  
  110.   
  111.    
  112.   
  113. //查询所有数据方法  
  114.   
  115. -(NSMutableArray*) findAll  
  116.   
  117. {  
  118.   
  119. return self.listData;  
  120.   
  121. }  
  122.   
  123.    
  124.   
  125. //按照主键查询数据方法  
  126.   
  127. -(Note*) findById:(Note*)model  
  128.   
  129. {  
  130.   
  131. for (Note* note in self.listData) {  
  132.   
  133. //比较日期主键是否相等  
  134.   
  135. if ([note.date isEqualToDate:model.date]){  
  136.   
  137. return note;  
  138.   
  139. }  
  140.   
  141. }  
  142.   
  143. return nil;  
  144.   
  145. }  
  146.   
  147. @end  
@implementation NoteDAO

static NoteDAO *sharedManager = nil;

+ (NoteDAO*)sharedManager

{

static dispatch_once_t once;

dispatch_once(&once, ^{

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

NSDate *date1 = [dateFormatter dateFromString:@"2010-08-04 16:01:03"];

Note* note1 = [[Note alloc] init];

note1.date = date1;

note1.content = @”Welcome to MyNote.”;

NSDate *date2 = [dateFormatter dateFromString:@"2011-12-04 16:01:03"];

Note* note2 = [[Note alloc] init];

note2.date = date2;

note2.content = @”欢迎使用MyNote。”;

sharedManager = [[self alloc] init];

sharedManager.listData = [[NSMutableArray alloc] init];

[sharedManager.listData addObject:note1];

[sharedManager.listData addObject:note2];

});

return sharedManager;

}

//插入Note方法

-(int) create:(Note*)model

{

[self.listData addObject:model];

return 0;

}

 

//删除Note方法

-(int) remove:(Note*)model

{

for (Note* note in self.listData) {

//比较日期主键是否相等

if ([note.date isEqualToDate:model.date]){

[self.listData removeObject: note];

break;

}

}

return 0;

}

 

//修改Note方法

-(int) modify:(Note*)model

{

for (Note* note in self.listData) {

//比较日期主键是否相等

if ([note.date isEqualToDate:model.date]){

note.content = model.content;

break;

}

}

return 0;

}

 

//查询所有数据方法

-(NSMutableArray*) findAll

{

return self.listData;

}

 

//按照主键查询数据方法

-(Note*) findById:(Note*)model

{

for (Note* note in self.listData) {

//比较日期主键是否相等

if ([note.date isEqualToDate:model.date]){

return note;

}

}

return nil;

}

@end



 

NoteDAO实现采用了单例设计模式,这种设计与DAO设计模式没有关系,这主要是出于访问数据的方便。数据放置在listData属性中(本应该是从数据库中的,但是数据库访问技术我们还没有学习),CRUD方法也都是对listData的处理,而非数据库。

domain组中Note代码如下,它只有两个属性date是创建备忘录的日期,content是备忘录内容:

  1. //  
  2.   
  3. //  Note.h  
  4.   
  5.    
  6.   
  7. #import <Foundation/Foundation.h>  
  8.   
  9.    
  10.   
  11. @interface Note : NSObject  
  12.   
  13.    
  14.   
  15. @property(nonatomic, strong) NSDate* date;  
  16.   
  17. @property(nonatomic, strong) NSString* content;  
  18.   
  19.    
  20.   
  21. @end  
  22.   
  23.    
  24.   
  25. //  
  26.   
  27. //  Note.m  
  28.   
  29. #import ”Note.h”  
  30.   
  31.    
  32.   
  33. @implementation Note  
  34.   
  35.    
  36.   
  37. @end  
//

//  Note.h

 

#import <Foundation/Foundation.h>

 

@interface Note : NSObject

 

@property(nonatomic, strong) NSDate* date;

@property(nonatomic, strong) NSString* content;

 

@end

 

//

//  Note.m

#import ”Note.h”

 

@implementation Note

 

@end



 

业务逻辑层BusinessLogicLayer中的类的设计一般是按照业务模块设计的,它的方法是业务处理方法,下面代码是NoteBL.h代码:

  1. @interface NoteBL : NSObject  
  2.   
  3. //插入Note方法  
  4.   
  5. -(NSMutableArray*) createNote:(Note*)model;  
  6.   
  7.    
  8.   
  9. //删除Note方法  
  10.   
  11. -(NSMutableArray*) remove:(Note*)model;  
  12.   
  13.    
  14.   
  15. //查询所有数据方法  
  16.   
  17. -(NSMutableArray*) findAll;  
  18.   
  19.    
  20.   
  21. @end  
  22.   
  23. 在NoteBL.h中定义了三个方法,之所以定义三个方法是根据我的业务需求决定的,业务需求可以参考的用例图。下面代码是NoteBL.m代码:  
  24.   
  25. @implementation NoteBL  
  26.   
  27.    
  28.   
  29. //插入Note方法  
  30.   
  31. -(NSMutableArray*) createNote:(Note*)model  
  32.   
  33. {  
  34.   
  35. NoteDAO *dao = [NoteDAO sharedManager];  
  36.   
  37. [dao create:model];  
  38.   
  39. return [dao findAll];  
  40.   
  41. }  
  42.   
  43.  //删除Note方法  
  44.   
  45. -(NSMutableArray*) remove:(Note*)model  
  46.   
  47. {  
  48.   
  49. NoteDAO *dao = [NoteDAO sharedManager];  
  50.   
  51. [dao remove:model];  
  52.   
  53. return [dao findAll];  
  54.   
  55. }  
  56.   
  57.  //查询所有数据方法  
  58.   
  59. -(NSMutableArray*) findAll  
  60.   
  61. {  
  62.   
  63. NoteDAO *dao = [NoteDAO sharedManager];  
  64.   
  65. return [dao findAll];  
  66.   
  67. }  
  68.   
  69.  @end  
@interface NoteBL : NSObject

//插入Note方法

-(NSMutableArray*) createNote:(Note*)model;

 

//删除Note方法

-(NSMutableArray*) remove:(Note*)model;

 

//查询所有数据方法

-(NSMutableArray*) findAll;

 

@end

在NoteBL.h中定义了三个方法,之所以定义三个方法是根据我的业务需求决定的,业务需求可以参考的用例图。下面代码是NoteBL.m代码:

@implementation NoteBL

 

//插入Note方法

-(NSMutableArray*) createNote:(Note*)model

{

NoteDAO *dao = [NoteDAO sharedManager];

[dao create:model];

return [dao findAll];

}

 //删除Note方法

-(NSMutableArray*) remove:(Note*)model

{

NoteDAO *dao = [NoteDAO sharedManager];

[dao remove:model];

return [dao findAll];

}

 //查询所有数据方法

-(NSMutableArray*) findAll

{

NoteDAO *dao = [NoteDAO sharedManager];

return [dao findAll];

}

 @end


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值