iOS-继承-继承的工厂设计模式-多任务需求v1.2-Yxx

先声明,这篇文章并非是讲什么是继承什么是工厂模式,而是根据我工作的实际场景和优化思路做的总结

在键盘上键入正确地咒语,屏幕会活动、变幻,显示出前所未有的也不可能存在的事物!
我先把所有版本文档罗列到这里:
iOS-继承-继承的工厂设计模式-多任务需求v1.1
iOS-继承-继承的工厂设计模式-多任务需求v1.2
iOS-协议-协议的工厂设计模式-多任务需求v1.3

我先直接介绍下v1.2版本的产品需求:


iOS-继承-继承的工厂设计模式-多任务需求v1.2-Yxx_第1张图片
待办事项v1.2

看图可知,对于版本v1.1中的需求,就新加了一个添加待办事项和删除待办事项的逻辑,首先我说下为什么我们会有这种奇葩的需求产生,我们做的App全部是以模块开发,每个模块都有各自功能,然后对接非常多的需求商,中间有实施者接入我们的模块,然后给需求商,也就是说,我这里模块可能有N多需求商的App在使用,这中间避免不了需求商的个性化需求,那么这个需求接口就是给他们自由添加删除事项。

一开始在做这个需求的时候,我是完全在v1.1版本上面去做的添加,无非就是增加两个接口给外部,他们实施者可以添加事情进来,有添加就有删除,很简单的道理,添加的事项是在App打开的时候就给进来的,那么相当于每次App打开都会去添加这个事项,但是或许我只是需要这个事项在第一次登陆才出现,那么删除接口就有用了。至于实施者是需要什么时候删除,以及删除的规则都是由他自己去定,我只提供逻辑。

在v1.1版本中,大家还记得我是使用的三个数组分别存储各类数据,在这里给自己留坑了:
坑1. 当删除事项的时候,你会发现很麻烦,你需要依次找到各个数组下面的值,依次删除其中数据,
坑2. v1.1版本的所有业务处理都是写在我的YxxAppLoginWaitWorking.m中的,那么实施者每添加一个事项就需要在YxxAppLoginWaitWorking.m中写代码,这样就违背了模块化开发了。

对于这两个坑,在我们小组讨论后,优化方案是这样的:
1.将业务、网络请求事项、手动加入事项、删除事项全部分开处理
2.将三个数组取出,只用一个数组去做操作

具体看下面代码和注释:

  • YxxAppLoginWaitWorking.h
#import 
@interface YxxAppLoginWaitWorking : NSObject
//初始化
+ (YxxAppLoginWaitWorking *)initAppLoginWaitWorking;
//调用业务逻辑
- (void)showAppLoginWaitWorking;
//手动添加事项
- (void)manualAddWaitWorking:(NSDictionary *)addWorking;
//手动删除事项
- (void)deleteWaitWorking:(NSString *)eventId;

@end
  • YxxAppLoginWaitWorking.m
@interface YxxAppLoginWaitWorkingDataListModel : HFModel
@property (nonatomic, strong) NSArray *taskList; /**< 信息列表 */
@end

@implementation YxxAppLoginWaitWorkingDataListModel
@end

@interface YxxAppLoginWaitWorking ()
//相比v1.1版本这里只保存模型数组
@property (nonatomic, copy) NSMutableArray *waitWorkingModelAry; /**< 保存事件模型 */

@end

@implementation YxxAppLoginWaitWorking
/**
 *  数组懒加载
 */
- (NSMutableArray *)waitWorkingModelAry
{
    if (!_waitWorkingModelAry) {
        _waitWorkingModelAry = [NSMutableArray array];
    }
    return _waitWorkingModelAry;
}
/**
 *  单例初始化
 */
+ (YxxAppLoginWaitWorking *)initAppLoginWaitWorking
{
    static YxxAppLoginWaitWorking *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[YxxAppLoginWaitWorking alloc] init];
    });
    return sharedInstance;
}
/**
 *  开始事项
 */
- (void)showAppLoginWaitWorking
{
    //监听登陆态
    [RACObserve([YxxAppContext instance], isLogin) subscribeNext:^(id x) {
        if ([x boolValue]){
            //添加本地手势事项
            NSDictionary *dict = @{@"eventId":@"事件5",@"eventPri":@"1011"};
            //手动添加数据
            [self manualAddWaitWorking:dict];
            //网络请求数据
            [self requestWaitWorking];
        }
    }];
}
/**
 *  手动添加待办事项
 */
