如何写一个对扩展开发对修改关闭的推送消息处理中心?
前一段时间做的推送消息处理,总是要根据不同的消息类型,进入到不同的消息处理流程中。由于消息处理流程的总体框架大同小异,只是具体的很小的一块代码不同。 于是很容易想到使用模板方法模式基类写框架流程,派生类负责具体的实现。
需要有三个类:
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进行不同的处理。
总结:
对扩展开放,可以新建派生类。对修改关闭,不需要对基类以及消息中心有任何改变。
代码包装性比较好。自认为不错的思路,欢迎交流。
好了消息中心的就写到这里。为了自己的小小思想能有一个小的记录。