2.模型Model应该放什么代码

模型Model应该放什么代码

在以往开发中,对于模型层笔者存在这么几个疑惑:

  • 模型Model只是一个纯粹的数据结构
  • 负责数据I/O操作的操作属于C还是M

第一个问题笔者认为原因在于认知错误,过往开发的过程中,笔者曾经一度认为数据和模型之间的转换属于业务操作,将这些处理放在控制器Controller层中执行:

- (void)analyseRequestJSON: (NSDictionary *)JSON {
    NSArray *modelsData = JSON[@"result"];
    NSMutableArray *models = @[].mutableCopy;

    for (NSDictionary *data in modelsData) {
        LXDRecord *record = [[LXDRecord alloc] init];
        record.content = data[@"content"];
        record.recorder = data[@"recorder"];
        record.createDate = data[@"createDate"];
        record.updateDate = data[@"updateDate"];
        [models addObject: record];
    }
}

这是典型的认知错误引发的代码错误放置的错误,对于这种情况,直接常见的做法是在Model中直接加入全能构造器Designed Initializer来将这部分代码转移至Model中:

@interface LXDRecord: NSObject
//properties
- (instancetype)initWithCreateDate: (NSString *)createDate
                        updateDate: (NSString *)updateDate
                           content: (NSString *)content
                          recorder: (NSString *)recorder;
@end

//Controller
- (void)analyseRequestJSON: (NSDictionary *)JSON {
    NSArray *modelsData = JSON[@"result"];
    NSMutableArray *models = @[].mutableCopy;

    for (NSDictionary *data in modelsData) {
        LXDRecord *record = [[LXDRecord alloc] initWithCreateDate: data[@"createDate"]
                                    updateDate: data[@"updateDate"]
                                       content: data[@"content"]
                                      recorder: data[@"recorder"]];
        [models addObject: record];
    }
}

在转移数据->模型这一逻辑处理之后数据层相对而言就充实的多,但这还不够。数据在完成抽象转换的工作之后,通常要展示到视图层面上。但往往模型还需要进行额外的加工才能展示,比如笔者曾经项目中的一个需求:用户在缴纳宽带费用后将宽带办理期间显示出来,这需求建立在服务器只有办理时间办理时长两个字段。在MVC的结构下,将这部分代码放在C层会导致代码过多过于杂乱的后果,因此笔者将其放在Model中:

@interface YQBNetworkRecord: YQBModel

@property (nonatomic, copy, readonly) NSString *dealDate;    //办理时间
@property (nonatomic, copy, readonly) NSString *effectTime;  //办理时长

- (NSString *)timeOfNetworkDuration;

@end

@implementation YQBNetworkRecord

- (NSString *)timeOfNetworkDuration {
    NSTimeInterval effectInterval = [_effectTime stringToInterval];
    return [_dealDate stringByAppendString: [_dealDate dateAfterInterval: effectInterval]];
}

@end

这一做法将一部分C 层次的逻辑放到了M中,由于这一部分的逻辑属于弱业务,属于几乎不会改动的业务逻辑,因此并不会影响MVC的整体结构。但同样也存在着风险:

  • 代码依赖于Model的差异化,复用性低
  • 代码量取决于Model的数量,容易导致胖Model的情况

虽然存在着这些不足,但是如果是在MVC模式下对控制器进行减负的情况下,这种做法简单有效。另外,使用category将这些逻辑代码分离出去可以使得复用性变得不那么的糟。当然上面的数据->模型过程中也存在着因为数据类型变化而导致构造器失效的问题,这时候参考YYModel的做法可以减少或者解决这些问题的发生

文章导航