最近在研究MVP這個(gè)體系架構(gòu),為了深入理解這個(gè)體系架構(gòu),自己也做了一些Demo。
體系目錄

示例圖片

每一模塊的功能
Model
數(shù)據(jù)模型層,建立數(shù)據(jù)模型,提供一些字典轉(zhuǎn)模型的方法;如果數(shù)據(jù)模型最后需要存儲(chǔ)到DB,這里也可以放一些DB的增刪改查操作,當(dāng)然最好還是再劃分一個(gè)DB層出來,專門用來處理數(shù)據(jù)操作
@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)
這個(gè)case中, 我們需要一個(gè)創(chuàng)建tableView,tableView的數(shù)據(jù)從哪里來呢?
這個(gè)Presenter會(huì)把數(shù)據(jù)傳遞給你的,View層拿到數(shù)據(jù)后只需要去加載到tableView上顯示就可以了。
Presenter
剛才說了,tableView層需要的數(shù)據(jù)從哪里來? Presenter提供,所以Presenter這里需要通過Service去從服務(wù)端請(qǐng)求數(shù)據(jù),
Service層可以對(duì)數(shù)據(jù)做一下處理,將json/xml 數(shù)據(jù)轉(zhuǎn)化成字典數(shù)據(jù),然后再傳遞給Presenter層。
Presenter層得到數(shù)據(jù)后,先傳遞給Model層做字典轉(zhuǎn)模型,如有需要,將模型數(shù)據(jù)直接存入Database中。
然后Presenter層將轉(zhuǎn)好的模型數(shù)據(jù)傳遞給View層,如何做到呢?
通過我們常用的delegate去實(shí)現(xiàn)。
UserViewProtocol.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@protocol UserViewProtocol <NSObject>
-(void)loadData:(NSArray *)array;
@end
NS_ASSUME_NONNULL_END
ViewController需要遵守這樣的協(xié)議,這邊拿到的array就是Preseter想傳遞給View層的數(shù)據(jù),View直接顯示這些數(shù)據(jù)即可。
- (void)requestData{
//1. 通過Service層發(fā)送網(wǎng)絡(luò)去請(qǐng)求數(shù)據(jù)
//2. 解析請(qǐng)求到的數(shù)據(jù),字典轉(zhuǎn)模型(Model層交互)
//假設(shè)我們得到了一個(gè)字典數(shù)組
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"
}
];
//字典轉(zhuǎn)模型
for (NSDictionary *dict in dictArray) {
[self.contactModelTotaldata addObject:[ContactModel initWithContactModelDict:dict]];
}
//3. 將模型數(shù)據(jù)通過協(xié)議方法傳遞給VC層
if ([self.delegate respondsToSelector:@selector(loadData:)]) {
[self.delegate loadData:self.contactModelTotaldata];
}
}
這樣,Presenter其實(shí)就相當(dāng)于一個(gè)協(xié)調(diào)者了,負(fù)責(zé)去請(qǐng)求數(shù)據(jù),通過model去存儲(chǔ)數(shù)據(jù),再把數(shù)據(jù)傳遞給ViewController層。
Another example
- 假設(shè)現(xiàn)在用戶想刪除一條數(shù)據(jù),VC層會(huì)直接調(diào)用Presenter的對(duì)象方法,并告訴它我要?jiǎng)h除的是哪一條數(shù)據(jù)。
- (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接受到刪除指定數(shù)據(jù)的消息后,會(huì)直接將該模型從數(shù)據(jù)庫中刪除,并從總的數(shù)據(jù)模型中將該數(shù)據(jù)刪除,全部工作做好之后,最好將更改后的總的數(shù)據(jù)通過代理方式再傳遞給VC,讓VC做刷新,重新加載。
-(void)deleteContactFromDB:(ContactModel *)contactModel{
//1. Delete the contact from db
//2. Delete from the total data
[self.contactModelTotaldata removeObject:contactModel];
//3. 將刪除后的總的數(shù)據(jù)重新傳遞給VC層,并讓它做刷新操作
if ([self.delegate respondsToSelector:@selector(loadData:)]) {
[self.delegate loadData:self.contactModelTotaldata];
}
}
其實(shí),從上可以看出,presenter層承擔(dān)了大部分的業(yè)務(wù)操作,presenter通過代理的方式向VC層發(fā)送消息,傳遞數(shù)據(jù)。因?yàn)閂C層含有了presenter這個(gè)對(duì)象,可以直接調(diào)用presenter的實(shí)例方法去傳遞消息。