iOS MVVM架構總結

来源:https://www.cnblogs.com/jukaiit/archive/2018/12/14/10115682.html
-Advertisement-
Play Games

為什麼使用MVVM iOS中,我們使用的大部分都是MVC架構。雖然MVC的層次明確,但是由於功能日益的增加、代碼的維護,使得更多的代碼被寫在了Controller中,這樣Controller就顯得非常臃腫。為了給Controller瘦身,後來又從MVC衍生出了一種新的架構模式MVVM架構。 MVVM ...


 

為什麼使用MVVM

iOS中,我們使用的大部分都是MVC架構。雖然MVC的層次明確,但是由於功能日益的增加、代碼的維護,使得更多的代碼被寫在了Controller中,這樣Controller就顯得非常臃腫。
為了給Controller瘦身,後來又從MVC衍生出了一種新的架構模式MVVM架構。

MVVM分別指什麼

MVVM就是在MVC的基礎上分離出業務處理的邏輯到ViewModel層,即:

Model層:請求的原始數據
View層:視圖展示,由ViewController來控制
ViewModel層:負責業務處理和數據轉化

簡單來說,就是API請求完數據,解析成Model,之後在ViewModel中轉化成能夠直接被視圖層使用的數據,交付給前端(View層)。

MVVM與MVC的不同

首先我們簡化一下MVC的架構模式圖:

 

 

 

在這裡,Controller需要做太多得事情,表示邏輯、業務邏輯,所以代碼量非常的大。而MVVM:

 

 

 

 

MVVM的實現

比如我們有一個需求:一個頁面,需要判斷用戶是否手動設置了用戶名。如果設置了,正常顯示用戶名;如果沒有設置,則顯示“博客園0122”這種格式。(雖然這些本應是伺服器端判斷的)
我們看看MVC和MVVM兩種架構都是怎麼實現這個需求的

MVC:

Model類:

#import <Foundation/Foundation.h>

@interface User : NSObject

@property (nonatomic, copy) NSString *userName;
@property (nonatomic, assign) NSInteger userId;

- (instancetype)initWithUserName:(NSString *)userName userId:(NSInteger)userId;

@end
@implementation User

- (instancetype)initWithUserName:(NSString *)userName userId:(NSInteger)userId {
    self = [super init];
    if (!self) return nil;
    _userName = userName;
    _userId   = userId;
    return self;
}

@end

 

ViewController類:

#import "HomeViewController.h"
#import "User.h"

@interface HomeViewController ()

@property (nonatomic, strong) UILabel *lb_userName;
@property (nonatomic, strong) User *user;

@end
@implementation HomeViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    //創建User實例並初始化
    if (_user.userName.length > 0) {
        _lb_userName.text = _user.userName;
    } else {
        _lb_userName.text = [NSString stringWithFormat:@"博客園%ld", _user.userId];
    }
}

@end

 

這裡我們需要將表示邏輯也放在ViewController中。

MVVM:

Model類:

#import <Foundation/Foundation.h>

@interface User : NSObject

@property (nonatomic, copy) NSString *userName;
@property (nonatomic, assign) NSInteger userId;

@end

 

ViewModel類:

聲明:

#import <Foundation/Foundation.h>
#import "User.h"

@interface UserViewModel : NSObject

@property (nonatomic, strong) User *user;
@property (nonatomic, copy) NSString *userName;

- (instancetype)initWithUserName:(NSString *)userName userId:(NSInteger)userId;

@end

 

實現:

#import "UserViewModel.h"

@implementation UserViewModel

- (instancetype)initWithUserName:(NSString *)userName userId:(NSInteger)userId {
    self = [super init];
    if (!self) return nil;
    _user = [[User alloc] initWithUserName:userName userId:userId];
    if (_user.userName.length > 0) {
        _userName = _user.userName;
    } else {
        _userName = [NSString stringWithFormat:@"博客園%ld", _user.userId];
    }
    return self;
}

@end

 

Controller類:

#import "HomeViewController.h"
#import "UserViewModel.h"

@interface HomeViewController ()

@property (nonatomic, strong) UILabel *lb_userName;
@property (nonatomic, strong) UserViewModel *userViewModel;

@end
@implementation HomeViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    _userViewModel = [[UserViewModel alloc] initWithUserName:@"liu" userId:123456];
    _lb_userName.text = _userViewModel.userName;
}

@end

 

可見,Controller中我們不需要再做多餘的判斷,那些表示邏輯我們已經移植到了ViewModel中,ViewController明顯輕量了很多。說白了,就是把原來ViewController層的業務邏輯和頁面邏輯等剝離出來放到ViewModel層。

總結:

  • MVVM同MVC一樣,目的都是分離Model與View,但是它更好的將表示邏輯分離出來,減輕了Controller的負擔;
  • ViewController中不要引入Model,引入了就難免會在Controller中對Model做處理;
  • 對於很簡單的界面使用MVVM會增加代碼量,但如果界面中內容很多、Cell樣式也很多的情況下使用MVVM可以很好地將VC中處理Cell相關的工作分離出來。

寫到這裡,MVVM基本上就算結束了。重要的還是去實踐,在實踐中檢驗真理。




https://www.jianshu.com/p/f1d0f7f01130

 


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

-Advertisement-
Play Games
更多相關文章
  • 下載需要的版本的xtrabackup軟體包,鏈接如下: https://www.percona.com/downloads/XtraBackup/LATEST/ percona-xtrabackup-8.0.4只支持mysql8.0及以上版本備份,如果想備份8.0以下版本MySQL,需要下載perc ...
  • 恢復內容開始 ODI流程 Topology 1、建立 源 物理結構體系 2、建立 目的 物理結構體系 步驟同上 3、建立 源 邏輯架構 4、建立 目的 邏輯架構 步驟同上 Designer 5、建立 源 模型 點擊 6、建立 目的 模型 步驟同上 7、建立項目 8、 導入模塊 路徑為 :F:\Ora ...
  • 1 /*修改欄位類型*/ 2 alter table 表名 ALTER COLUMN 列名 nvarchar(500) 3 go 4 /*增加欄位和說明*/ 5 alter table 表名 add 列名 nvarchar(50) 6 EXECUTE sp_addextendedproperty N... ...
  • map reduce的解釋 這是一張來自mongodb mapreduce圖示,比較能說明問題 其實我們可以從word count這個實例來理解MapReduce。MapReduce大體上分為六個步驟:input, split, map, shuffle, reduce, output。細節描述如下 ...
  • 本文簡述在Android開發中佈局的簡單應用,屬於基礎知識,僅供學習分享使用。 ...
  • android底部增加背景 底部陰影寬度為1,若是左邊右邊上邊需要陰影按照這個方法加上left,right,top就好了 ...
  • 在ObjC中,什麼是深淺拷貝? 深淺拷貝分別指深拷貝和淺拷貝,即 mutableCopy 和 copy 方法。 copy複製一個不可變對象,而 mutableCopy 複製一個 mutable 可變對象。 非容器類對象 如NSString,NSNumber等一類對象 示例1: 查看記憶體可以發現,st ...
  • 概述 從前面的博文我們也可以看到,數組和字典中只能存儲對象類型,其他基本類型和結構體是沒有辦法放到數組和字典中的,當然你也是無法給它們發送消息的也就是說有些NSObject的方法是無法調用的,這個時候通常會用到裝箱boxing和拆箱unboxing。 其實各種高級語言基本上都有裝箱和拆 箱的過程,例 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...