工程結(jié)構(gòu)架構(gòu)谴古,減少耦合混亂以及防治需求大改造成結(jié)構(gòu)重構(gòu),如何構(gòu)建穩(wěn)定可擴展可變換的工程結(jié)構(gòu)的思考
我打算采用Information flow的方式自上而下稠歉,兩大層分為基礎層和展現(xiàn)層的結(jié)構(gòu)掰担。基礎層分為多層怒炸,展現(xiàn)層也可分為多層带饱。主要思想是將基礎層的最下一層當做零部件,將業(yè)務層最下層當做組裝大部件阅羹,通過流程串起來形成一個完整的產(chǎn)品勺疼,做零件時按照做出一個就扔進對應基礎層的籃子里思路來,目錄結(jié)構(gòu)也可以按照這種來進行捏鱼。這兩大層的最下層按照零件拆得越小越容易應對需求變化越容易保護鞏固上層的思路來就好执庐。拿微信這個大家都熟悉的產(chǎn)品的幾個功能來簡單示例說明下這個思路構(gòu)建后的結(jié)構(gòu),模塊比較多导梆,一些模塊就不深入到最底層分析了:
基礎層
- 網(wǎng)絡
-- 收發(fā)數(shù)據(jù)
---單例(持續(xù)使用數(shù)據(jù))
---本地(緩存和持續(xù)化存儲數(shù)據(jù)對業(yè)務的封裝輸出)
---單次使用(API接口Model封裝輸出和業(yè)務邏輯封裝的ViewModel轨淌,將這些做為業(yè)務零件)
- 存儲
--- NSUserDefault(對輕量需要存儲的添加下一層業(yè)務零件封裝)
--- keychain(對安全級別較高需要存儲的添加下一層業(yè)務零件封裝)
--- 文件存儲(對時效需求短的需要存儲的添加下一層業(yè)務零件封裝)
--- 數(shù)據(jù)庫存儲(對數(shù)據(jù)量大的需要存儲的添加下一層業(yè)務零件封裝,業(yè)務層上一層加一層封裝CoreData或SQLite方便日后切換數(shù)據(jù)庫用)
- 動畫(下層將動畫框架輸出成各個可以復用的動畫功能小零件)
- 視圖風格
- 列表控件
-- 上拉加載更多
-- 下拉刷新
-- GuideView
- WebView控件
- AlertView
- iOS系統(tǒng)空間封裝
-- 拍照控件
-- 通訊錄
- 二維碼
- 語音
- 安全
- 支付
- 統(tǒng)計
- 日志
展現(xiàn)層
- 首頁
-- 訂閱
-- 掃描二維碼
-- 發(fā)布視頻
- 列表
-- 時間軸列表
--- Listview頭部封面
--- 外鏈情況Cell
--- 圖片Cell
--- 廣告插入Cell
--- 留言評論
--- 贊區(qū)域
-- 我的列表
-- 訂閱列表
-- 文章列表
- 詳細頁
-- 分享
-- 內(nèi)容區(qū)
-- 評論
- 登錄
-- 注冊
-- 登錄
-- 忘記密碼
-- 條款
-- 上傳頭像
-- 個人信息修改
基礎層中各個模塊上層可以使用類似CocoaPod或Cathage方式看尼,下一層再對其引用進行業(yè)務封裝递鹉。
這里注意最下層需要拆的粒度越細越好。減少橫向依賴藏斩。類似Common這樣的東西可以拆到基礎層的對應模塊里梳虽,比如說配置文件里和統(tǒng)計相關(guān)的放到基礎層的統(tǒng)計里,網(wǎng)絡相關(guān)的放到網(wǎng)絡里灾茁,顏色字體放到視圖風格里窜觉,不要都堆在一個文件里谷炸。再或者是各種第三方的Category也放到對應的組里,比如說UIView+Additions和UIColor+Expanded就放到視圖風格這個模塊中禀挫,不要專門搞個Category放所有的Category旬陡。
數(shù)據(jù)流控制模式MVC和MVCS/MVVM/VIPER的選擇
其實這些都是對MVC的擴展,只是擴展的方向不同而已语婴。VIPER把視圖和數(shù)據(jù)拆得過細變相增加了復雜度很多人也都不熟也沒有意愿去了解它的實現(xiàn)描孟,但是模塊復用卻達到了最優(yōu),MVCS是這幾個里對MVC優(yōu)化最簡單的只是把數(shù)據(jù)的存儲拆開了砰左。MVVM正好介于VIPER和MVCS之間匿醒,從ViewController里拆出來的ViewModel能夠?qū)?shù)據(jù)經(jīng)過邏輯處理用于View的顯示,View有操作用過ReactiveCocoa將信號傳給ViewModel來處理缠导。
如果是我個人選擇我會選擇VIPER廉羔,因為它更符合細粒度模塊劃分的思想。但是用在團隊多人開發(fā)上僻造,還是偏向MVVM這種折中方案憋他。MVVM按照先前對應用的結(jié)構(gòu)分層,會將View和ViewController放到展現(xiàn)層的最下面的兩層里髓削,將ViewModel和Model放到基礎層對應模塊的最下面一層中竹挡。最后要說的是無論選擇哪種,只要是按照減少ViewController大小立膛,將改胖的地方放到Model或View都是可以的揪罕,招式學多后最高境界就是無招勝有招嘛,有時也不需要刻板的在一個項目中將所有的模塊都按照統(tǒng)一的思路給框死宝泵,比如說一個模塊很簡單就用MVC好啰,一般復雜就用MVVM,要是項目本身業(yè)務非常龐大可以整體采用VIPER來進行ViewController的完全拆分鲁猩。
可以通過下列圖表看其中的不同:
名稱 邏輯和視圖 數(shù)據(jù)
MVC View + ViewController + Model
MVCS View + ViewController + Store + Model
MVVM View + ViewController + ViewModel + Model
VIPER View + ViewController + Wireframe + Presenter + Interactor + Data Manager + Entity(Model)
代碼規(guī)范
這塊最有權(quán)威的應該是蘋果自己提出的蘋果官方規(guī)范,按照這套來肯定是沒問題的罢坝,而且首先應該遵守廓握。代碼結(jié)構(gòu)主要根據(jù)不同團隊的經(jīng)驗來做。下面舉個我常用的代碼結(jié)構(gòu)
@property
...
#pragma mark - Life cycle
生命周期嘁酿,類似addSubview和Notification的監(jiān)聽和銷毀都放在這里
#pragma mark - Interface
接口
#pragma mark - Event response
#pragma mark - Private method
如果是ViewController隙券,這個地方就是瘦身的關(guān)鍵,業(yè)務和邏輯功能相關(guān)的就放到ViewModel里闹司。
#pragma mark - Delegate
代理
#pragma mark - Getters and Setters
建議所有的Property都設置娱仔,這樣修改配置會比較方便,看起來不會很混亂