浅谈MVC和MVVM架构模式(二)

首先我们来建立一个项目,以MVC模式和MVVM模式分别展示一个简单tableview.

Paste_Image.png

1.AppGeneral:通用类

a.Base:基类(整个框架的基类,使用需要继承)

b.Categories : 公共扩展类 (就是一些常用的类别)

c.Macro:宏定义类 (就是整个应用会用到的宏定义)
1):AppMacro.h -- app项目的相关宏定义
2):NotificationMacro.h -- 通知相关的宏定义
2):ApiMacro.h -- 项目中测试环境和生产环境所有接口路径的宏定义

d.Models: 公共Model (公用的一些数据模型)

e.Utils:项目的相关工具类(比如类似数据请求等工具类)

f.Views:公共View (封装的一些常用的View)

2.Main:项目中主要的东西(如AppDelegate,main.m)

3.Modules:模块 (如首页模块,发现模块,我的模块等)

4.Resource:这里放置的是工程所需的一些资源(Fonts 字体,Images 图片,Sounds 声音,Videos 视频)

5.Vendors : 第三方的类库/SDK,(UMeng、baiduMapSDK等等)。

接下来进入正题

1.MVC模式

Paste_Image.png
@interface ProductModel : NSObject

 @property (copy, nonatomic) NSString *desc;  //描述

@end
@interface ProductCell : UITableViewCell

 @property (strong, nonatomic) ProductModel *productModel;

 + (instancetype)cellForTableView:(UITableView *)tableView;

@end

@interface ProductCell ()

 @property (strong, nonatomic) UILabel *descLbl;

@end

@implementation ProductCell

+ (instancetype)cellForTableView:(UITableView *)tableView
{
    NSString *identify = @"ProductCell";
    ProductCell *cell = [tableView dequeueReusableCellWithIdentifier:identify];
    if (nil == cell) {
        cell = [[ProductCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identify];
    }
    return cell;
}

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        
        self.selectionStyle = UITableViewCellSelectionStyleNone;
        
        self.descLbl = [[UILabel alloc] init];
    
        [self.contentView addSubview:self.descLbl];
        
    }
    return self;
}

-(void)layoutSubviews
{
    [super layoutSubviews];
    
    [self.descLbl mas_makeConstraints:^(MASConstraintMaker *make) {
       
        make.edges.equalTo(self.contentView).with.insets(UIEdgeInsetsMake(10, 10, 10, 10));
    }];
}

-(void)setProductModel:(ProductModel *)productModel
{
    self.descLbl.text = productModel.desc;
}

@end

@interface ProductsVC ()<UITableViewDelegate,UITableViewDataSource>

 @property (strong, nonatomic) UITableView *productListTableView;

 @property (strong, nonatomic) NSMutableArray *productsArray;

@end

@implementation ProductsVC

- (void)viewDidLoad {
   
    [super viewDidLoad];
    
    [self setupUI];
    
    [self setupUILayout];
    
    [self requestData];
    
}

-(void)setupUI
{
    self.productListTableView = [[UITableView alloc] init];
    self.productListTableView.delegate = self;
    self.productListTableView.dataSource = self;
    [self.view addSubview:self.productListTableView];
}

-(void)setupUILayout
{
     [self.productListTableView mas_makeConstraints:^(MASConstraintMaker *make) {
        
         make.left.equalTo(self.view);
         make.top.equalTo(self.view);
         make.right.equalTo(self.view);
         make.bottom.equalTo(self.view);
     }];
}

-(void)requestData
{
    [NetWorkManager requestWithType:HttpRequestTypeGet withUrlString:@"/test" withParaments:@{@"page":@"1"} withSuccessBlock:^(NSDictionary *object) {
        
        if ([[object valueForKey:@"success"] boolValue]) {
            
            self.productsArray = [ProductModel mj_objectArrayWithKeyValuesArray:[object valueForKey:@"data"]];
            
            [self.productListTableView reloadData];
            
        }else{
            
            NSLog(@"%@",[object valueForKey:@"errorMsg"]);
        }

        
    } withFailureBlock:^(NSError *error) {
        
        NSLog(@"系统忙,请稍后再试");
        
    } progress:^(float progress) {
        
    }];
}

