最近在研究MVP这个体系架构,为了深入理解这个体系架构,自己也做了一些Demo。
体系目录
示例图片
每一模块的功能
Model
数据模型层,建立数据模型,提供一些字典转模型的方法;如果数据模型最后需要存储到DB,这里也可以放一些DB的增删改查操作,当然最好还是再划分一个DB层出来,专门用来处理数据操作
@interface ContactModel : NSObject
@property(nonatomic,copy) NSString *name;
@property(nonatomic,copy) NSString *position;
@property(nonatomic,copy) NSString *jobDescription;
+(instancetype)initWithContactModelDict:(NSDictionary *)dict;
-(instancetype)contactModelWithDict:(NSDictionary *)dict;
//DB Operation
-(void)writeToDatabase:(ContactModel *)contactModel;
-(void)deleteContactModel:(ContactModel *)contactModel;
-(void)updateContactModel:(ContactModel *)contactModel;
@end
View(View+VC)
这个case中, 我们需要一个创建tableView,tableView的数据从哪里来呢?
这个Presenter会把数据传递给你的,View层拿到数据后只需要去加载到tableView上显示就可以了。
Presenter
刚才说了,tableView层需要的数据从哪里来? Presenter提供,所以Presenter这里需要通过Service去从服务端请求数据,
Service层可以对数据做一下处理,将json/xml 数据转化成字典数据,然后再传递给Presenter层。
Presenter层得到数据后,先传递给Model层做字典转模型,如有需要,将模型数据直接存入Database中。
然后Presenter层将转好的模型数据传递给View层,如何做到呢?
通过我们常用的delegate去实现。
UserViewProtocol.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@protocol UserViewProtocol <NSObject>
-(void)loadData:(NSArray *)array;
@end
NS_ASSUME_NONNULL_END
ViewController需要遵守这样的协议,这边拿到的array就是Preseter想传递给View层的数据,View直接显示这些数据即可。
- (void)requestData{
//1. 通过Service层发送网络去请求数据
//2. 解析请求到的数据,字典转模型(Model层交互)
//假设我们得到了一个字典数组
NSArray *dictArray = @[
@{
@"name" : @"EvanYang",
@"position" : @"IT Developer",
@"jobDescription" : @"Develop the IT Process"
},
@{
@"name" : @"ZhangSan",
@"position" : @"iOS Developer",
@"jobDescription" : @"Develop for the iOS"
},
@{
@"name" : @"LiSi",
@"position" : @"Software Engineer",
@"jobDescription" : @"Software"
}
];
//字典转模型
for (NSDictionary *dict in dictArray) {
[self.contactModelTotaldata addObject:[ContactModel initWithContactModelDict:dict]];
}
//3. 将模型数据通过协议方法传递给VC层
if ([self.delegate respondsToSelector:@selector(loadData:)]) {
[self.delegate loadData:self.contactModelTotaldata];
}
}
这样,Presenter其实就相当于一个协调者了,负责去请求数据,通过model去存储数据,再把数据传递给ViewController层。
Another example
- 假设现在用户想删除一条数据,VC层会直接调用Presenter的对象方法,并告诉它我要删除的是哪一条数据。
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
//Delete
if (editingStyle == UITableViewCellEditingStyleDelete) {
ContactModel *contactModel = self.totalData[indexPath.row];
[self.myPresenter deleteContactFromDB:contactModel];
}
}
- Presenter接受到删除指定数据的消息后,会直接将该模型从数据库中删除,并从总的数据模型中将该数据删除,全部工作做好之后,最好将更改后的总的数据通过代理方式再传递给VC,让VC做刷新,重新加载。
-(void)deleteContactFromDB:(ContactModel *)contactModel{
//1. Delete the contact from db
//2. Delete from the total data
[self.contactModelTotaldata removeObject:contactModel];
//3. 将删除后的总的数据重新传递给VC层,并让它做刷新操作
if ([self.delegate respondsToSelector:@selector(loadData:)]) {
[self.delegate loadData:self.contactModelTotaldata];
}
}
其实,从上可以看出,presenter层承担了大部分的业务操作,presenter通过代理的方式向VC层发送消息,传递数据。因为VC层含有了presenter这个对象,可以直接调用presenter的实例方法去传递消息。