iOS開發那些事-移動平台架構設計
低耦合企業級係統架構設計
我們往往稱JavaEE或.Net 開發的產品為“係統”,而移動平台(主要是:Android、iOS和Window Phone)開發的產品為“應用”。“係統”比較複雜,需要架構設計,而“應用”相對比較簡單,這是不是意味著我們不需要考慮架構問題呢?
我們首先了解一下企業級係統架構設計。軟件設計的原則是提高軟件係統的“可複用性”和“可擴展性”,係統架構設計采用層次劃分方式,這些層次之間是 鬆耦合的,層次的內部是高內聚的。降低耦合是軟件設計的目標,能夠設計出低耦合的係統,就意味著我們的係統具有“可複用性”和“可擴展性”。通用低耦合 JavaEE和.Net企業級係統架構圖。
表示層是用戶與係統交互的組件集合,用戶通過這一層向係統提交請求或發出指令,係統通過這一層接收用戶請求或指令,然後,將指令消化吸收後調用下一層,再將調用的結果展現到這一層。表示層應該是輕薄的不應該具有業務邏輯。
業務層是係統的核心業務處理層,負責接收表示層的指令和數據,消化吸收後,進行組織業務邏輯的處理,並將結果返回給表示層。
數據持久層是服務層用於訪問數據庫層,從設計規範上講為了降低耦合度,服務層不應該具有訪問數據庫的代碼,訪問數據庫的代碼應該放到數據持久層中。
信息係統層,是係統的數據來源,可以是數據庫、文件、遺留係統和網絡數據。
移動平台的分層架構設計
移動平台的應用是縮小版本的係統,它也需要架構設計,但並非所有的應用都一定基於通用低耦合企業級係統架構,一般而言主要是涉及信息處理的應用才使用這種架構設計模式,例如:一些遊戲有自己的遊戲引擎,引擎也屬於架構設計。iOS平台一般信息處理應用分層架構設計圖。
表示層,iOS中的表示層是由UIKit Framework構成的,它包括我們前麵學習的視圖、控製器、控件和事件處理等內容;
業務邏輯層,采用什麼框架要據具體的業務而定,但一般是具有一定業務處理功能的Objective-C和C++封裝的類,或者是C封裝的函數。
數據持久層,提供本地或網絡數據訪問,它可能是訪問SQLite數據API函數,也可能是CoreData技術,或是訪問文件的NSFileManager,或是網絡通信等技術,采用什麼方式要看信息係統層是什麼。
信息係統層,就iOS而言它的信息來源分為:本地和網絡。本地數據可以放入文件中也可以放在數據庫中,目前iOS本地數據庫采用SQLite3。網絡可以是某個雲服務,也可以是一般的Web服務。
基於同一工程的分層
架構對於我們iPhone和iPad開發有著很現實的意義。如果我們要編寫一個基於iOS(iPhone和iPad兩個平台)“My備忘錄”應用, 它具有:增加、刪除和查詢備忘錄的基本功能, “備忘錄”應用用例圖,分層設計之後,表示層可以有不同iPhone版和iPad版本,而且業務邏輯層、數 據持久層和信息係統層都可以公用。這樣可以大大減少我們的工作量,這就是分層設計的好處。
iOS考慮iPhone和iPad兩個平台,我們繪製了設計原型草圖, iPhone版本的“My備忘錄”應用設計原型草圖。iPad版本的“My備忘錄”橫屏設計原型草圖, iPad版本的“My備忘錄”豎屏設計原型草圖。
在iOS平台分層的具體做法有多種模式:基於同一工程的分層、基於一個工作空間不同工程的分層和靜態鏈接庫分層。本小節介紹基於同一工程的分層。
我們在前文中已經介紹了構建自適應iPhone和iPad工程,就是我們現在要講的基於同一工程的分層模式。請讀“備忘錄”應用的代碼,實現過程這 裏不做介紹,打開“MyNotes”工程,在Xcode工程導航麵板有3個組:PresentationLayer、 BusinessLogicLayer和PersistenceLayer。創建這3個組的目的是把不同層中類放到對應的組中便於管 理, PresentationLayer是放置的表示層相關類,BusinessLogicLayer是放置的業務邏輯層的相關 類,PersistenceLayer是放置持久層相關類。
各個層的下麵再如何劃分呢?我們可以按照業務模塊劃分,也可以按照組件功能劃分。本應用中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