简单工厂模式+反射动态生产cell

2017-10-27  本文已影响131人  举个栗子wow

最近手头里没太多的工作就把之前的代码整了整,梳理了之前的各种工厂模式,算是又学习了一遍。

简单工厂和工厂模式的区别:
简单工厂在工厂类中融入了逻辑判断,虽然和客户端解耦合但也违背了开放封闭的原则,再添加新功能时要去修改之前的代码;工厂模式则把逻辑从工厂类移到了客户端类,虽然在客户端进行必要的逻辑判断,却可以进行扩展不必修改之前的代码。

因为简单工厂破坏了开放封闭原则需要对原来的代码进行改动,所以这里配合了反射模式来消除这一不利的影响,达到即使不去修改工厂类也能进行扩展的效果。

这里要注意,用反射模式配合需要事先约定好一系列的命名规则。整个逻辑是利用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的控制器直接提取成了一个基类,在简单的页面中直接使用。这种方式使得代码更加精简、耦合度低、复用性高。

上一篇 下一篇

猜你喜欢

热点阅读