数据库发包
现在就来看看数据库发包模式 这个用到了抽象工厂模式 其实经理的那个差不多都是注册具体工厂到抽象工厂,只是这里不是抽象工厂而是PktFactoryMgr功能和抽象工厂差不多 { #define __REGISTER_DB_PKT_CREATEFUNCTION(DBOptClassType) \ Register<DBOptClassType>(PktSingleFactory<DBOptClassType>::GetOrCreateInstance()); __REGISTER_DB_PKT_CREATEFUNCTION(AskActorList);//注册包工厂到m_vecPktConstructor中 __REGISTER_DB_PKT_CREATEFUNCTION(AskActorInfo); __REGISTER_DB_PKT_CREATEFUNCTION(AskActorInfoEx); __REGISTER_DB_PKT_CREATEFUNCTION(AskUserInfo); } m_vecPktConstructor[pFactory->GetPktID()] = new FnPktCreate(std::bind(&PktSingleFactory<T>::CreatePkt, pFactory)); 我任务PktSingleFactory就相当于具体工厂,将具体工厂类注册金抽象工厂类 void asynDBCenter::GetUserInfo(std::function<void(bool bExist, const ShuiHu::UserInfo& hr)>* fnGetUserInfo, const char* pszName) { //抽象工厂根据注册进去的具体工厂创建具体产品,但有点疑问就是抽象工厂具体工厂可以创建多个具体产品类的实例,但CreatePkt是显示的去new DB::AskUserInfo* pAskPkt = dynamic_cast<DB::AskUserInfo*>(m_pPktFacMgr->CreatePkt(DB::eDBOpt_AskUserInfo)); //InterruptStream流内部封装操作,没什么 DB::InterruptStream SendStream(m_pSendBuffer, eMaxSendBufferSize); DB::DBOptID eOptID = pAskPkt->GetID(); SendStream.CopyIn(&eOptID, sizeof(DB::DBOptID)); // 操作ID pAskPkt->m_uFlag = (unsigned __int64)fnGetUserInfo; // 识别标记 strncpy(pAskPkt->m_aUserName, pszName, MAX_NAME_LEN); pAskPkt->Write(SendStream); //DestroyPkt又显示的delete,每次发包去new,delete容易造成内存碎片 m_pPktFacMgr->DestroyPkt(pAskPkt); PushShmInter(SendStream); }
DBSvr那边根据接收的数据创建介入式流,从其中读取ID创建相应的包,然后从包从介入式流中读取数据,在根据包的ID解析数据访问数据库