前言
之前写程序的时候我们都是自己随意的进行文件的划分与完成,对整个项目的结构的设计没有成熟且完整的结构。今天就来说一下一个最经典的架构模式。MVC(Model-View-Controller)架构模式。
MVC各层级
由名字我们就能知道,MVC一共有三层,即Model,View和Controller
在这种模式中的交互的流程:
- 用户点击View - 视图响应事件
- 用代理传递事件到Controller - 发起网络请求更新数据层Model
- Model处理完数据 - 代理或通知给Controller
- 最后改变视图的样式,整个流程结束
Model层
模型层,负责处理数据以及处理部分的业务逻辑,如存放数据结构,网络请求等
常见自定义类或进行网络请求结果的封装对象
View层
即视图层,负责对数据的展示和事件的捕捉,一般来说,在屏幕上看到的各种组件都可以归类为View
Controller层
例如典型的UIViewController,主要负责协调Model和View,处理大部分的逻辑
- 从Model取数据 - 更新View
- 接受用户操作 - 更新数据层Model
各个层级的关系图示:
优缺点
优点:有了明确的组织方式,用Controller来控制全局,同时把View与Model的变化分隔开
缺点:会有大量逻辑方面的代码放进Controller层,导致其会越来越臃肿,后期维护成本高
示例代码
下面是一个非常简单的一个用MVC模式写的登录界面,文件部分
#import "LoginVC.h"
#import "LoginModel.h"
#import "LoginView.h"
@interface LoginVC ()
@property(nonatomic, strong)LoginModel *loginModel;
@property(nonatomic, strong)LoginView *loginView;
@property(nonatomic, strong)UIAlertController *alert;
@end
@implementation LoginVC
- (void)viewDidLoad {
[super viewDidLoad];
self.loginView = [[LoginView alloc] initWithFrame: self.view.frame];
[self.loginView initView];
[self.view addSubview: self.loginView];
self.loginModel = [[LoginModel alloc] init];
[self.loginModel initLoginModel];
[self.loginView.loginBtn addTarget: self action: @selector(login) forControlEvents: UIControlEventTouchUpInside];
}
- (void)login {
BOOL islogin = NO;
for (int i = 0; i < self.loginModel.accountArray.count; i++) {
if ([self.loginModel.accountArray[i] isEqualToString:self.loginView.acctextfield.text] &&
[self.loginModel.passwordArray[i] isEqualToString:self.loginView.passtextfield.text]) {
islogin = YES;
break;
}
}
if (islogin == YES) {
self.alert = [UIAlertController alertControllerWithTitle: @"提示" message: @"登录成功" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *defaultAction = [UIAlertAction actionWithTitle: @"确认" style: UIAlertActionStyleDefault handler: nil];
[self.alert addAction: defaultAction];
[self presentViewController: self.alert animated: YES completion: nil];
} else {
self.alert = [UIAlertController alertControllerWithTitle: @"提示" message: @"用户名或者密码错误" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *defaultAction = [UIAlertAction actionWithTitle: @"确认" style: UIAlertActionStyleDefault handler: nil];
[self.alert addAction: defaultAction];
[self presentViewController: self.alert animated: YES completion: nil];
}
}
#import "LoginModel.h"
@implementation LoginModel
- (void)initLoginModel {
self.accountArray = [[NSMutableArray alloc] init];
self.passwordArray = [[NSMutableArray alloc] init];
[self.accountArray addObject: @"123456"];
[self.passwordArray addObject: @"654321"];
}
@end
#import "LoginView.h"
@implementation LoginView
- (void)initView {
self.backgroundColor = [UIColor whiteColor];
self.acctextfield = [[UITextField alloc] init];
self.acctextfield.frame = CGRectMake(50, 80, 300, 40);
self.acctextfield.placeholder = @"请输入账号";
self.acctextfield.borderStyle = UITextBorderStyleRoundedRect;
[self.acctextfield becomeFirstResponder];
[self addSubview: self.acctextfield];
self.passtextfield = [[UITextField alloc] init];
self.passtextfield.frame = CGRectMake(50, 130, 300, 40);
self.passtextfield.placeholder = @"请输入密码";
self.passtextfield.borderStyle = UITextBorderStyleRoundedRect;
[self.passtextfield becomeFirstResponder];
[self addSubview: self.passtextfield];
self.loginBtn = [UIButton buttonWithType: UIButtonTypeSystem];
self.loginBtn.frame = CGRectMake(140, 190, 80, 30);
[self.loginBtn setTitle: @"登录" forState: UIControlStateNormal];
[self addSubview: self.loginBtn];
}
@end
运行结果
总结
MVC模式(官方推荐,缺点是Controller容易臃肿)
Model:数据和业务逻辑
View:界面展示
Controller:桥梁,负责把 Model 的数据提供给 View,同时处理用户输入
MVP模式(Model - View - Presenter)
Model:数据和业务逻辑
View:只负责显示,不处理逻辑
Presenter:从 Model 获取数据,处理后再交给 View 显示;View 的交互也通过 Presenter 处理(整理好再显示
特点:把 UI 逻辑从 Controller 中抽出来,Controller 更轻,View 更可测试
MVVM模式(Model–View–ViewModel)
Model:数据和业务逻辑
View:界面展示
ViewModel:包装 Model,处理好数据并与View 自动同步
因为才刚刚学习架构模式这方面相关内容,对MVP与MVVM都只是简单了解,若以后深入学习后会再重新进行细节的介绍