iOS架构模式——MV(X)的懂得以及实战

iOS架构模式——MV(X)的懂得以及实战

作一个iOS程序员,MVC一定是我们熟悉的同等种架构模式,而且当您的种规模不生的时候,MVC也真正发它们的优势,它的开支效率真的是十足大。但当您的档次提高的一定的圈,你会意识传统的MVC模式会招致C层代码量剧增,维护困难等一样层层问题,这个时节我们就是得考虑部分别模式了。

MV(X)的基本要素

常用的架模式

  • MVC
  • MVVM
  • MVP
  • VIPER

前面三栽模式还由三独模块组合:

  • Models —— 数据层,负责数据的拍卖。
  • Views —— 展示层,即具备的UI
  • Controller/Presenter/ViewModele(控制器/展示器/视图模型)——它们背负View与Mode之间的调遣

MVC

传统的MVC

咱俩所熟悉的MVC其实Apple给咱们提供的Cocoa
MVC,但事实上MVC最优先有于Web,它原先的规范应该是这么的

澳门新葡亰官网 1

传统MVC

当这种架构下,View是无状态的,在Model变化之时段她只是略的受Controller重绘,比如网页中你点击了一个初的链接,整个页面就再也加载。尽管这种MVC在iOS应该里面可以兑现,但是由于MVC的老三单模块都紧紧耦合了,每一个模块都同另外少种植模块出关联,所以尽管是贯彻了为从未啊意思。这种耦合还降低了它的只是重用性,所以,传统的MVC在iOS中可以放弃了。

Apple的MVC

澳门新葡亰官网 2

Cocoa MVC

Apple提供的MVC中,View和Model之间是彼此独立的,它们才经Controller来互沟通。可惜的是Controller得重用性太差,因为我们一般还将乱的作业逻辑在了Controller中。

具体中,我们的MVC一般是这般的

澳门新葡亰官网 3

现实MVC

为何会这样啊?主要还是以我们的UIViewController它自身就是有着一个VIew,这个View是兼具视图的根视图,而且View的生命周期也还由Controoler负责管理,所以View和Controller是深麻烦就互相独立的。虽然你可以将控制器里之一对事情逻辑和数据易工作授Model,但是若倒是绝非艺术用部分做事被View来分担,因为View的主要职责只是用用户之操作行为付出Controller去处理而已。于是Controller最终便改为了颇具东西的代办和数据源,甚至还发生网络要求…..还有……所以我们刻画的Controller代码量一般还是特别可怜之,随着当事情需的增,Controller的代码量会一直加强,而相对来说View同Model的代码量就比较稳定,所以呢有人把MVC叫做Massive
View Controller,因为Controller确实显示有些臃肿。

每当这边关于Model的剪切,其实有一个肥胖Model和薄Model之分,它们的别主要就是把Controller的片数据处理职责交给了肥胖Model。

胖Model(Fat Model):

胖Model包含了一部分弱业务逻辑。胖Model要上的目的是,Controller从肥胖Model这里拿到数码后,不用做额外之操作还是单开老少的操作就能用数据利用在View上。
FatModel做了这些已故业务后,Controller可以变得相对skinny一点,它才待关怀大业务代码。而强业务转移的可能性要于死业务特别得几近,弱业务相对安静,所以弱业务塞给Model不会见生极其特别题目。另一方面,弱业务重新出现的效率要盖强业务,对复用性要求还胜,如果就片事情形容以Controller,会招代码冗余,类似的代码会落得四处都是,而且只要弱业务发修改,你就是会需要改所有地方。如果塞到了Model中,就只是需要转移Model就足足了。
然胖Mpdel也未是就是没缺陷的,它的缺陷就是在于胖Model相对比较为难移植,虽然光是包含弱业务,但是其毕竟也是业务,迁移的时刻大容易拔出罗布带起泥,也就是说它耦合了她的作业。而且软件是会成长之,FatModel也殊有或乘软件的成长更Fat,最后难以维护。

瘦Model(Slim Model):

