iOS架构模式MVC、MVP、MVVM(内附demo)
来源:互联网 发布:windows 许可证过期 编辑:程序博客网 时间:2024/06/01 10:30
MVC
MVC的实现思路是:用户操作View,在Controller层完成业务逻辑处理,更新Model层,将数据显示在View层。
在MVC中,每个层之间都有关联,耦合比较紧,在大型项目中,维护起来比较费力。
View把控制权交给Controller层,自己不执行业务逻辑;Controller层执行业务逻辑并且操作Model层,但不会直接操作View层;View和Model层的同步消息是通过观察者模式进行,而同步操作是由View层自己请求Model层的数据,然后对视图进行更新,观察者模式可以做到多视图同时更新。
MVC结构如图所示:
模型层:
Person.h
#import <Foundation/Foundation.h>@interface Person : NSObject@property (nonatomic, readonly) NSString *firstName;@property (nonatomic, readonly) NSString *lastName;- (instancetype)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName;@end
Person.m
#import "Person.h"@implementation Person- (instancetype)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName { self = [super init]; if (self) { _firstName = firstName; _lastName = lastName; } return self;}@end
视图层:
TestView.h
#import <UIKit/UIKit.h>@interface TestView : UIView@property (nonatomic, strong) UILabel *nameLabel;@end
TestView.m
#import "TestView.h"@implementation TestView- (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.nameLabel = [[UILabel alloc] initWithFrame:self.bounds]; self.nameLabel.textAlignment = NSTextAlignmentCenter; [self addSubview:self.nameLabel]; } return self;}@end
控制器层:
ViewController.m
#import "ViewController.h"#import "Person.h"#import "TestView.h"@interface ViewController ()@property (nonatomic, strong) Person *personModel;@property (nonatomic, strong) TestView *testView;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; [self setupViews]; if (self.personModel.firstName.length > 0) { self.testView.nameLabel.text = self.personModel.firstName; } else { self.testView.nameLabel.text = self.personModel.lastName; }}- (void)setupViews { self.personModel = [[Person alloc] initWithFirstName:@"" lastName:@"胡歌"]; self.testView = [[TestView alloc] initWithFrame:CGRectMake(100, 100, CGRectGetWidth(self.view.bounds)-200, 50)]; [self.view addSubview:self.testView];}@end
MVP
MVP的实现思路是:用户操作View,在Presenter层完成业务逻辑处理,更新Model层,通过Presenter将数据显示在View层,完全隔断Model和View之间的通信。
我们通过接口的方式来连接view和presenter层,这样导致的问题是,如果页面过于复杂,我们的接口就会很多,为了更好的处理类似的问题,需要定义一些基类接口,把一些公共的逻辑,比如网络请求,toast,提示框等放在里面。
因为MVP不依赖Model,所以可以更好的进行组件化,把它从特定的场景中脱离出来,做到高度复用。MVP中的Presenter更多的作为框架的控制者,承担了大量的逻辑操作。
MVP结构如图:
模型层:
Person.h
#import <Foundation/Foundation.h>@interface Person : NSObject@property (nonatomic, readonly) NSString *firstName;@property (nonatomic, readonly) NSString *lastName;- (instancetype)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName;@end
Person.m
#import "Person.h"@implementation Person- (instancetype)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName { self = [super init]; if (self) { _firstName = firstName; _lastName = lastName; } return self;}@end
视图层:
TestView.h
#import <UIKit/UIKit.h>@interface TestView : UIView@property (nonatomic, strong) UILabel *nameLabel;@end
TestView.m
#import "TestView.h"@implementation TestView- (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.nameLabel = [[UILabel alloc] initWithFrame:self.bounds]; self.nameLabel.textAlignment = NSTextAlignmentCenter; [self addSubview:self.nameLabel]; } return self;}@end
Presenter层:
PersonViewProtocol.h
#import <Foundation/Foundation.h>@protocol PersonViewProtocol <NSObject>- (void)setNameText:(NSString *)nameText;@end
Presenter.h
#import <Foundation/Foundation.h>#import "PersonViewProtocol.h"@interface Presenter : NSObject- (void)attachView:(id <PersonViewProtocol>)view;- (void)fetchData;@end
Presenter.m
#import "Presenter.h"#import "Person.h"@interface Presenter()@property (nonatomic, strong) Person *person;@property (nonatomic, weak) id<PersonViewProtocol> attachView;@end@implementation Presenter- (void)attachView:(id<PersonViewProtocol>)view { self.attachView = view;}- (void)fetchData { self.person = [[Person alloc] initWithFirstName:@"赵丽颖" lastName:@"胡歌"]; if (self.person.firstName.length > 0) { [self.attachView setNameText:self.person.firstName]; } else { [self.attachView setNameText:self.person.lastName]; }}@end
ViewController.m
#import "ViewController.h"#import "PersonViewProtocol.h"#import "Presenter.h"#import "TestView.h"@interface ViewController ()<PersonViewProtocol>@property (nonatomic, strong) TestView *testView;@property (nonatomic, strong) Presenter *presenter;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; [self setupViews]; self.presenter = [Presenter new]; [self.presenter attachView:self]; [self.presenter fetchData];}- (void)setupViews { self.testView = [[TestView alloc] initWithFrame:CGRectMake(100, 100, CGRectGetWidth(self.view.bounds)-200, 50)]; [self.view addSubview:self.testView];}#pragma PersonViewProtocol- (void)setNameText:(NSString *)nameText { self.testView.nameLabel.text = nameText;}@end
MVVM
MVVM和MVP的最大区别是采用了双向绑定机制,View的变动,自动反映在ViewModel上。
MVVM结构如图:
模型层:
Person.h
#import <Foundation/Foundation.h>@interface Person : NSObject@property (nonatomic, readonly) NSString *firstName;@property (nonatomic, readonly) NSString *lastName;- (instancetype)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName;@end
Person.m
#import "Person.h"@implementation Person- (instancetype)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName { self = [super init]; if (self) { _firstName = firstName; _lastName = lastName; } return self;}@end
视图层:
TestView.h
#import <UIKit/UIKit.h>@interface TestView : UIView@property (nonatomic, strong) UILabel *nameLabel;@end
TestView.m
#import "TestView.h"@implementation TestView- (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.nameLabel = [[UILabel alloc] initWithFrame:self.bounds]; self.nameLabel.textAlignment = NSTextAlignmentCenter; [self addSubview:self.nameLabel]; } return self;}@end
ViewModel层:
PersonViewModel.h
#import <Foundation/Foundation.h>#import "Person.h"@interface PersonViewModel : NSObject@property (nonatomic, readonly) Person *person;@property (nonatomic, readonly) NSString *nameText;- (instancetype)initWithPerson:(Person *)person;@end
PersonViewModel.m
#import "PersonViewModel.h"@implementation PersonViewModel- (instancetype)initWithPerson:(Person *)person { self = [super init]; if (self) { _person = person; if (_person.firstName.length > 0) { _nameText = _person.firstName; } else { _nameText = _person.lastName; } } return self;}@end
ViewController.m
#import "ViewController.h"#import "PersonViewModel.h"#import "TestView.h"@interface ViewController ()@property (nonatomic, strong) TestView *testView;@property (nonatomic, strong) PersonViewModel *viewModel;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; [self setupViews]; self.testView.nameLabel.text = self.viewModel.nameText;}- (void)setupViews { Person *person = [[Person alloc] initWithFirstName:@"" lastName:@"胡歌"]; self.viewModel = [[PersonViewModel alloc] initWithPerson:person]; self.testView = [[TestView alloc] initWithFrame:CGRectMake(100, 100, CGRectGetWidth(self.view.bounds)-200, 50)]; [self.view addSubview:self.testView];}@end
(MVC、MVP、MVVM)Demo下载
密码:pmv6
- iOS架构模式MVC、MVP、MVVM(内附demo)
- iOS 架构模式 - 简述 MVC, MVP, MVVM
- 架构模式 -- MVC、MVP、MVVM
- 架构模式:MVC,MVP&MVVM
- iOS架构 - MVC/MVP/MVVM
- iOS 架构模式--解密 MVC,MVP,MVVM以及VIPER架构
- iOS 架构模式--解密 MVC,MVP,MVVM以及VIPER架构
- iOS 架构模式--解密 MVC,MVP,MVVM以及VIPER架构
- iOS 架构模式--解密 MVC,MVP,MVVM以及VIPER架构
- iOS 架构模式--解密 MVC,MVP,MVVM以及VIPER架构
- iOS架构模式-揭秘MVC,MVP,MVVM和VIPER
- iOS架构模式-揭秘MVC,MVP,MVVM和VIPER
- iOS 架构模式 - 简述 MVC, MVP, MVVM 和 VIPER (译)
- 104.iOS架构模式(MVC/MVCS/MVP/MVVM/VIPER)
- Android架构模式:MVC & MVP & MVVM
- MVC、MVP、MVVM架构模式--简单说
- 浅谈 MVC、MVP 和 MVVM 架构模式
- iOS 框架模式(简述 MVC,MVP,MVVM 和 VIPER)
- NET USE 用法
- 【20171116】为什么main函数是public static void
- HTTPS 建立连接的详细过程
- Exchange备份单个用户邮件及清理邮箱数据
- iOS开发错误及解决方法
- iOS架构模式MVC、MVP、MVVM(内附demo)
- linux学习笔记总结(链接)
- js基础
- Python标准库
- 钱包代码
- js旋转木马特效
- 最近实现的一个分离文章内容功能,挺有意思,分享一下
- 转帖matlab_1_图像处理imfinfo_imshow_funtion
- ArrayList