#pragma mark-- tableDelegate,tableDataSource

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.productsArray.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    ProductCell *cell = [ProductCell cellForTableView:tableView];
    
    ProductModel *productModel = self.productsArray[indexPath.row];
    
    cell.productModel = productModel;
    
    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 50;
}


#pragma mark--  懒加载
-(NSMutableArray *)productsArray
{
    if (_productsArray==nil) {
        
        _productsArray = [NSMutableArray array];
        
    }
    return _productsArray;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    
}

@end

这就完成了一个非常简单列表的MVC模式,当然,随着页面的复杂程度,你会发现控制器会越来越臃肿,这就是MVC模式非常大的一个弊端.

最后我们来看看MVVM+RAC模式是怎样完成这么一个简单的列表页面(这里就不细讲RAC的使用了) cell和model代码不变,变的是控制器里面的代码和新增的一个vm

@interface ProductViewModel : NSObject<UITableViewDataSource>

 //请求命令
 @property (strong, nonatomic) RACCommand *reuqesCommand;

 //模型数组
 @property (strong, nonatomic) NSArray *modelArray;

@end

@implementation ProductViewModel

- (instancetype)init
{
    if (self = [super init]) {
        
        [self initialBind];
    }
    return self;
}


-(void)initialBind
{
    _reuqesCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
        
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            
            [NetWorkManager requestWithType:HttpRequestTypePost withUrlString:@"/test" withParaments:@{@"page":@"1"} withSuccessBlock:^(NSDictionary *object) {
                
                if ([[object valueForKey:@"success"] boolValue]) {
                    
                    // 请求成功调用
                    // 把数据用信号传递出去
                    [subscriber sendNext:[ProductModel mj_objectArrayWithKeyValuesArray:[object valueForKey:@"data"]]];
                    
                    [subscriber sendCompleted];
                    
                }else{
                    
                    NSLog(@"%@",[object valueForKey:@"errorMsg"]);
                }

                
            } withFailureBlock:^(NSError *error) {
                
            } progress:^(float progress) {
                
            }];
            
            return nil;
            
        }];
        
    }];
}

#pragma mark - UITableViewDataSource

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.modelArray.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    ProductCell *cell = [ProductCell cellForTableView:tableView];
    
    ProductModel *productModel = self.modelArray[indexPath.row];
    
    cell.productModel = productModel;
    
    return cell;
}

@end

@interface ProductListVC ()

 @property (strong, nonatomic) UITableView *productListTableView;

 @property (strong, nonatomic) ProductViewModel *productViewModel;

@end

@implementation ProductListVC

- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    [self setupUI];
    
    [self setupUILayout];
    
    [self bindViewModel];
}

-(void)setupUI
{
    self.productListTableView = [[UITableView alloc] init];
    self.productListTableView.dataSource = self.productViewModel;
    [self.view addSubview:self.productListTableView];
}

-(void)setupUILayout
{
    [self.productListTableView mas_makeConstraints:^(MASConstraintMaker *make) {
        
        make.left.equalTo(self.view);
        make.top.equalTo(self.view);
        make.right.equalTo(self.view);
        make.bottom.equalTo(self.view);
    }];
}

-(void)bindViewModel
{
    //执行请求
    RACSignal *requesSiganl = [self.productViewModel.reuqesCommand execute:nil];
    
    //获取请求数据
    [requesSiganl subscribeNext:^(NSArray *x) {
        
        self.productViewModel.modelArray = x;
        
        [self.productListTableView reloadData];
        
    }];
}


#pragma mark -- 懒加载
-(ProductViewModel *)productViewModel
{
    if (_productViewModel==nil) {
        
        _productViewModel = [[ProductViewModel alloc] init];
        
    }
    
    return _productViewModel;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容