## 模型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`的做法可以減少或者解決這些問題的發生