iOS-设计模式(MVC、MVP、MVVM)
App开发过程中,随着业务的不断发展,代码和逻辑不断增加,有时候不得不重构以前的代码,好的架构,决定了代码的易用性、可扩展性、可维护性、可读性以及健壮性等等,利于代码的拓展和重构,下面就简单探讨一下iOS中常见的设计模式吧。
本文中主要介绍三种设计模式MVC、MVP、MVVM
一、MVC模式
Models: 数据层,负责数据的处理和获取的数据接口层。
Views:展示层,即UI层(实际开发中也是业务模型)。
Controller: 控制器层,它是 Model 和 View 之间的桥梁。当用户对 View 有操作时它负责去修改相应 Model;当 Model 的值发生变化时它负责去更新对应 View。
![](https://img.haomeiwen.com/i1672235/1b2a26d95611a313.jpg)
优点: 对Controller进行瘦身,将View内部的细节封装起来。
缺点: View依赖于Model,没有区分业务逻辑和业务展示
。
MVC核心代码:
// 1.controller类
@implementation MVCViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 创建view
MVCHeaderView *headView = [[MVCHeaderView alloc] init];
headView.frame = CGRectMake(100, 100, 100, 150);
headView.mvcDelegate = self;
[self.view addSubview:headView];
// 加载模型数据
MVCModel *model = [[MVCModel alloc] init];
model.name = @"翀鹰精灵";
model.image = @"header";
// 设置数据到view上
headView.mvcModel = model;
}
#pragma mark - MJAppViewDelegate
- (void)viewDidClick:(MVCHeaderView *)headView {
NSLog(@"控制器监听到了appView的点击");
}
@end
// 2.view类
//2.1 MVCHeaderView.h
@class MVCHeaderView,MVCModel;
@protocol MVCViewDelegate <NSObject>
@optional
-(void)viewDidClick:(MVCHeaderView*)headView;
@end
@interface MVCHeaderView : UIView
@property (nonatomic, strong) MVCModel * mvcModel;
@property (nonatomic, weak) id<MVCViewDelegate> mvcDelegate;
@end
//2.2 MVCHeaderView.m
@interface MVCHeaderView()
@property (weak, nonatomic) UIImageView *iconView;
@property (weak, nonatomic) UILabel *nameLabel;
@end
@implementation MVCHeaderView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
UIImageView *iconView = [[UIImageView alloc] init];
iconView.frame = CGRectMake(0, 0, 100, 100);
[self addSubview:iconView];
_iconView = iconView;
UILabel *nameLabel = [[UILabel alloc] init];
nameLabel.frame = CGRectMake(0, 100, 100, 30);
nameLabel.textAlignment = NSTextAlignmentCenter;
[self addSubview:nameLabel];
_nameLabel = nameLabel;
}
return self;
}
- (void)setMvcModel:(MVCModel *)mvcModel {
_mvcModel = mvcModel;
self.iconView.image = [UIImage imageNamed:mvcModel.image];
self.nameLabel.text = mvcModel.name;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
if ([self.mvcDelegate respondsToSelector:@selector(viewDidClick:)]) {
[self.mvcDelegate viewDidClick:self];
}
}
@end
// 3.model类
@interface MVCModel : NSObject
@property (copy, nonatomic) NSString *name;
@property (copy, nonatomic) NSString *image;
@end
二、MVP模式
MVP 架构模式是 MVC 的一个变种,MVC 与 MVP 之间的区别其实并不明显,作者认为两者之间最大的区别就是 MVP 中使用 Presenter 对视图和模型进行了解耦,它们彼此都对对方一无所知,沟通都通过 Presenter 进行。
MVP 中,Presenter 可以理解为松散的控制器,其中包含了视图的 UI 业务逻辑。
MVP核心代码:
// 1.controller类
#import "MVPViewController.h"
#import "MVPHeaderPresenter.h"
@interface MVPViewController ()
@property (strong, nonatomic) MVPHeaderPresenter *presenter;
@end
@implementation MVPViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.presenter = [[MVPHeaderPresenter alloc] initWithController:self];
}
@end
// 2.view类 复用MVC中view类
// 3.Presenter类
//3.1 MVPHeaderPresenter.h
#import <UIKit/UIKit.h>
@interface MVPHeaderPresenter : NSObject
- (instancetype)initWithController:(UIViewController *)controller;
@end
//3.2 MVPHeaderPresenter.m
#import "MVPHeaderPresenter.h"
#import "MVPHeaderView.h"
#import "MVPModel.h"
@interface MVPHeaderPresenter() <MVPViewDelegate>
@property (weak, nonatomic) UIViewController *controller;
@end
@implementation MVPHeaderPresenter
- (instancetype)initWithController:(UIViewController *)controller {
if (self = [super init]) {
self.controller = controller;
// 创建View
MVPHeaderView *headView = [[MVPHeaderView alloc] init];
headView.frame = CGRectMake(100, 100, 100, 150);
headView.mvpDelegate = self;
[controller.view addSubview:headView];
// 加载模型数据
MVPModel *model = [[MVPModel alloc] init];
model.name = @"【MVP】翀鹰精灵";
model.image = @"header";
// 赋值数据
[headView setName:model.name andImage:model.image];
}
return self;
}
@end
三、MVVM模式
MVVM由三个部分组成,也就是 Model、View 和 ViewModel;其中视图模型(ViewModel)和View进行了一个双向绑定.
MVVM核心代码:
// 1.controller类
#import "MVVMViewController.h"
#import "MVVMViewModel.h"
@interface MVVMViewController ()
@property (strong, nonatomic) MVVMViewModel *viewModel;
@end
@implementation MVVMViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.viewModel = [[MVVMViewModel alloc] initWithController:self];
}
@end
// 2.view类
- (void)setMvvmModel:(MVVMViewModel *)mvvmModel {
_mvvmModel = mvvmModel;
__weak typeof(self) waekSelf = self;
[self.KVOController observe:mvvmModel keyPath:@"name" options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary<NSKeyValueChangeKey,id> * _Nonnull change) {
waekSelf.nameLabel.text = change[NSKeyValueChangeNewKey];
}];
[self.KVOController observe:mvvmModel keyPath:@"image" options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary<NSKeyValueChangeKey,id> * _Nonnull change) {
waekSelf.iconView.image = [UIImage imageNamed:change[NSKeyValueChangeNewKey]];
}];
}
// 3.viewModel类
@implementation MVVMViewModel
- (instancetype)initWithController:(UIViewController *)controller {
if (self = [super init]) {
self.controller = controller;
// 创建View
MVVMHeaderView *headView = [[MVVMHeaderView alloc] init];
headView.frame = CGRectMake(100, 100, 200, 150);
headView.mvvmModel = self;
headView.mvvmDelegate = self;
[controller.view addSubview:headView];
// 加载模型数据
MVVMModel *model = [[MVVMModel alloc] init];
model.name = @"【MVVM】翀鹰精灵";
model.image = @"header";
self.name = model.name;
self.image = model.image;
}
return self;
}
#pragma mark - MJAppViewDelegate
- (void)mvvmViewDidClick:(MVVMHeaderView *)appView {
NSLog(@"viewModel 监听了 appView 的点击");
self.name = @"变化中的【mvvm】";
self.image = @"header";
}
@end
最后,没有最好的,适合项目的才是最好的架构。
Demo下载.