最近手頭里沒(méi)太多的工作就把之前的代碼整了整,梳理了之前的各種工廠模式蒸其,算是又學(xué)習(xí)了一遍顾患。
簡(jiǎn)單工廠和工廠模式的區(qū)別:
簡(jiǎn)單工廠在工廠類中融入了邏輯判斷,雖然和客戶端解耦合但也違背了開(kāi)放封閉的原則产阱,再添加新功能時(shí)要去修改之前的代碼;工廠模式則把邏輯從工廠類移到了客戶端類块仆,雖然在客戶端進(jìn)行必要的邏輯判斷构蹬,卻可以進(jìn)行擴(kuò)展不必修改之前的代碼。
因?yàn)楹?jiǎn)單工廠破壞了開(kāi)放封閉原則需要對(duì)原來(lái)的代碼進(jìn)行改動(dòng)悔据,所以這里配合了反射模式來(lái)消除這一不利的影響庄敛,達(dá)到即使不去修改工廠類也能進(jìn)行擴(kuò)展的效果。
這里要注意科汗,用反射模式配合需要事先約定好一系列的命名規(guī)則藻烤。整個(gè)邏輯是利用Model通過(guò)工廠反射來(lái)創(chuàng)建對(duì)應(yīng)的Cell。
cell基類(每個(gè)新產(chǎn)生的cell都要繼承cell基類):
.h
#import <UIKit/UIKit.h>
@class JWBaseModel;
@interface JWBaseCell : UITableViewCell
/**
* 用model為cell賦值头滔,基類不做處理怖亭,子類重寫這個(gè)方法
*
* @param model 繼承基類的model
*/
- (void)setUpValueForCellWithModel:(JWBaseModel *)model;
/**
* 設(shè)置代理
*/
- (void)setUpDelegateWithVC:(id)vc;
.m中兩個(gè)方法都只是空方法不做任何處理,子類去重寫這個(gè)方法
#import "JWBaseCell.h"
@implementation JWBaseCell
#pragma mark 用model為cell賦值坤检,基類不作處理
- (void)setUpValueForCellWithModel:(JWBaseModel *)model {
}
#pragma mark 設(shè)置代理
- (void)setUpDelegateWithVC:(id)vc {
}
model基類(每個(gè)新產(chǎn)生的model都要繼承model基類):空類就不貼了兴猩,可以自行加一些空值判斷或者計(jì)算行高之類的基類方法供子類使用
簡(jiǎn)單工廠類(通過(guò)反射來(lái)替代傳值判斷):
.h
#import <Foundation/Foundation.h>
@class JWBaseModel,JWBaseCell;
@interface JWCreatCellManager : NSObject
/**
* 動(dòng)態(tài)創(chuàng)建cell
*
* @param model 繼承基類的model
*
* @return 繼承基類的cell
*/
+ (JWBaseCell *)creatCellWithModel:(JWBaseModel *)model;
@end
.m 這里要注意一定要有自己的命名規(guī)則,在使用時(shí)嚴(yán)格按照命名規(guī)則來(lái)生成類名
下面的代碼需要cell和model命名有對(duì)應(yīng)關(guān)系 XXXCell ---- XXXModel XXX內(nèi)容一樣
#import "JWCreatCellManager.h"
#import "JWBaseCell.h"
#import "JWBaseModel.h"
@implementation JWCreatCellManager
#pragma mark 動(dòng)態(tài)創(chuàng)建cell
+ (JWBaseCell *)creatCellWithModel:(JWBaseModel *)model {
//提取類名
NSString *className = NSStringFromClass([model class]);
//處理類名
NSString *resultName = [className stringByReplacingOccurrencesOfString:@"Model" withString:@"Cell"];
Class objectClass = NSClassFromString(resultName);
JWBaseCell *cell = [[objectClass alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:className];
return cell;
}
@end
在使用時(shí)只需要改變創(chuàng)建的model就能自動(dòng)拿出對(duì)應(yīng)的cell早歇,返回cell的代碼如下:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
JWBaseModel *model = _dataArray[indexPath.row];
JWBaseCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([model class])];
if (!cell) {
cell = [JWCreatCellManager creatCellWithModel:model];
}
[cell setUpDelegateWithVC:self];
[cell setUpValueForCellWithModel:model];
return cell;
}
當(dāng)然我們可以讓子類的model具備更多的特性倾芝,分散更多的代碼讨勤,例如基類中增加計(jì)算行高的方法在子類中重寫。
這種簡(jiǎn)單工廠+反射的模式使得我不用再去修改工廠類中的代碼晨另。我把這種vc中帶一個(gè)tabview的控制器直接提取成了一個(gè)基類潭千,在簡(jiǎn)單的頁(yè)面中直接使用。這種方式使得代碼更加精簡(jiǎn)借尿、耦合度低刨晴、復(fù)用性高。