MVVM

緒論

以前在項(xiàng)目中大家都很喜歡使用的MVC模式,MVC即Model-VIew-Controller。他是1970年代被引入到軟件設(shè)計(jì)大眾的。MVC模式致力于關(guān)注點(diǎn)的切分,這意味著model和controller的邏輯是不與用戶界面(View)掛鉤的。因此,維護(hù)和測試程序變得更加簡單容易。

MVC

MVC設(shè)計(jì)模式將應(yīng)用程序分離為3個(gè)主要的方面:Model,View和Controller。

MVC
  • Model
    Model代表了描述業(yè)務(wù)路邏輯,業(yè)務(wù)模型、數(shù)據(jù)操作、數(shù)據(jù)模型的一系列類的集合。這層也定義了數(shù)據(jù)修改和操作的業(yè)務(wù)規(guī)則。
  • View
    View代表了UI組件,像CSS,jQuery,html等。他只負(fù)責(zé)展示從controller接收到的數(shù)據(jù)。也就是把model轉(zhuǎn)化成UI。
  • Controller
    Controll負(fù)責(zé)處理流入的請求。它通過View來接受用戶的輸入,之后利用Model來處理用戶的數(shù)據(jù),最后把結(jié)果返回給View。Controll就是View和Model之間的一個(gè)協(xié)調(diào)者。

MVVM:

MVVM是MVC思想的完全變革。它是將“數(shù)據(jù)模型數(shù)據(jù)雙向綁定”的思想作為核心,因此在View和Model之間沒有聯(lián)系,通過ViewModel進(jìn)行交互,而且Model和ViewModel之間的交互是雙向的,因此視圖的數(shù)據(jù)的變化會同時(shí)修改數(shù)據(jù)源,而數(shù)據(jù)源數(shù)據(jù)的變化也會立即反應(yīng)到View上。


MVVM
  • 用戶和View交互。
  • View和ViewModel是多對一關(guān)系。意味著一個(gè)ViewModel只映射多個(gè)View。
  • View持有ViewModel的引用,但是ViewModel沒有任何View的信息。
  • View 和ViewModel之間有雙向數(shù)據(jù)綁定關(guān)系。

為什么使用MVVM

在 iOS 上使用 MVVM 的動(dòng)機(jī),就是它能減少 View Controller 的復(fù)雜性并使得表示邏輯更易于測試。通過一些例子,我們將看到它如何達(dá)到這些目標(biāo)。

  • MVVM 可以兼容你當(dāng)下使用的 MVC 架構(gòu)。
  • MVVM 增加你的應(yīng)用的可測試性。
  • MVVM 配合一個(gè)綁定機(jī)制效果最好。

注:MVVM 基本上就是 MVC 的改進(jìn)版,所以很容易就能看到它如何被整合到現(xiàn)有使用典型 MVC 架構(gòu)的應(yīng)用中。讓我們看一個(gè)簡單的 Person Model 以及相應(yīng)的 View Controller:

@interface Person : NSObject

- (instancetype)initwithSalutation:(NSString *)salutation firstName:(NSString *)firstName lastName:(NSString *)lastName birthdate:(NSDate *)birthdate;

@property (nonatomic, readonly) NSString *salutation;
@property (nonatomic, readonly) NSString *firstName;
@property (nonatomic, readonly) NSString *lastName;
@property (nonatomic, readonly) NSDate *birthdate;

@end

接著我們?nèi)?chuàng)建一個(gè)PersonViewController ,在 viewDidLoad 里,只需要基于它的 model 屬性設(shè)置一些 Label 即可。

- (void)viewDidLoad {
    [super viewDidLoad];

    if (self.model.salutation.length > 0) {
        self.nameLabel.text = [NSString stringWithFormat:@"%@ %@ %@", self.model.salutation, self.model.firstName, self.model.lastName];
    } else {
        self.nameLabel.text = [NSString stringWithFormat:@"%@ %@", self.model.firstName, self.model.lastName];
    }

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"EEEE MMMM d, yyyy"];
    self.birthdateLabel.text = [dateFormatter stringFromDate:model.birthdate];
}

以上就是標(biāo)準(zhǔn)的 MVC?,F(xiàn)在來看看我們?nèi)绾斡靡粋€(gè) View Model 來增強(qiáng)它。首先創(chuàng)建一個(gè)PersonViewModel。

@interface PersonViewModel : NSObject

- (instancetype)initWithPerson:(Person *)person;

@property (nonatomic, readonly) Person *person;

@property (nonatomic, readonly) NSString *nameText;
@property (nonatomic, readonly) NSString *birthdateText;

@end

View Model 的具體實(shí)現(xiàn)大概如下:

@implementation PersonViewModel

- (instancetype)initWithPerson:(Person *)person {
    self = [super init];
    if (!self) 
    return nil;
    _person = person;
    if (person.salutation.length > 0) {
        _nameText = [NSString stringWithFormat:@"%@ %@ %@", self.person.salutation, self.person.firstName, self.person.lastName];
    } else {
        _nameText = [NSString stringWithFormat:@"%@ %@", self.person.firstName, self.person.lastName];
    }

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"EEEE MMMM d, yyyy"];
    _birthdateText = [dateFormatter stringFromDate:person.birthdate];

    return self;
}

@end

此時(shí)的我們已經(jīng)將 viewDidLoad 中的表示邏輯放入我們的 View Model 里了。此時(shí),我們新的 viewDidLoad 就會非常輕量:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.nameLabel.text = self.viewModel.nameText;
    self.birthdateLabel.text = self.viewModel.birthdateText;
}

因此,MVVM并沒有對我們的 MVC 架構(gòu)做太多改變。還是同樣的代碼,只不過移動(dòng)了位置。它與 MVC 兼容,帶來更輕量的 View Controllers。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容