瘠Model只担负作业数据的发挥,所有业务无论强弱一律总人口受Controller。瘦Model要达到的目的是,尽一切可能夺编写精心粒度Model,然后配套各种helper类或者措施来对死去业务做抽象,强业务还交给Controller。
由Slim
Model跟工作了无关,它的数足以交到其他一个能够处理它数的Helper或其他的目标,来成功业务。在代码迁移的上独立性很强,很少会面世拔出萝卜带出泥的情事。另外,由于SlimModel只是数量表达,对它进行保障基本上是0成本,软件膨胀得又决定,SlimModel也无见面那个及哪里去。缺点就在,Helper这种做法呢掉得那个好,由于Model的操作会产出于各种地方,SlimModel很爱出现代码重复,在早晚水准及负了DRY(Don’t
Repeat
Yourself)的笔触,Controller仍然不可避免在必然水平达冒出代码膨胀。

概括,Cocoa MVC在各级面的变现如下:

  • 划分 – View 和 Model 确实是落实了分别,但是 View 和 Controller
    耦合的太 厉害
  • 可测性 – 因为划分的不够理解,所以能测的为主就惟有 Model 而曾
  • 易用
    相较于任何模式,它的代码量最少。而且基本上每个人都异常熟稔她,即便是未曾尽多经历的开发者也克维护。

MVP

澳门新葡亰官网 4

MVP

关押起和Cocoa
MVC很像,也实在特别像。但是,在MVC中View和COntroller是紧密耦合的,而于MVP中,Presenter完全不关心ViewController的生命周期,而且View也克让概括mock出来,所以当Presenter里面基本无呀布局相关的代码,它的职责只是经过数量及状态更新View。
还要于MVP中,UIVIewController的那些子类其实是属View的。这样便提供了又好之可测性,只是开发进度会更胜,因为您必须手动去创造数量与绑定事件。

下我写了单简易的Demo

澳门新葡亰官网 5

MVPDemo

是因为这里要是读书架构模式思想,所以我之命名简单粗暴,希望大家懂得。

澳门新葡亰官网 6

界面1

界面也非常简单,就是通过点击按钮修改两只label显示的情

Model很简单,就是一个数据结构,但当骨子里利用被,你可用网络要等部分数额处理在这里

@interface Model : NSObject

@property (nonatomic, strong) NSString *first;
@property (nonatomic, strong) NSString *second;

@end

假如受Presenter和View通信,所以我们定义一个说道,以贯彻Presenter向View发送命令

@protocol MyProtocol <NSObject>

- (void)setFirst:(NSString *)first;
- (void)setSecond:(NSString *)second;

@end

view/VIewController,实现该协议

.h
 @interface ViewController : UIViewController

@property (nonatomic, strong) UILabel *firstLabel;
@property (nonatomic, strong) UILabel *secondLabel;
@property (nonatomic, strong) UIButton *tapButton;

@end


.m主要代码
- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.firstLabel];
    [self.view addSubview:self.secondLabel];
    [self.view addSubview:self.tapButton];
    self.presenter = [Presenter new];
    [self.presenter attachView:self];
}

- (void)buttonClicked{
    [self.presenter reloadView];
}

- (void)setFirst:(NSString *)first{
    self.firstLabel.text = first;
}

- (void)setSecond:(NSString *)second{
    self.secondLabel.text = second;
}

Presenter

.h
@interface Presenter : NSObject

- (void)attachView:(id <MyProtocol>)attachView;
- (void)reloadView;

@end


.m
@interface Presenter()

@property (nonatomic, weak) id <MyProtocol> view;
@property (nonatomic, strong) Model *model;

@end

@implementation Presenter

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.model = [Model new];
        self.model.first = @"first";
        self.model.second = @"second";
    }
    return self;
}

- (void)attachView:(id<MyProtocol>)attachView{
    self.view = attachView;
}

- (void)reloadView{
    //可以在这里做一些数据处理
    [self.view setFirst:self.model.first];
    [self.view setSecond:self.model.second];
}
@end

此只有是一个简单的Demo,其实想很简短,就是说话业务逻辑交给Presenter,而Presenter以命的款式来支配View。
完整Demo可以看这里

部分证明:

MVP架构拥有三单真独立的支行,所以在组装的时候会发生一对题目,而MVP也成为了第一个披露这种题材的架,因为我们不思叫View知道Model的音讯,所以当脚下底Controller去组装是勿正确的,我们该以另外的地方就组建。比如我们得创造一个应用层的Router服务,让其来当组建和View-to-View的转场。这个题目下过多模式受到还有。

下总结一下MVP的每方面呈现:

  • 划分——我们拿大部分任务都分配到了Presenter和Model里面,而View基本无需开啊
  • 可测性——我们得以经过View来测试大部分事务逻辑
  • 易用——代码量差不多是MVC架构的少倍,但是MVP的笔触要非常清晰的

