创建一个工厂factory = new RequestFactory(&info)
,调用工厂中的创建编解码的方法创建编解码对象RequestCodec(m_info)
,命名为codec,再调用codec中的编解码方法encodeMsg()
,对编码对象进行编解码输出到str。
syntax = "proto3";
message RequestMsg
{
int32 cmdType = 1;
bytes clientID = 2;
bytes serverID = 3;
string sign = 4; //此处为客户端信息独有
string data = 5;
}
message RespondMsg
{
int32 status = 1;
int32 seckeyID = 2; //此处为服务端信息独有
bytes clientID = 3;
bytes serverID = 4;
string data = 5;
}
不同的工厂类
对数据信息分别
进行编码
和解码
。CodecFactory* factory = new RequestFactory(&info);
此时根据传参不同,m_flag
区分该工厂初始化为编码或者解码.
RequestFactory::RequestFactory(std::string enc) : CodecFactory()
{
m_flag = false;
m_encStr = enc;
}
RequestFactory::RequestFactory(RequestInfo * info) : CodecFactory()
{
m_flag = true;
m_info = info;
}
codec
。Codec* codec = factory->createCodec();
Codec * RequestFactory::createCodec()
{
Codec* codec = NULL;
if (m_flag) //m_flag = true;,则就是编码对象
{
codec = new RequestCodec(m_info);
}
else
{
codec = new RequestCodec(m_encStr);
}
return codec;
}
RequestCodec::RequestCodec(RequestInfo *info)
{
initMessage(info);
}
void RequestCodec::initMessage(RequestInfo *info)
{
m_msg.set_cmdtype(info->cmd);
m_msg.set_clientid(info->clientID);
m_msg.set_serverid(info->serverID);
m_msg.set_sign(info->sign);
m_msg.set_data(info->data);
}
string str = codec->encodeMsg();
string RequestCodec::encodeMsg()
{
string output;
m_msg.SerializeToString(&output);
return output;
}
工厂: 使用一个单独的类来做创建实例的过程, 这就是工厂。
简单工厂:把对象的创建放到一个工厂类中,通过
参数
来创建不同的对象。
特点:
- 缺点:每添一个对象,就需要对简单工厂进行修改(尽管不是删代码,仅仅是添一个switch case,但仍然违背了“不改代码”的原则)
- 优点:去除了与具体产品的依赖, 实现简单。
# 简单工厂模式的使用:
1. 创建一个工厂类
2. 在这个类中提供一个公共的成员方法
- 创建对象, 一般情况下创建某些实现多态的子类对象
- 返回这个对象的地址
// 通过创建工厂类, 添加工厂函数, 创建对象
// 两个编解码的子类
class RequestCodec : public Codec // 编解码请求数据
class RespondCodec : public Codec // 编解码响应数据
// 创建工厂类, 创建编解码对象
class Factory
{
public:
Factory();
~Factory();
// 工厂函数, 创建对象
// flag==1 -> RequestCodec
// falg==2 -> RespondCodec
Codec* createObject(int flag)
{
Codec* c = NULL;
// 判断
if(flag == 1)
{
c = new RequestCodec();
}
else if(flag == 2)
{
c = new RespondCodec();
}
return c;
}
}
工厂类的使用:
// 1. 创建工厂类对象
Factory* fac = new Factory;
// 2. 通过工厂函数创建编解码对象
Codec* c = fac->createObject(1);
// 3. 编码
string str = c->encoceMsg();
工厂方法:每种产品由一种工厂来创建,一个工厂保存一个new
特点:基本完美,完全遵循 “不改代码”的原则
# 工厂模式流程
1. 创建一个工厂类的基类
2. 在这个基类中定义一个虚函数 -> 创建对象的方法
3. 创建子工厂类(编解码的基类有多少子类, 就创建多少个子工厂类)
- 每个编解码的子类, 都对应一个工厂类
4. 在子工厂类中重写工厂类基类中的虚函数
复制到画图中可放大查看
RequestCodec用于客户端数据的编解码
RespondCodec用于服务端数据的编解码
// 两个编解码的子类
class RequestCodec : public Codec
class RespondCodec : public Codec
class TestCodec : public Codec // 编解码响应数据
父类中右一个虚拟方法,子类继承该方法后需要根据各自需求重写该方法。
// 创建工厂类的基类
class BaseFactory
{
public:
BaseFactory();
~BaseFactory;
virtual Codec* createCodec()
{
//待重写
return NULL;
}
}
// 工厂类子类
class RequestFactory : public BaseFactory
{
public:
RequestFactory();
~RequestFactory;
Codec* createCodec()
{
return new RequestCodec; // 方法重写
}
}
// 工厂类子类
class RespondFactory : public BaseFactory
{
public:
RespondFactory();
~RespondFactory;
Codec* createCodec()
{
return new RespondCodec; // 方法重写
}
}
// 1. 创建工厂类对象
BaseFactory* fac = new RespondFactory;
// 2. 通过工厂创建了编解码对象
Codec* c = fac->createCodec();
// 3. 使用编解码对象对数据进行编解码
string str = c->encodeMsg();