工程项目中 Controller越来约臃肿,业务和View层耦合越来约严重,如何给Controller减减负迫在眉睫。
MVVM框架设计
如图所示:
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的项目,目录结构大致是这样的
结果就是,原来臃肿的Controller被细分到了其他的类中,为其大大的减负。同时,也做到了UI,业务分离,如果项目需要替换接口,业务逻辑,只需要修改对应Handler即可,也起到了降低耦合的作用。
不过也有导致了一个Controller,对应的相关类文件变多,创建麻烦的缺点,因此,在新建类的时候,可以采用建立XCode模版,或者脚本实现自动创建。本人采用的是执行脚本创建,所以创建文件变多的麻烦并不存在。