- (void)manualAddWaitWorking:(NSDictionary *)addWorking
{
    YxxAppLoginWaitWorkingModel *loginWorkingModel=nil;
    NSError *err;
    //这里是手动加入的本地登陆事项
    if (addWorking) {
        if (addWorking[@"eventId"] || addWorking[@"eventPri"]) {
            //去重操作,防止多次添加同一个事件
            for (loginWorkingModel in self.waitWorkingModelAry) {
                if ([loginWorkingModel.eventId isEqualToString:addWorking[@"eventId"]]) {
                    return;
                }
            }
            loginWorkingModel = [MTLJSONAdapter modelOfClass:[YxxAppLoginWaitWorkingModel class] fromJSONDictionary:addWorking error:&err];
            loginWorkingModel.waitWorkingType = waitWorkingManualAdd;
            [self.waitWorkingModelAry addObject:loginWorkingModel];

        }else{
            LogError(@"取!手动加入的本地登陆事项,为空或者缺少字段");
        }
    }
}
/**
 *  手动删除待办事项(这里删除只是排除在app没有退出的情况,用户重新登录,而会再次处理待办事项)
 */
- (void)deleteWaitWorking:(NSString *)eventId
{
    NSMutableArray *copyAry =  [NSMutableArray arrayWithArray:self.waitWorkingModelAry];
    for (YxxAppLoginWaitWorkingModel *deleteModel in self.waitWorkingModelAry) {
        if ([deleteModel.eventId isEqualToString:eventId]) {
            [self.waitWorkingModelAry removeObject:copyAry];
        }
    }
    [self.waitWorkingModelAry removeAllObjects];
    [self.waitWorkingModelAry addObjectsFromArray:copyAry];
    [copyAry removeAllObjects];
}
/**
 *  网络请求
 */
- (void)requestWaitWorking
{
    [request sendRequest:^(YxxRequestModel *requestModel, NSError *error) {
        NSError *err;
        YxxAppLoginWaitWorkingModel *waitWorkingModel=nil;
        NSMutableArray *separationEvent = [NSMutableArray array];//存储待办事项接口下来的数据,以方便只删除此数据
        if (error){
            //接口失败了,也要处理其他端口获取的待办事项
            if (self.waitWorkingModelAry.count) {
                [self eventProcessing];
            }
            LogError(@"接口请求失败");
            return;
        }else{
            id model = requestModel.dataModel;
            if ([model isKindOfClass:[YxxAppLoginWaitWorkingDataListModel class]]) {
                NSArray *taskList = ((YxxAppLoginWaitWorkingDataListModel *)model).taskList;
                //判断有数据才存数组
                if (taskList.count) {
                    for (NSDictionary *dict in taskList) {
                        waitWorkingModel = [MTLJSONAdapter modelOfClass:[YxxAppLoginWaitWorkingModel class] fromJSONDictionary:dict error:&err];
                        //过滤缺少字段的情况
                        if (waitWorkingModel.eventPri && waitWorkingModel.eventId && waitWorkingModel.eventStep) {
                            waitWorkingModel.waitWorkingType = waitWorkingRequest;
                            [self.waitWorkingModelAry addObject:waitWorkingModel];
                        }else{
                            LogError(@"后台数据缺少字段,待办事项不做处理,谢谢");
                        }
                    }
                }
                // 代办事项处理
                [self eventProcessing];
            }
        }
    }];
}
/**
 *  待办事项的事件处理逻辑
 */
- (void)eventProcessing
{
    //判空处理
    if (self.waitWorkingModelAry.count == 0) {
        return;
    }
    //  取优先级最高的,即eventPri最小的
    YxxAppLoginWaitWorkingModel *minNumModel = self.waitWorkingModelAry[0];
    for (YxxAppLoginWaitWorkingModel *model in self.waitWorkingModelAry) {
        if ([model.eventPri integerValue] < [minNumModel.eventPri integerValue]) {
            minNumModel = model;
        }
    }
    //所有事项的父辈
    YxxDoWaitWorkingBaseClass *doWaitWorking = [YxxDoWaitWorkingBaseClass createClichClassWithEventId:minNumModel.eventId];
    [doWaitWorking startEvent:minNumModel];
    
    // 做完待办事项后,删除
    // 服务器代办事项做完后,删除服务器拿到的代办事项
    NSMutableArray *copyAry =  [NSMutableArray arrayWithArray:self.waitWorkingModelAry];
    for (YxxAppLoginWaitWorkingModel *deleteModel in self.waitWorkingModelAry) {
        if (deleteModel.waitWorkingType == waitWorkingRequest || deleteModel.waitWorkingType == waitWorkingAccessLogin) {
            [copyAry removeObject:deleteModel];
        }
    }
    [self.waitWorkingModelAry removeAllObjects];
    [self.waitWorkingModelAry addObjectsFromArray:copyAry];
    [copyAry removeAllObjects];
}

