iOS 中架構模式的淺顯理解

来源:http://www.cnblogs.com/v2m_/archive/2017/08/04/7282820.html
-Advertisement-
Play Games

我們開發軟體中應用各種模式,主要是為了 1. 職責劃分:一個類只做一件事 2. 易用,可維護,方便擴展 3. 解耦,相互獨立,可單獨測試 各種設計模式其實都是在解決上面的問題,讓我們對比看看吧。 一、如何理解MVC設計模式 在通常的定義中,MVC 是下圖的結構 但是在 cocoa 體系中,蘋果建議的 ...


我們開發軟體中應用各種模式,主要是為了

  1. 職責劃分:一個類只做一件事
  2. 易用,可維護,方便擴展
  3. 解耦,相互獨立,可單獨測試

各種設計模式其實都是在解決上面的問題,讓我們對比看看吧。

一、如何理解MVC設計模式

在通常的定義中,MVC 是下圖的結構

但是在 cocoa 體系中,蘋果建議的 MVC 模式如下圖所示

在斯坦福課程中,解釋的 MVC 如下圖所示

綜合一下在 cocoa 系統中可以這麼理解:

  • M model,存儲、定義、操縱數據
  • V view,用戶看到的UI,能夠和用戶交互
  • C controller,協調者,把 model 的數據放到 view 中展示,相應 view 的交互改變 model
    特別在 cocoa 系統中
    C 持有一個 model,直接操作 model;model 通過 KVO、通知等方式拋出自己改變的事件
    C 通過 IBOutlet 或者直接持有一個 view,他可以直接操作這個view;view 有了交互,可以通過action target 方式 以及 delegate 方式 讓 controller 來響應事件,但是 view 並不知道具體是哪個類對象;view 的需要的數據,可以通過 protocol 的方式,讓 controller 實現這個 protocol 並且成為 view 的數據源,來提供數據給 view,view並不需要知道 controller 的具體的類對象。

最簡單的例子就是 UITableviewController,他一般會持有一個 NSArray 作為 model,同時根視圖就是一個 UITableView,這是 view。controller 從網路或者本地載入數據賦值給 array,然後 reload tableview。tableview 繪製時請求數據源,相應用戶事件會通過delegate 發起調用。tableview 與 array 並沒有直接的關係。

進一步的,如果我的頁面很複雜,那麼這個 MVC 是怎麼處理的呢?看看斯坦福的另一張講義:

也就是 cocoa 中,Controlelr 控制的 view 可以是屬於別的 MVC 中的,最外層的 MVC 來管理這些子 MVC。所以最好不要一個 C 中對應多個 view 或者 model,而是需要拆分成多個 MVC 來。

缺點:

  1. 如果嚴格按照MVC模式的話,不像 view 傳遞 model,那麼代碼就會臃腫,想象往一個cell 設置用戶信息,單獨傳一個 userModel,然後 cell 內部處理會很簡潔,如果分開在controller 裡面傳 頭像、姓名、簽名,就會很臃腫
  2. view 和 controller 一般都是綁定在一起的,生命周期的控制依賴於 controller,獨立測試會很不方便

二、MVP 模式

基於 MVC 的缺點和優點,既然 view 和 cocoa 中的 viewController 已經那麼強的緊密耦合了,那麼把這兩者看成同一個東西,一起做為一個 view 。
Model 層負責數據的增刪改查(網路,資料庫查詢,本地文件讀寫)。
Presenter 層只是一個中介,負責數據的轉發。

上圖展示的是 View 持有 Presenter,Presenter 持有 Model。所以 Presenter 不依賴於具體的 View,這個可以通過 Protocol 來實現,讓 View 實現一些數據更新的協議,presenter 就可以不知道View 具體是什麼就能傳遞數據。

優點:
每一層的任務互相獨立分開了,讓測試更加方便。

** 缺點:**
代碼量會提升很多。

示例見參考2.參考2的複雜MVP可以簡化如下圖所示:

三、MVVM 模式

