MVC
MVC架构模式: Model-View-Controller是一个用来组织代码的权威范式。Apple甚至是这么说的。在MVC下,所有的对象被归类为一个model,一个view,或一个controller。Model持有数据,View显示与用户交互的界面,而View Controller调解Model和View之间的交互。
用户操作View, 在Controller层完成业务逻辑处理, 更新Model层, 将数据显示在View层.
- Model层
@interface Person : NSObject
@property (nonatomic, readonly) NSString *firstName;
@property (nonatomic, readonly) NSString *lastName;
- (instancetype)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName;
@end
@implementation Person
- (instancetype)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName {
if ([super init]) {
_firstName = firstName;
_lastName = lastName;
}
return self;
}
@end
- View层
@interface TestView : UIView
@property (nonatomic, strong) UILabel *nameLabel;
@end
@implementation TestView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
_nameLabel = [[UILabel alloc] initWithFrame:self.bounds];
_nameLabel.textAlignment = NSTextAlignmentCenter;
[self addSubview:_nameLabel];
}
return self;
}
@end
- Controller层
@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:@"XXX"];
self.testView = [[TestView alloc] initWithFrame:CGRectMake(100, 100, CGRectGetWidth(self.view.bounds)-200, 50)];
[self.view addSubview:self.testView];
}
@end
MVP
MVP架构模式: Model-View-Presenter是MVC的改良模式,由IBM的子公司Taligent提出。和MVC的相同之处在于:Controller/Presenter负责业务逻辑,Model管理数据,View负责显示只不过是将 Controller 改名为 Presenter,同时改变了通信方向。
View 与 Model 不通信,都通过 Presenter 传递。Presenter完全把Model和View进行了分离,主要的程序逻辑在Presenter里实现。
- Model层
@interface Person : NSObject
@property (nonatomic, readonly) NSString *firstName;
@property (nonatomic, readonly) NSString *lastName;
- (instancetype)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName;
@end
@implementation Person
- (instancetype)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName {
if (self = [super init]) {
_firstName = firstName;
_lastName = lastName;
}
return self;
}
@end
- View层
@interface TestView : UIView
@property (nonatomic, strong) UILabel *nameLabel;
@end
@implementation TestView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
_nameLabel = [[UILabel alloc] initWithFrame:self.bounds];
_nameLabel.textAlignment = NSTextAlignmentCenter;
[self addSubview:_nameLabel];
}
return self;
}
@end
- Presenter层
@protocol PersonViewProtocol
- (void)setNameText:(NSString *)nameText;
@end
@interface Presenter : NSObject
- (void)attachView:(id )view;
- (void)fetchData;
@end
@interface Presenter()
@property (nonatomic, strong) Person *person;
@property (nonatomic, weak) id attachView;
@end
@implementation Presenter
- (void)attachView:(id)view {
self.attachView = view;
}
- (void)fetchData {
self.person = [[Person alloc] initWithFirstName:@"AAA" lastName:@"BB"];
if (self.person.firstName.length > 0) {
[self.attachView setNameText:self.person.firstName];
} else {
[self.attachView setNameText:self.person.lastName];
}
}
@end
- Controller
@interface ViewController ()
@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架构模式: Model-View-ViewModel是 M-V-VM 三部分组成,它本质上就是 MVC 的改进版. 在 MVC 下,所有的对象被归类为一个 model,一个 view,或一个 controller。Model 持有数据,View 显示与用户交互的界面,而 View Controller 调解 Model 和 View 之间的交互。然而,随着模块的迭代我们越来越发现 MVC 自身存在着很多不足。因此,MVVM 从其他应用而出,在 iOS 中从此我们完全将业务逻辑加以区分并使用这套思想。在 MVVM 中他的设计思路和 MVC 很像。它正式规范了视图和控制器紧耦合的性质,并引入新的组件 ViewModel。此外,它还有像监管版本的 MVP 那样的绑定功能,但这个绑定不是在 View 和 Model 之间而是在 View 和 ViewModel 之间。
- Model层
@interface Person : NSObject
@property (nonatomic, readonly) NSString *firstName;
@property (nonatomic, readonly) NSString *lastName;
- (instancetype)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName;
@end
@implementation Person
- (instancetype)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName {
if (self = [super init]) {
_firstName = firstName;
_lastName = lastName;
}
return self;
}
@end
- View层
@interface TestView : UIView
@property (nonatomic, strong) UILabel *nameLabel;
@end
@implementation TestView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
_nameLabel = [[UILabel alloc] initWithFrame:self.bounds];
_nameLabel.textAlignment = NSTextAlignmentCenter;
[self addSubview:_nameLabel];
}
return self;
}
@end
- ViewModel层
@interface PersonViewModel : NSObject
@property (nonatomic, readonly) Person *person;
@property (nonatomic, readonly) NSString *nameText;
- (instancetype)initWithPerson:(Person *)person;
@end
@implementation PersonViewModel
- (instancetype)initWithPerson:(Person *)person {
if (self = [super init]) {
_person = person;
if (_person.firstName.length > 0) {
_nameText = _person.firstName;
} else {
_nameText = _person.lastName;
}
}
return self;
}
@end
- Controller
@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:@"AAA" lastName:@"BB"];
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