先举个例子,我们在开发中,经常会处理很多异步消息,比如:io消息、信号、定时器等,现在我们就建立一个消息处理器系统,代码如下:
struct msg
{
int msg_id;
char data[1];
};
class BaseMsgProcessor
{
public:
virtual int process_msg(struct msg *msg)
{
std::cout << "process general msg/n";
return 0;
}
};
class IOMsg : public BaseMsgProcessor
{
public:
virtual int process_msg(struct msg *msg)
{
std::cout << "process io msg/n";
return 0;
}
};
class TimeOutMsg : public BaseMsgProcessor
{
public:
virtual int process_msg(struct msg *msg)
{
std::cout << "process TimeOutMsg msg/n";
return 0;
}
};
class SignalMsg : public BaseMsgProcessor
{
public:
virtual int process_msg(struct msg *msg)
{
std::cout << "process SignalMsg msg/n";
return 0;
}
};
上面的类结构,相当于像用户暴露了process_msg接口,用户会做如下的使用方法
BaseMsgProcessor * processor = NULL;
//io消息
struct msg m;
m.msg_type = MT_IO;
processor = new IOMsg;
processor->process_msg(&m);
delete processor;
processor = NULL;
//超时消息
m.msg_type = MT_TIMEOUT;
processor = new TimeOutMsg;
processor->process_msg(&m);
delete processor;
processor = NULL;
//处理信号
m.msg_type = MT_SIGNAL;
processor = new SignalMsg;
processor->process_msg(&m);
delete processor;
processor = NULL;
这里的问题在哪里呢?
1、用户需要识别不同的消息处理器,有时这个识别逻辑可能比较复杂,所以容易出错。而原本这个消息处理器体系结构的组织、规划,是程序作者最清楚的。
2、需要负责处理器实例的创建、回收。有时,我们处理器的实例并不是通过简单的new/delete,创建、释放的,所以这个过程容易让用户产生使用上的错误。
如果“消息处理器”的作者,把整个使用过程都提供出来,就可以易用许多。如下:
enum msg_type
{
MT_IO,
MT_TIMEOUT,
MT_SIGNAL
};
struct msg
{
int msg_id;
int msg_type;
char data[1];
};
class BaseMsgProcessor
{
public:
static int process(struct msg *msg)
{
BaseMsgProcessor * processor = Factory(msg->msg_type);
if (!processor)
return -1;
struct msg m;
int r = processor->process_msg(&m);
delete processor;
processor = NULL;
return r;
}
static BaseMsgProcessor * Factory(int msg_type)
{
BaseMsgProcessor *process = NULL;
switch(msg_type)
{
case MT_IO:
process = new IOMsg;
case MT_SIGNAL:
process = new SignalMsg;
case MT_TIMEOUT:
process = new TimeOutMsg;
default:
;
}
return process;
}
private:
virtual int process_msg(struct msg *msg)
{
std::cout << "process general msg/n";
return 0;
}
};
class IOMsg : public BaseMsgProcessor
{
private:
virtual int process_msg(struct msg *msg)
{
std::cout << "process io msg/n";
return 0;
}
};
class TimeOutMsg : public BaseMsgProcessor
{
private:
virtual int process_msg(struct msg *msg)
{
std::cout << "process TimeOutMsg msg/n";
return 0;
}
};
class SignalMsg : public BaseMsgProcessor
{
private:
virtual int process_msg(struct msg *msg)
{
std::cout << "process SignalMsg msg/n";
return 0;
}
};
用户只需要调用一下process,不用关心 process内部的细节
struct msg m;
BaseMsgProcessor::process(&m);