iOS-协议-协议的工厂设计模式-多任务需求v1.3-Yxx

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

在键盘上键入正确地咒语,屏幕会活动、变幻,显示出前所未有的也不可能存在的事物!
我先把所有版本文档罗列到这里:
iOS-继承-继承的工厂设计模式-多任务需求v1.1
iOS-继承-继承的工厂设计模式-多任务需求v1.2
iOS-协议-协议的工厂设计模式-多任务需求v1.3
下面我来说下v1.3我们需要做什么,这次没有产品的强制需求,完全为了方便自己而做的优化处理,先看图:

v1.3待办事项

从图中我大概说下优化的点:

  • 1.由之前的接口添加事项,改为全部写plist文件注入,这样就可以统一管理所有的事项,更方便实施者去注入。
  • 2.当登录成功后,只是去做了请求和数据的收集为一个模型数组,但是这个时候不处理业务,让其暂时挂起。因为对于实施者而言,或许他需要在登录后做自己想做的事情,做完才想做原本的事项,也就加了一个业务暂时等待的逻辑,这样做比起之前更加人性化。
  • 3.代码的划分比之前更明确
代码需要做的逻辑

上图是简单的逻辑:

  • 1.v1.2版本的是继承工厂设计模式,但是这个版本就成了代理协议工厂设计模式,这样能够很好地解耦,对于实施者而言,它无需关心我做了什么,他只需要遵循代理协议,做自己想做的事情就ok了,并且自己的业务类需要实现的方法由4个变为1个,这对于实施者更加简单,减少接入成本。
    1. 其实我们要做的事情也就是创建plist,建立数据收集器,建立代理,就是实现这三个东西。
  • 以下是具体代码,先看Delegate:
  • YxxAppPendingTaskDelegate.h
#import <Foundation/Foundation.h>
@class YxxAppLoginWaitWorkingModel;

@protocol YxxAppPendingTaskDelegate <NSObject>

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

@end

协议就一个接口,如果后续有接口,可在协议里面随意添加,大大的扩展性

  • YxxAppPendingClass.h 这个类是将注入的事项分为一个事项一个类,这样处理起来比较容易
#import <Foundation/Foundation.h>
#import "YxxAppPendingTaskDelegate.h"

@interface YxxAppPendingClass : NSObject

@property (nonatomic, copy, readonly) NSString *eventId;
@property (nonatomic, copy, readonly) NSString *className;

- (instancetype)initPendingClassWithEventId:(NSString *)eventId andClassName:(NSString *)className;

@end
  • YxxAppPendingClass.m
#import "YxxAppPendingClass.h"

@implementation YxxAppPendingClass

- (instancetype)initPendingClassWithEventId:(NSString *)eventId andClassName:(NSString *)className
{
    self = [super init];
    if (self) {
        _eventId = eventId;
        _className = className;
    }
    return self;
}
@end
  • YxxAppPendingTaskManage.h 这个类是做注入事项的预处理,基本都是处理数据存数据
#import <Foundation/Foundation.h>

@interface YxxAppPendingTaskManager : NSObject

+ (instancetype)shareInstances;

/**
 * eventId    事件ID
 * className  事件类名
 */
- (void)addAppLoginWaitWorkingWithEventId:(NSString *)eventId andClassName:(NSString *)className;

- (NSString *)searchEventIdWithDoEventId:(NSString *)eventId;

@end
  • YxxAppPendingTaskManage.m
#import "YxxAppPendingTaskManager.h"
#import "YxxAppPendingClass.h"

@interface YxxAppPendingTaskManager ()

@property (nonatomic, copy) NSMutableArray *pendingClassAry;

@end

@implementation YxxAppPendingTaskManager

/**
 *  数组懒加载
 */
- (NSMutableArray *)pendingClassAry
{
    if (!_pendingClassAry) {
        _pendingClassAry = [NSMutableArray array];
    }
    return _pendingClassAry;
}

+ (instancetype)shareInstances
{
    static YxxAppPendingTaskManager *pendingTask = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        pendingTask = [[YxxAppPendingTaskManager alloc] init];
    });
    return pendingTask;
}
//对于实施者,只需要调用这个接口先注入需要做的事项
- (void)addAppLoginWaitWorkingWithEventId:(NSString *)eventId andClassName:(NSString *)className
{
    YxxAppPendingClass *pendingClass = [[YxxAppPendingClass alloc] initPendingClassWithEventId:eventId andClassName:className];
    [self addPendingClassAry:pendingClass];
}

- (void)addPendingClassAry:(YxxAppPendingClass *)pendingClass
{
    [self.pendingClassAry addObject:pendingClass];
}

//通过传入的事件id,找到对应的类名,并返回,以供初始化该类
- (NSString *)searchEventIdWithDoEventId:(NSString *)eventId
{
    if (self.pendingClassAry.count) {
        for (YxxAppPendingClass *pendingClass in self.pendingClassAry) {
            NSLog(@"*******%@",pendingClass.eventId);
            if ([pendingClass.eventId isEqualToString:eventId]) {
                return pendingClass.className;
            }
        }
        return nil;
    }else{
        return nil;
    }
}

@end

  • YxxAppLoginWaitWorking.h 这里类是数据所有的聚合
#import <Foundation/Foundation.h>

@interface YxxAppLoginWaitWorking : NSObject

+ (YxxAppLoginWaitWorking *)initAppLoginWaitWorking;
- (void)showAppLoginWaitWorking;
- (void)manualAddWaitWorking:(NSDictionary *)addWorking;
- (void)deleteWaitWorking:(NSString *)eventId;

@end
  • YxxAppLoginWaitWorking.m 这个类对于之前v1.2版本没有太大变化
@interface YxxAppLoginWaitWorkingDataListModel : HFModel
@property (nonatomic, strong) NSArray *taskList; /**< 信息列表 */
@end

@implementation YxxAppLoginWaitWorkingDataListModel
@end

@interface YxxAppLoginWaitWorking ()

@property (nonatomic, copy) NSMutableArray *waitWorkingModelAry; /**< 保存事件模型 */
@property (nonatomic, weak) id <YxxAppPendingTaskDelegate> delegate;

@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;
        }
    }
    NSString *className = [[YxxAppPendingTaskManager shareInstances] searchEventIdWithDoEventId:minNumModel.eventId];
    if (className) {
        id delegate = [[NSClassFromString(className) alloc] init];
        self.delegate = delegate;
        if ([self.delegate respondsToSelector:@selector(startEvent:)]) {
            [self.delegate 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

对于业务类就很简单了

  • EventOne.h
#import <Foundation/Foundation.h>
#import "EventOne.h"

@interface YxxTestWaitWorking : NSObject <YxxAppPendingTaskDelegate>

@end
  • EventOne.m
#import "EventOne.h"

@implementation PAFFTestWaitWorking

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

@end

到这里所有的待办事项的优化就讲完了,我个人觉得工厂设计模式无非就是,提前注入事情,在业务处理的时候如何找到类并初始化这个类的一个过程,不管是协议的方式,还是继承的方式,也都是这么一个过程,当然我自己从这个业务的出生到成长,我也学习到了思维模式的重要性,一个需求实现起来很简单并不难,但是人性化、扩展性、简洁性、调理的清楚程度,都是值得考虑的范畴,当然也要根据实际业务环境做优化,并不是盲目的优化没用的东西,那也就适得其反了。


原创,请忽随意转载

推荐阅读更多精彩内容