MVP 的 Presenter 需要主動更新 view,如果增加一個綁定機制呢,model 的改變及時反饋在 view上會不會更酷。但是這樣就會讓 model 和 view 關聯起來,所以就出來一個 viewModel 的東西。

ViewModel 持有 Model,管理 Model 並可以把 Model 中的數據處理成 View 需要的數據。同時可以處理用戶輸入驗證邏輯,視圖顯示邏輯,發起網路請求和其他各種各樣的代碼。
View 持有 ViewModel,並且和 ViewModel 中的數據綁定,讓 ViewModel 中的數據改變及時反應在 View上;並且把一些按鈕事件的 target 設置給 ViewModel。

優點:

  • View Model 的引入配合狀態流和響應式編程使得 App 的結構更加清晰,交互更加流暢。
  • MVVM 中的 View 責任多一點,因為要設置綁定,但也因為綁定,所以代碼量更少。測試時主要是測試 View Model 和 Model 。

缺點:
因為數據的雙向綁定,讓BUG的定位更加困難,過大的項目也會耗費更多的記憶體。

四、VIPER 模式

VIPER 其實是 MVP 的一種擴展,VP不變,M變成了 Interactor 和 Entity,外加一個 Routing。Entity 就是 model 的數據結構, Interactor 就是處理 model 的類,增刪改查model,Routing 就是控制視圖的跳轉。可以看到 viper 模式分的更細,每層的功能更明確,更容易測試。但是也更複雜,代碼量也會更加龐大。

可以參考下麵兩個圖結構圖。
圖一:

圖二:

參考1.https://www.objc.io/issues/13-architecture/mvvm/
參考2.https://github.com/amacou/MVPExample
參考3.https://www.objc.io/issues/13-architecture/viper/


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.通讀了下w3cschool上的簡介:CSS3 box-sizing 屬性_w3cschool。 2.看簡介理解的不夠深刻,偶屬於剛看完轉眼就能忘記的人。出於對自己的不放心,還是老老實實把例子拿到線下看看: <!DOCTYPE html> <html> <head> <meta charset=" ...
  • ————————————————————————————————————————————————————————— 文件拖選v1.0 圖片不清楚時請右鍵點擊"在新鏈接中打開圖片" 實現效果 頁面佈局 實現思路 拖選框 css樣式中設置拖選框樣式,註意設置position: absolute;漂浮狀態 ...
  • *{box-sizing:border-box;} 此情,容器元素css屬性必含overflow:hidden,不然會出問題 $(window).resize(()=>{ $('#willAdjustDiv').width($('#divContainer').width()); }) ; 記錄一下 ...
  • 概述: 身份證的校驗,識別,分離,處處可見。最近H5移動端的項目就需要掃碼獲取身份證,根據身份證自動識別省份、性別、年齡、生日信息。這裡分享完善版,希望大家喜歡。 環境: 依賴jQuery、BootStrap Html JavaScript:身份證驗證及自動識別部分 JavaScript:表單提交校 ...
  • //AJAX $.ajax({ url:"data.txt", type:'get', dataType:'json', data:null, async:true, timeout:1000,//設定超時時間 一般都是3000毫秒 cache:false,//設定GET請求的時候不走 緩存數據,原 ...
  • 這三個事件只在手機上生效 touchstart,手指開始觸屏 touchmove,手指移動 touchend,手指觸屏結束 這個事件在手機上跟在pc端都生效 scroll事件 addeventlistener(name,callback,optional,useCapture) useCapture ...
  • 所有方法基於這個數組: var arr=[1,3,4,5,6,7,8]; 1.length屬性: arr.length;//7 動態獲取數組長度. 2.shift: arr.shift();//1 刪除數組中第一個元素,返回刪除的那個值,並將長度減1;如:console.log(arr.shift( ...
  • 介紹一下 impress.js是一個非常炫酷的幻燈片展示框架,依靠CSS3技術。 impress.js使用起來非常簡單,下麵就來簡單介紹一下其用法。 Start 首先,當然要引入impress.js。 在div標簽設置id為impress(不要求一定是div),然後在你想進行展示的地方加上calss ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...