Osheep

时光不回头,当下最重要。

iOS - MVVM模式设计实践

工程项目中 Controller越来约臃肿,业务和View层耦合越来约严重,如何给Controller减减负迫在眉睫。

MVVM框架设计

如图所示:

《iOS - MVVM模式设计实践》

MVVM结构图.png
  • Controller: 里面只包含一个View,由于是要将原来臃肿Controller瘦身,这里的效果拔群。
    Controller里做的主要是初始化这个View,设置Controller的title,以及默认View的背景色。如果需要设置leftBarButtonItem或者rightBarButtonItem均在此处设置。

  • View:此处包含所有视图相关的View,所有UI相关的操作放在这里,然后通过KVO监听ViewModel让视图变化。

  • ViewModel:所有数据相关的属性都存放在这里,同时用于被KVO的对象,传统的ViewModel可以提供对数据以及业务的处理,但是为了防止ViewModel的臃肿,对ViewModel进行进一步拆分。

  • Model: 网络层相关model

  • DataProtocol: 处理数据的协议,在View或者Controller中被调用,效果是解耦。

  • BusinessProtocol: 处理业务的协议,在View或者Controller中被调用,效果是解耦。

  • DataHandler:处理数据的实现

  • BusinessHandler:处理业务的实现

MVVM实现

Controller,View,ViewModel之间通过定义一个Content类进行绑定操作。

Content类

#import <Foundation/Foundation.h>
#import "DDDDataHandler.h"
#import "DDDBusinessHandler.h"

@interface DDDContext : NSObject
@property (nonatomic, strong, readonly) DDDDataHandler *dataHandler;
@property (nonatomic, strong, readonly) DDDBusinessHandler *businessHandler;

- (instancetype)initWithDataHandler:(DDDDataHandler*)dataHandler
                withBusinessHandler:(DDDBusinessHandler*)businessHandler;
@end

@implementation DDDContext
#pragma mark - lifecycle
- (instancetype)initWithDataHandler:(DDDDataHandler*)dataHandler
                withBusinessHandler:(DDDBusinessHandler*)businessHandler
{
    self = [super init];
    if (self){
        _dataHandler = dataHandler;
        _dataHandler.context = self;

        _businessHandler = businessHandler;
        _businessHandler.context = self;
    }

    return self;
}
@end

同时给NSObject添加一个分类,使得他们可以调用Content

NSObject + DDD 类

#import <Foundation/Foundation.h>

@class DDDContext;
@interface NSObject (DDD)
@property (nonatomic, strong)DDDContext *context;
@end

DataHandler 类

#import <Foundation/Foundation.h>
#import "DDDContext.h"

@class DDDContext;
@interface DDDDataHandler : NSObject
@property (nonatomic, weak) DDDContext *context;
@end

BusinessHandler 类

#import <Foundation/Foundation.h>
#import "DDDContext.h"


@class DDDContext;
@interface DDDBusinessHandler : NSObject
@property (nonatomic, weak) DDDContext *context;
@property (nonatomic, weak) UIViewController *controller;
@end

只要在初始化Controller,View的时候,对Content进行赋值,那么他们之间的关系就被绑定了。

例如,在Controller初始化中调用.

- (void)initContext
{
    xxxDataHandler *datahandler = [xxxDataHandler new];
    xxxBusinessHandler *businessHandler = [xxxBusinessHandler new];
    businessHandler.controller = self;
    self.context = [[DDDContext alloc] initWithDataHandler:datahandler withBusinessHandler:businessHandler];
}

== xxxBusinessHandler,xxxDataHandler为子类 ==

MVVM在工程中的应用

使用本文中MVVM的项目,目录结构大致是这样的

《iOS - MVVM模式设计实践》

MVVM代码结构.png

结果就是,原来臃肿的Controller被细分到了其他的类中,为其大大的减负。同时,也做到了UI,业务分离,如果项目需要替换接口,业务逻辑,只需要修改对应Handler即可,也起到了降低耦合的作用。

不过也有导致了一个Controller,对应的相关类文件变多,创建麻烦的缺点,因此,在新建类的时候,可以采用建立XCode模版,或者脚本实现自动创建。本人采用的是执行脚本创建,所以创建文件变多的麻烦并不存在。

点赞