闲来无事,研究了下IOS的MVP设计架构,分享下自己的感悟,说的不对的地方还请各位大神不吝指教
首先上一张图:
1 . 概念:"MVP"中的M指的是model,"V"指的是UIViewController以及UIView,"P"指的是"Present",
MVP解耦的关键在于将传统的UIViewController部分业务逻辑交由"Present"处理,比如网络请求,用户的操作行为,
- "MPV"如何解耦以及与他们三者之间是如何通信的呢?
"Present"一方面通过Service层调用接口获取数据给Model层,
[_userService getUserInfosSuccess:^(NSDictionary *dic) {
[self.attachView hideIndicator];
NSArray *userArr = [dic valueForKey:@"data"];
if ([self processOriginDataToUIFriendlyData:userArr].count == 0) {
[self.attachView showEmptyView];
}
[self.attachView userViewDataSource:[self processOriginDataToUIFriendlyData:userArr]];
} andFail:^(NSDictionary *dic) {
}];
- (NSArray<UserModel *> *)processOriginDataToUIFriendlyData:(NSArray *)originData {
NSMutableArray<UserModel *> *friendlyUIData = [NSMutableArray array];
for (NSDictionary *dic in originData) {
if ([[dic valueForKey:@"gender"] isEqualToString:@"male"]) {
UserModel *model = [UserModel userWithDict:dic];
[friendlyUIData addObject:model];
}
}
return friendlyUIData;
}
然后又以协议的方式
[self.attachView userViewDataSource:[self processOriginDataToUIFriendlyData:userArr]];
将数据传给UIViewController
#pragma mark - UserViewProtocol
- (void)userViewDataSource:(NSArray<UserModel *> *)data {
self.friendlyUIData = data;
[self.tableView reloadData];
}
从而实现"Present"层向"V"层通信的机制,同时"V"层的控制器UIViewController通过添加"Present"对象
- (Presenter *)presenter {
if (_presenter == nil) {
_presenter = [[Presenter alloc] init];
[_presenter attachView:self];
}
return _presenter;
}
实现"V"层向"Present"层通信,因此我们可以看出"V"层和"Present"是双向通信,而"P"即"Present"则通过请求数据赋值给Model来实现"P"层和"M"层通信,
- 用户的一些业务逻辑和操作全部交由"Present"去操作,而Present又是通过协议的方式
@interface Presenter()
@property (nonatomic,strong) UserService *userService;
@property (nonatomic, weak) id<UserViewProtocol> attachView;
@end
#import "UserModel.h"
@protocol UserViewProtocol <NSObject>
- (void)userViewDataSource:(NSArray<UserModel *> *)data;
- (void)showIndicator;
- (void)hideIndicator;
- (void)showEmptyView;
去响应用户的操作,具体的协议操作也是在“V”即Controller层实现
#pragma mark - UserViewProtocol
- (void)userViewDataSource:(NSArray<UserModel *> *)data {
self.friendlyUIData = data;
[self.tableView reloadData];
}
- (void)showIndicator {
[self.indicatorView startAnimating];
self.indicatorView.hidden = NO;
}
- (void)hideIndicator {
[self.indicatorView stopAnimating];
}