首页 > 代码库 > object-c编程tips

object-c编程tips

如何写一个对扩展开发对修改关闭的推送消息处理中心?

前一段时间做的推送消息处理,总是要根据不同的消息类型,进入到不同的消息处理流程中。由于消息处理流程的总体框架大同小异,只是具体的很小的一块代码不同。 于是很容易想到使用模板方法模式基类写框架流程,派生类负责具体的实现。


需要有三个类:

LPPushDispatchCenter: 消息处理中心类

LPPushDispatch :消息处理基类

LPDetailPushDispatch(很多很多个这样的派生类): 消息处理派生类


所有的消息首先进入消息处理中心,它实现为一个单例类,是为了外部更方便的使用。它保存了消息类型和对应的派生类对象的映射。

当需要handleMessage时候,它根据消息的类型找到具体的消息处理派生类对象,然后创建相应的对象,进行具体的处理。如何保存消息类型和处理对象的映射呢? 刚开始的时候实现的比较简单,直接switch case, 根据type返回不同的类对象。 现在仔细看了类对象的加载过程,发现load方法会在类对象加载的时候调用,于是联想到可以在派生类中的load方法告知自己的type,并将自身type和class绑定注册到消息中心中。


消息中心的主要方法:

#pragma mark 单例方法
//单例
+(LPPushDispatchCenter*)shareInstance
{
    static dispatch_once_t onceToken;
    static LPPushDispatchCenter *pushCenter = nil;
    dispatch_once(&onceToken, ^{
        pushCenter = [[self alloc] init];
    });
    return pushCenter;
}

-(id)init
{
    if(self = [super init]){
        _typeAndClassDic = [[NSMutableDictionary alloc]init];
    }
    return self;
}


-(void)registerPushType:(NSInteger)type andClass:(Class)typeClass
{
    if(_typeAndClassDic[@(type)]){
        NSLog(@"ERROR: type(%ld) has same class", type);
        return;
    }
    _typeAndClassDic[@(type)] = typeClass;
}
-(void)handleMessage:(LPPushMessage*)msg
{
    NSInteger type = msg.type;
    Class typeClass = _typeAndClassDic[@(type)];
    if (typeClass) {
        LPPushDispatch* dispatch = [[typeClass alloc]init];
        dispatch.pushMessage = msg;
        [dispatch handlePushMessage];
    }
    else{
        NSLog(@"handleMessageWithType: unknown type(%ld)", type);
    }
}

消息中心只有一个外部方法,handleMessage,它传入msg, 根据msg的type类型在_typeAndClassDic中找到对应的class类对象,创建对应的对象,赋值pushMessage参数,调用LPPushDispatch的handlePushMessage方法。


LPPushDispatch基类框架:

+(void)setType:(NSInteger)type
{
    [[LPPushDispatchCenter shareInstance] registerPushType:type andClass:[self class]];
}
/** 处理推送消息 */
-(void)handlePushMessage
{
    BOOL isNeedHandle = [self beforeHandleMessage];
    if(isNeedHandle){
        [self handlingPushMessage];
        [self afterHandleMessage];
    }
}

//预处理
-(BOOL)beforeHandleMessage
{
    return YES;
}
//正在处理
-(void)handlingPushMessage
{
    [self openMessage];
}
//后处理
-(void)afterHandleMessage
{

}

它提供了一个setType方法供派生类调用,派生类调用setType来将自己的type和class注册到LPPushDispatchCenter中。真正的处理方法是handlingPushMessage,它里面调用派生类的openMessage方法。


再看LPDetailPushDispatch派生类:

+(void)load
{
    DLog(@"");
    self.type = 0;
}

- (void)openMessage {
    DLog(@"%@", self.pushMessage);
}
它使用self.type调用基类的setType方法,将自己注册到消息中心类的字典中。 同时还需要实现的有openMessage方法,它根据不同self.pushMessage进行不同的处理。


总结:

对扩展开放,可以新建派生类。对修改关闭,不需要对基类以及消息中心有任何改变。

代码包装性比较好。自认为不错的思路,欢迎交流。


好了消息中心的就写到这里。为了自己的小小思想能有一个小的记录。