美文网首页
架构设计之MVP模式

架构设计之MVP模式

作者: 背着相机去旅行 | 来源:发表于2019-05-10 20:27 被阅读0次

    这几天思考项目重构的问题,我就啰嗦两句。项目重构说白了就是为controller减负,解耦合。之前项目都是使用mvc模式写的,发现这样写有个弊端,就是一堆代码逻辑都堆积在controller里面,导致有些类文件庞大,有的多达上千行的代码量,阅读起来十分困难,更别说重用了,改个bug都困难。

    大家有兴趣的话可以阅读下唐巧的被误解的 MVC 和被神化的 MVVM

    站在大牛的肩膀上学习,总是事半功倍的。下面我们来说下MVP架构,插一句,没有任何架构设计是完美的,我们只能给不同的需求制定不同的架构设计,去降低耦合,提高复用。这是MVPDemo,需要的话自行下载。

    这是MVP架构设计图,第一次画,有些粗糙
    MVP架构图

    下面是具体的代码实现:
    先来看下类结构


    高清无码图

    首先来定义一个view的协议,用来处理数据回调,上代码:
    #import <Foundation/Foundation.h>

    @protocol BaseViewProtocol <NSObject>
    
    - (void)showRemindTitle:(NSString *)message;
    
    @optional
    - (void)testTouchAction:(NSInteger)index;
    @end
    

    接下来在TabViewController里面去写需求,让P 层执行

    @interface TableViewController ()<BaseViewProtocol>
    
    //V 层包括UIView 和UIViewController及子类,需要持有P 层的实例对象
    @property (nonatomic, strong) HomePresenter *presenter;
    
    @end
    
    @implementation TableViewController
    
    - (void)viewDidLoad {
    [super viewDidLoad];
    
    //初始化一个P对象
    _presenter = [[HomePresenter alloc] init];
    
    //使用协议绑定进行数据传输
    _presenter.protocol = self;
    
    //显示head view,这里在P层创建了headView,当然也可以在Controller里面创建,传入P层
    self.tableView.tableHeaderView = _presenter.headView;
    
    [_presenter loadData];
    
    }
    
    - (void)showRemindTitle:(NSString *)message{
        if (message) {
          //show view
          [[[UIAlertView alloc] initWithTitle:@"温馨提示" message:message delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil] show];
        }
    }
    

    MVP中主要代码集中在P层,下面是P层代码逻辑:

    @interface HomePresenter ()<BLoopImageViewDelegate>
    
    @end
    
    /**
     *  P 层作为协调者(中介),需要持有M 层和V 层的对象的引用
     *  适当的时候去协调他们的更新逻辑
     */
    @implementation HomePresenter
    
    
    - (BLoopImageView *)headView{
    if (!_headView) {
        _headView = [[BLoopImageView alloc] initWithFrame:CGRectMake(0, 0, Screen_bounds.size.width, 240) delegate:self imageItems:nil isAuto:YES];
    }
        return _headView;
    }
    
    - (void)setProtocol:(id<BaseViewProtocol>)protocol{
        _protocol = protocol;
    }
    
    - (void)loadData{
        [HomeListModel startGETURL:^(NSArray *info, NSString *error) {
         if (error) {
              //当请求出错时需要回调给出提示信息
              if (self.protocol) {
                 [self.protocol showRemindTitle:error];
              }
         } else {
                [self.headView setItemsArr:info];
            }
        }];
    }
    
    #pragma mark
    - (void)foucusImageFrame:(BLoopImageView *)imageView didSelectItem:(BLoopImageItem *)item{
        NSLog(@"item.title = %@",item.title);
        [self.protocol testTouchAction:item.tag];
    
    }
    - (void)foucusImageFrame:(BLoopImageView *)imageView currentItem:(NSInteger)index{
        NSLog(@"index = %zd",index);
    }
    
    - (void)cancelHeadView{
        self.headView = nil;
    }
    

    M层代码就变得很清爽了,只专一的去做数据处理,并组织好UI 显示的数据,看代码:

    @implementation HomeListModel
    
    + (void)startGETURL:(void (^)(NSArray *info, NSString *error))block{
        [[BKNetworking share] get:@"http://bapi.baby-kingdom.com/index.php?mod=stand&op=index&ver=3.6.0&app=ios" completion:^(BKNetworkModel *model, NSString *netErr) {
            if (netErr) {
                block(nil, netErr);
            } else {
                if (model.status) {
                    NSDictionary *data = model.data;
                    if ([data isKindOfClass:[NSDictionary class]]) {
                        NSArray *items = [self loadPackageData:data[@"lists"]];
                    
                        //创建model
                        block ( items, nil );
                    }
                }
            }
        }];
    }
    
    
    //组装数据并返回
    + (NSArray *)loadPackageData:(NSArray *)images{
        //添加最后一张图 用于循环
        int length = (unsigned)images.count;
        NSMutableArray *itemArray = [NSMutableArray arrayWithCapacity:length+2];
        if (length > 1)
        {
            NSDictionary *dict = images[length-1];
            BLoopImageItem *item = [[BLoopImageItem alloc] initWithDict:dict tag:-1];
            [itemArray addObject:item];
        }
        for (int i = 0; i < length; i++)
        {
            NSDictionary *dict = images[i];
            BLoopImageItem *item = [[BLoopImageItem alloc] initWithDict:dict tag:i];
            [itemArray addObject:item];
        }
        //添加第一张图 用于循环
        if (length >1)
        {
            NSDictionary *dict = images[0];
            BLoopImageItem *item = [[BLoopImageItem alloc] initWithDict:dict tag:length];
            [itemArray addObject:item];
        }
    
        return itemArray;
    
    }
    
    @end
    

    参考文章:

    iOS 软件架构 - MVC, MVP, MVVM 和 VIPER 「译」

    第一次设计到架构,可能还有问题,希望大家一起交流讨论,谢谢!


    相关文章

      网友评论

          本文标题:架构设计之MVP模式

          本文链接:https://www.haomeiwen.com/subject/ytigkxtx.html