閱讀706 返回首頁    go 阿裏雲 go 技術社區[雲棲]


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備忘錄”豎屏設計原型草圖。

9 10 11

 

 

在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代碼如下:

@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代碼如下:

@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是備忘錄內容:

//

//  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代碼:

@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


內容來源於《iOS6開發指南》一書,作者:關東升

最後更新:2017-04-03 19:13:18

  上一篇:go android獲取URLConnection和HttpClient網絡請求響應碼
  下一篇:go Windows Blue請願清單:十五項必須改進的特性