最主要的目的在于減少代碼量,提高復用度,降低耦合度,方便后期修改。結(jié)構(gòu)清晰,方便測試。
- 第一步:搞清楚要解決哪些問題,并找到解決這些問題的充要條件
你必須得清楚你要做什么,業(yè)務方希望要什么。而不是為了架構(gòu)而架構(gòu),也不是為了體驗新技術而改架構(gòu)方案。減少充要條件。搞清楚對于業(yè)務方而言的真正充要條件很重要!這決定了你的架構(gòu)是否足夠易用。另外,傳的參數(shù)越少,耦合度相對而言就越小,你替換模塊或者升級模塊所花的的代價就越小。
- 第二步:問題分類,分模塊
- 第三步:搞清楚各問題之間的依賴關系,建立好模塊交流規(guī)范并設計模塊
關鍵在于建立一套統(tǒng)一的交流規(guī)范。- 第四步:推演預測一下未來可能的走向,必要時添加新的模塊,記錄更多的基礎數(shù)據(jù)以備未來之需
- 第五步:先解決依賴關系中最基礎的問題,實現(xiàn)基礎模塊,然后再用基礎模塊堆疊出整個架構(gòu)
- 第六步:打點,跑單元測試,跑性能測試,根據(jù)數(shù)據(jù)去優(yōu)化對應的地方
總而言之就是要遵循這些原則:自頂向下設計(1,2,3,4步),自底向上實現(xiàn)(5),先測量,后優(yōu)化(6)。
什么樣的架構(gòu)叫好架構(gòu)?
代碼整齊,分類明確,沒有common,沒有core
不用文檔,或很少文檔,就能讓業(yè)務方上手
思路和方法要統(tǒng)一,盡量不要多元
沒有橫向依賴,萬不得已不出現(xiàn)跨層訪問
對業(yè)務方該限制的地方有限制,該靈活的地方要給業(yè)務方創(chuàng)造靈活實現(xiàn)的條件
易測試,易拓展
保持一定量的超前性
接口少,接口參數(shù)少
高性能
View層
當我們開始設計View層的架構(gòu)時,往往是這個App還沒有開始開發(fā),或者這個App已經(jīng)發(fā)過幾個版本了,然后此時需要做非常徹底的重構(gòu)。我們在這時候必須清楚認識到:View層的架構(gòu)一旦實現(xiàn)或定型,在App發(fā)版后可修改的余地就已經(jīng)非常之小了。因為它跟業(yè)務關聯(lián)最為緊密,所以哪怕稍微動一點點,它所引發(fā)的蝴蝶效應都不見得是業(yè)務方能夠hold住的。
View代碼結(jié)構(gòu)的規(guī)定
不要在viewDidLoad里面初始化你的view然后再add,這樣代碼就很難看。在viewDidload里面只做addSubview的事情,最后在viewDidAppear里面做Notification的監(jiān)聽之類的事情。至于屬性的初始化,則交給getter去做。
常情況下ViewController里面一般是不會存在private methods的,這個private methods一般是用于日期換算、圖片裁剪啥的這種小功能。這種小功能要么把它寫成一個category,要么把他做成一個模塊,哪怕這個模塊只有一個函數(shù)也行。ViewController基本上是大部分業(yè)務的載體,本身代碼已經(jīng)相當復雜,所以跟業(yè)務關聯(lián)不大的東西能不放在ViewController里面就不要放。另外一點,這個private method的功能這時候只是你用得到,但是將來說不定別的地方也會用到,一開始就獨立出來,有利于將來的代碼復用。
在iOS開發(fā)領域中,怎樣才算是MVC劃分的正確姿勢?
M應該做的事:
給ViewController提供數(shù)據(jù)
給ViewController存儲數(shù)據(jù)提供接口
提供經(jīng)過抽象的業(yè)務基本組件,供Controller調(diào)度
C應該做的事:
管理View Container的生命周期
負責生成所有的View實例,并放入View Container
監(jiān)聽來自View與業(yè)務有關的事件,通過與Model的合作,來完成對應事件的業(yè)務。
V應該做的事:
響應與業(yè)務無關的事件,并因此引發(fā)動畫效果,點擊反饋(如果合適的話,盡量還是放在View去做)等。
界面元素表達
目錄結(jié)構(gòu):
第一種
AppDelegate 這個目錄下放的是AppDelegate.h(.m)文件,是整個應用的入口文件,所以單獨拿出來。
Macro 這個目錄下放了整個應用會用到的宏定義(把宏定義在.h中放在這個目錄中)VendorMacro.h 里放一些第三方常量
Models 這個目錄下放一些與數(shù)據(jù)相關的Model文件,General 這個目錄放會被重用的Views/Classes和Categories
Vendors 這個目錄放第三方的類庫/SDK,如UMeng、WeiboSDK、WeixinSDK等等。
Helpers 這個目錄放一些助手類,文件名與功能掛鉤。助手類的主要作用是幫助Controller瘦身,也可以提供一定程度的復用。自己封裝可復用的類等。
Sections 這個目錄下面的文件對應的是app的具體單元,如導航、瀑布流等等。
Resources 這個目錄下放的是app會用到的一些資源,主要是圖片。
Cocoapods 業(yè)務無關的類庫可以通過 Cocoapods 來方便地管理,如SDWebImage, Reachability等等。還有一些是多個應用都會用到的基礎模塊,比如HBAPI、HBSNS 、HBFoundation(HB為公司名首字母)等等,可以建一個私有的git repo,然后加到podfile中,這樣如果HBAPI有更新,只需要pod update一下就行了。
主目錄按照業(yè)務分類,內(nèi)目錄按照模塊分類
主目錄按照模塊分類,內(nèi)目錄按照業(yè)務分類
VPBD
ViewController(View):管理View的層次結(jié)構(gòu)、生命周期、一些組合過的View。
ViewModel:負責轉(zhuǎn)換View需要的數(shù)據(jù)格式。
Presenter:顯示View、ViewController的邏輯。
Router(Wireframe):頁面跳轉(zhuǎn)邏輯。
Business:核心業(yè)務邏輯,復用性很高。
Model:基本數(shù)據(jù)模型,根據(jù)業(yè)務來定義。
DataSource:對于數(shù)據(jù)的抽象,對于Business層而言,不需要知道它是從網(wǎng)絡、數(shù)據(jù)庫還是緩存中得到的。
MVVM 模式下iOS項目目錄結(jié)構(gòu)
一、MVVM 模式介紹
MVVM 是 Model-View-View Model 的縮寫,MVVM 聽起來好像很復雜的樣子,但它本質(zhì)上就是MVC 的改進版。MVVM 就是將其中的View 的狀態(tài)和行為抽象化,讓我們將視圖 UI 和業(yè)務邏輯分開。當然這些事 ViewModel 已經(jīng)幫我們做了,它可以取出 Model 的數(shù)據(jù)同時幫忙處理 View 中由于需要展示內(nèi)容而涉及的業(yè)務邏輯。在 iOS 中使用 MVVM 可以將 ViewController 中處理 Mode 的業(yè)務邏輯全部交由 ViewModel,讓 ViewController 不再顯的特別臃腫。
MVVM模式是通過下面三個核心組件組成,每個都有它自己所要處理的事情:
Model -數(shù)據(jù)模型
View – 用來將Model 的內(nèi)容顯示出來
ViewModel - 扮演“View”和“Model”之間的使者,幫忙處理 View 的業(yè)務邏輯
- 低耦合。視圖(View)可以獨立于Model變化和修改,一個ViewModel可以綁定到不同的"View"上,當View變化的時候Model可以不變,當Model變化的時候View也可以不變。
- 可重用性。你可以把一些視圖邏輯放在一個ViewModel里面,讓很多view重用這段視圖邏輯。
- 獨立開發(fā)。開發(fā)人員可以專注于業(yè)務邏輯和數(shù)據(jù)的開發(fā)(ViewModel),設計人員可以專注于頁面設計。
- 可測試。界面素來是比較難于測試的,而使用MVVM的一大好處是我們可以很容易對 ViewModel 進行單元測試
二、項目目錄結(jié)構(gòu)
一個合理的項目目錄結(jié)構(gòu)首先應該是讓人一目了然的,讓人一眼看上去就能大概了解目錄的職責,了解每個文件夾下的內(nèi)容是做什么的,而且容易應對新的改變方便后續(xù)添加功能或者擴展。要達到以下兩個目的:
1)使項目更適合于團隊開發(fā),能夠降低耦合、便于任務的劃分和代碼的整合管理。
2)使項目能夠積累出更多可復用的代碼和架構(gòu)。
這個結(jié)構(gòu)會在不斷遇到問題解決問題的過程中權(quán)衡、進化,在這個過程最重要的是能夠保持:
1)主干簡潔。主干上防止過度劃分,過度劃分會讓代碼放在這個目錄下也可以,放在另一個目錄下好像也行,容易混亂。
2)分支開放。不對過于細節(jié)的分支做嚴格規(guī)范,可以發(fā)揮大家的靈活性和創(chuàng)造性。
Define —— 用于存放些宏(#define)。
Models —— 用于存放模型類。如:BaseModel.h,CollectionModel.h
NetworkManager —— 用于存放網(wǎng)絡請求類
Resources —— 用于存放資源 例如xib,storyboard,圖片,plist,音頻,視頻
Util —— 用于存放可重用的分類Category和擴展或者工具類Tools,比如數(shù)據(jù)正則匹配等。能復用的視圖Views
Vendors —— 用于存放第三方框架或者第三方SDK文件
View —— 用于存放視圖類
ViewControllers —— 用于存放視圖控制器類,也就是View層。
ViewModel —— 用于存放視圖模型類,及處理 View 和 Model 之間的業(yè)務邏輯和網(wǎng)絡請求。
Config:就是工程的配置文件,用于放置程序的一些配置,UI高度,方便統(tǒng)一修改。
整體項目的運行流程是:每層之間的交互是用Block的形式來實現(xiàn)的。
ViewController->向ViewModel請求數(shù)據(jù)->ViewModel->向網(wǎng)絡請求數(shù)據(jù)->需要數(shù)據(jù)解析類型負責解析
開發(fā)流程
在拿到設計圖后,就可以針對設計圖抽離出可復用的Classes/Views,考慮一下某個效果的具體實現(xiàn),使用合適的設計模式來避免大量的if/else嵌套,等等。所以前期一定要做好充足的準備工作。
ViewController里面:
@property
pragma mark - life cycle
生命周期
viewDidLoad
pragma mark - UItableViewDelegate
pragma mark - CustomDelegate
自定義委托
pragma mark - event response
事件響應
pragma mark - private methods
私有方法