最近手头里没太多的工作就把之前的代码整了整,梳理了之前的各种工厂模式,算是又学习了一遍。
简单工厂和工厂模式的区别:
简单工厂在工厂类中融入了逻辑判断,虽然和客户端解耦合但也违背了开放封闭的原则,再添加新功能时要去修改之前的代码;工厂模式则把逻辑从工厂类移到了客户端类,虽然在客户端进行必要的逻辑判断,却可以进行扩展不必修改之前的代码。
因为简单工厂破坏了开放封闭原则需要对原来的代码进行改动,所以这里配合了反射模式来消除这一不利的影响,达到即使不去修改工厂类也能进行扩展的效果。
这里要注意,用反射模式配合需要事先约定好一系列的命名规则。整个逻辑是利用Model通过工厂反射来创建对应的Cell。
cell基类(每个新产生的cell都要继承cell基类):
.h
#import <UIKit/UIKit.h>
@class JWBaseModel;
@interface JWBaseCell : UITableViewCell
/**
* 用model为cell赋值,基类不做处理,子类重写这个方法
*
* @param model 继承基类的model
*/
- (void)setUpValueForCellWithModel:(JWBaseModel *)model;
/**
* 设置代理
*/
- (void)setUpDelegateWithVC:(id)vc;
.m中两个方法都只是空方法不做任何处理,子类去重写这个方法
#import "JWBaseCell.h"
@implementation JWBaseCell
#pragma mark 用model为cell赋值,基类不作处理
- (void)setUpValueForCellWithModel:(JWBaseModel *)model {
}
#pragma mark 设置代理
- (void)setUpDelegateWithVC:(id)vc {
}
model基类(每个新产生的model都要继承model基类):空类就不贴了,可以自行加一些空值判断或者计算行高之类的基类方法供子类使用
简单工厂类(通过反射来替代传值判断):
.h
#import <Foundation/Foundation.h>
@class JWBaseModel,JWBaseCell;
@interface JWCreatCellManager : NSObject
/**
* 动态创建cell
*
* @param model 继承基类的model
*
* @return 继承基类的cell
*/
+ (JWBaseCell *)creatCellWithModel:(JWBaseModel *)model;
@end
.m 这里要注意一定要有自己的命名规则,在使用时严格按照命名规则来生成类名
下面的代码需要cell和model命名有对应关系 XXXCell ---- XXXModel XXX内容一样
#import "JWCreatCellManager.h"
#import "JWBaseCell.h"
#import "JWBaseModel.h"
@implementation JWCreatCellManager
#pragma mark 动态创建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
在使用时只需要改变创建的model就能自动拿出对应的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;
}
当然我们可以让子类的model具备更多的特性,分散更多的代码,例如基类中增加计算行高的方法在子类中重写。
这种简单工厂+反射的模式使得我不用再去修改工厂类中的代码。我把这种vc中带一个tabview的控制器直接提取成了一个基类,在简单的页面中直接使用。这种方式使得代码更加精简、耦合度低、复用性高。
网友评论