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地图