除此以外,MVP还有一个变体,它的两样主要就是是互补加了数据绑定。这个版的MVP的View和Model直接绑定,而Presenter仍然连续处理View上之用户操作,控制View的来得变化。这种架构和传统的MVC类似,所以我们着力可舍。

MVVM

MVVM可以说凡是MV(X)系列被新型兴起之为是最最良好之一模一样栽架构,而它也广受我们iOS程序员喜爱。

澳门新葡亰官网 7

MVVM

MVVM和MVP很像:

  • 把ViewController看成View
  • View和Model之间无紧耦合

此外它还吃VIew和ViewModel做了数绑定。ViewModel可以调用对Model做更改,也足以重Model更新的时节对本身进行调,然后经过View和ViewModel之间的绑定,对View进行对应的翻新。

关于绑定

在iOS平台方面有KVO和通知,但是就此起总是认为无绝方便,所以有一对叔着库供我们捎:

  • 据悉KVO的绑定库,如
    RZDataBinding
    或者
    SwiftBond
  • 使用全量级的
    函数式响应编程
    框架,比如ReactiveCocoaRxSwift
    或者PromiseKit

实际上,我们在干MVVM的时光就是很易想到ReactiveCocoa,它呢是我们当iOS中以MVVM的极端好工具。但是相对来说它的习成本和护卫成本
也是比较强之,而且如果您下不当,很可能造成灾难性的问题。

下我暂时不用RAC来概括展示一下MVVM:

澳门新葡亰官网 8

MVVM

界面很粗略,就是点击一个button修改label里面的数量

澳门新葡亰官网 9

界面

Model

@interface MVVMModel : NSObject

@property (nonatomic, copy) NSString *text;

@end

@implementation MVVMModel

- (NSString *)text{
    _text = [NSString stringWithFormat:@"newText%d",rand()];
    return _text;
}

ViewModel

@interface MVVMViewModel : NSObject

- (void)changeText;

@end

@interface MVVMViewModel()

@property (nonatomic, strong) NSString *text;
@property (nonatomic, strong) MVVMModel *model;

@end

@implementation MVVMViewModel

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.model = [MVVMModel new];
    }
    return self;
}

- (void)changeText{
    self.text = self.model.text;;
}

Controller

@interface MVVMViewController ()

@property (weak, nonatomic) IBOutlet UILabel *textLabel;
@property (nonatomic, strong) MVVMViewModel *viewModel;

@end

@implementation MVVMViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.viewModel = [[MVVMViewModel alloc]init];
    [self.viewModel addObserver:self forKeyPath:@"text" options:NSKeyValueObservingOptionNew context:nil];
}
- (IBAction)buttonClicked:(UIButton *)sender {
    [self.viewModel changeText];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    self.textLabel.text = change[@"new"];
}

MVVM的核心就是View和ViewModel的一个绑定,这里我只是略的经KVO实现,看起并无是那优雅,想使深度应用的语句我觉得还是发必不可少学习一下RAC底,需要完整的Demo请看这里。

下面我们又来针对MVVM的诸面呈现做一个品:

  • 划分——MVVM 框架内的 View 比 MVP
    里面负责的业务若重复多片。因为前者是经 ViewModel
    的数量绑定来更新自己状态的,而后者只是把所有的波都付给 Presenter
    去处理便结了,自己本身并无负担更新。
  • 可测性—— 因为 ViewModel 对 View
    是未知的,这样我们对它的测试就变得要命粗略。View
    应该吗是会为测试的,但是或许以它们对 UIKit
    的依,你会直接略过她。
  • 易用——它比MVP会更加从简,因为在 MVP 下你必要将 View
    的具备事件都交 Presenter 去处理,而且需要手动的失创新 View
    的状态;而以 MVVM 下,你仅仅需要用绑定就好缓解。

综上:MVVM
真的那个有魅力,因为她不光结了上述几种框架的亮点,还未欲而也视图的换代去形容额外的代码(因为在
View 上曾经召开了数绑定),另外它们当可测性上的表现吧仍很过硬。

以简单容易亮,以上的Demo都不行简洁,不明了看了这首博客能否加深你针对MV(X)的一些理解,这些理解呢只看成自身个人的部分参考,有啊尴尬的地方希望大家指出。

admin

网站地图xml地图