@end
  • YxxDoWaitWorkingBaseClass.h
@interface YxxDoWaitWorkingBaseClass : NSObject

/**
 *  在编译的过程中,子类的load方法调用,主要是得到一个字典存入数组中
 */
void registerWaitEvent(Class eventClass, NSString *eventPri);

/**
 *  得到一个子类的类名
 */
NSString *classsNameStringWithEventId(NSString *eventPri);

/**
 *  初始化
 *  eventId : 将优先级最高的id传入
 */
+(instancetype)createClichClassWithEventId:(NSString *)eventPri;

/**
 *  类方法,子类在编译的时候会存入事件的id
 */
+(NSString *)eventId;

/**
 *  事件需要做得事情
 */
-(void)startEvent:(YxxAppLoginWaitWorkingModel *)model;

/**
 *  清除待办事项请求
 */
- (void)cancelWaitWorkingRequest:(NSString *)eventId;

@end
  • YxxDoWaitWorkingBaseClass.m
#import "YxxDoWaitWorkingBaseClass.h"
#import "YxxRequest.h"

static NSMutableArray *eventIdAry;
/**
 *  在编译的过程中,子类的load方法调用,主要是得到一个字典存入数组中
 */
NSString *classsNameStringWithEventId(NSString *eventId){
    if (eventIdAry.count) {
        for (NSDictionary *dict in eventIdAry) {
            NSArray *eventIdKeyAry = [dict allKeys];
            if ([eventIdKeyAry[0] isEqualToString:eventId]) {
                return dict[eventIdKeyAry[0]];
            }
        }
    }else{
        return nil;
    }
}

@implementation YxxDoWaitWorkingBaseClass
//根据出入的优先级找到对应事项,然后返回对应事项子类
+(instancetype)createClichClassWithEventId:(NSString *)eventPri
{
    NSString *className = classsNameStringWithEventId(eventPri);
    if (className) {
        return [[NSClassFromString(className) alloc] init];
    }
    return nil;
}

void registerWaitEvent(Class eventClass, NSString *eventId){
    if (eventId == nil) {
        return;
    }
    if (eventIdAry == nil) {
        eventIdAry = [NSMutableArray array];
    }
    [eventIdAry addObject:@{eventId:NSStringFromClass(eventClass)}];
    
}

+(NSString*)eventId
{
    return nil;//事件优先级
}

-(void)startEvent:(YxxAppLoginWaitWorkingModel *)model
{
    NSLog(@"%@",model);
}

/**
 *  清除待办事项请求
 */
- (void)cancelWaitWorkingRequest:(NSString *)eventId
{
     NSLog(@"%@",和服务器沟通清除事项);
}

@end

对于子类需要实现四个接口

  • YxxEventOne.h
@interface YxxTestWaitWorking : YxxDoWaitWorkingBaseClass

@end
  • YxxEventOne.m
#import "YxxEventOne.m"

@implementation YxxTestWaitWorking

+ (void)load
{
    registerWaitEvent(self, [self eventId]);
}

+ (NSString *)eventId
{
    return @"eventOne";
}

- (void)startEvent:(YxxAppLoginWaitWorkingModel *)model
{
   NSLog(@"%@",写你需要做的事情,事件1);
}

@end
  • YxxEventTwo.h
@interface YxxTestWaitWorking : YxxDoWaitWorkingBaseClass

@end
  • YxxEventTwo.m
#import "YxxEventTwo.m"

@implementation YxxTestWaitWorking

+ (void)load
{
    registerWaitEvent(self, [self eventId]);
}

+ (NSString *)eventId
{
    return @"eventTwo";
}

- (void)startEvent:(YxxAppLoginWaitWorkingModel *)model
{
   NSLog(@"%@",写你需要做的事情,事件2);
}

@end

如果你看懂了上面的逻辑,那么就能够看出,这种方式可以无限扩张,业务的灵活性打打提升。对于我自己的模块我不用在乎实施者的具体业务,我只要求实施者的业务继承我的父类,按照父类实现规定接口即可!相比v1.1版本代码逻辑条理性有所提升,可扩展性大幅提升,我觉得对于代码的优化,无非就是用最简洁的代码,写出更好的逻辑。后面还有一次优化,比现在的v1.2还有清晰
iOS-协议-协议的工厂设计模式-多任务需求v1.3


原创,请忽随意转载

你可能感兴趣的:(iOS-继承-继承的工厂设计模式-多任务需求v1.2-Yxx)