iOS开发

iOS 工厂模式的简单使用

2019-05-27  本文已影响2人  yitez

这里使用的是简单工厂模式。

简单工厂模式的定义:
简单工厂模式是属于创建型模式,简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式。

简单工厂模式的使用:
我们在UITableView的协议方法里经常可以看到这样代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    if(indexPath.row==0) {
        EEvaluteUserInfoTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"EEvaluteUserInfoTableViewCell"];
        return cell;
    }
    else if(indexPath.row==1){
        EEvaluteTipLineTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"EEvaluteTipLineTableViewCell"];
        return cell;
        
    }
  else {
        EEvaluteTextViewTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"EEvaluteTextViewTableViewCell"];
        return cell;
    }
}

更有甚者可以达到十几种以上的cell存在(比如聊天界面),这样的话相关类的代码量就会变得十分庞大。
这种情况我们就可以使用简单工厂模式来搭建。

解决方案:
我们还是以聊天界面为例:
首先我们创建一个批量获取界面模型的工厂,用来根据不同的数据模型返回不同的界面模型:

#import "KKMessageCellFactory.h"
@implementation KKMessageCellFactory
- (KKBaseMessageCell *)getMessageCellFromModel:(KKBaseMessageModel *)model forTableView:(UITableView *)tableView {
    NSString *cellName = [model cellName];
    NSString *identifier = [NSString stringWithFormat:@"%@_Id",cellName];
    KKBaseMessageCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    if(!cell) {
        [tableView registerClass:NSClassFromString(cellName) forCellReuseIdentifier:identifier];
        cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    }
    return cell;
}
@end

然后我们创建两个基类,一个界面基类,一个数据模型的基类。基类提供方法由子类重写实现。

@interface KKBaseMessageCell : UITableViewCell
#cell赋值
- (void)setDataModel:(KKBaseMessageModel *)model;  
@end
@interface KKBaseMessageModel : NSObject
// model对应的cell的类名
- (NSString *)cellName;
// 数据对应的界面元素的尺寸。
- (CGSize)dataSizeForMessage;
@end

接下来我们就可以创建子类了。
创建KKTextMessageModel,KKImageMessageModel,KKVideoMessageModel分别对应KKTextMessageCell,KKImageMessageCell,KKVideoMessageCell。
model子类里面实现方法:

@implementation KKTextMessageModel
- (NSString *)cellName {
    return @"KKTextMessageCell";
}

- (CGSize)dataSizeForMessage {
    return CGSizeMake([UIScreen mainScreen].bounds.size.width, 50);
}

cell子类里面实现:

- (void)setDataModel:(KKBaseMessageModel *)model {
    self.textLabel.text = @"文本消息";
}

然后我们就可以实现controller里面的协议方法了:

#这里是模拟数据
- (void)getDataArray {
    KKTextMessageModel *textModel = [KKTextMessageModel new];
    KKImageMessageModel *imageModel = [KKImageMessageModel new];
    KKVideoMessageModel *videoModel = [KKVideoMessageModel new];
    _dataArray = @[textModel,imageModel,videoModel,imageModel,textModel,videoModel].mutableCopy;
}

#pragma mark  UITableView-delegate
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.dataArray.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    KKBaseMessageModel *model = self.dataArray[indexPath.row];
    KKBaseMessageCell *cell = [self.cellFactory getMessageCellFromModel:model forTableView:tableView];
    [cell setDataModel:model];
    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    KKBaseMessageModel *model = self.dataArray[indexPath.row];
    CGSize dataSize = [model dataSizeForMessage];
    
    return dataSize.height-10;
}

这样的代码看起来就简洁多了。

上一篇下一篇

猜你喜欢

热点阅读