①简单工厂:
介绍:比如游戏里面任何一个obj都是一个实体Entity,这个Entity就是父类,子类就是怪物Monster、玩家Player、NPC、静态物品Doodad
构成:一个实体父类Entity、三个子类(每个子类有自己的构造函数)、一个怪物工厂类(根据传入参数静态方法生成怪物)
总结:每个构造函数实现了创建怪物的流程,实现不同对象的业务逻辑代码隔离
②工厂方法:
介绍:如果怪物是雨林、城市、沙漠,玩家的职业如果是盗贼、剑士、狂战士等等,那么写那么多细化的类
③抽象工厂:
介绍:由于新增的工厂类是工厂模式必须付出的代价,不太可取,可以简化成人物类、怪物类、静态物品类(尽可能的缩小类的范围,减少重复的可以抽象简化的类)
介绍:通过一个对象克隆出一摸一样的对象
构成:
一个怪物父类Mosnter(创建Monster是虚函数,子类实现)、静态物品类玩家类NPC类调用各个类的构造函数,返回Monster对象(记得在子类自己写拷贝构造函数,不然两个对象都是同一个,但是之前的对象已经在函数结束的时候析构了)
//深拷贝
Stack(const Stack& st) {
_array = (DataType*)malloc(sizeof(DataType) * st._capacity);
if (_array == nullptr) {
perror("malloc fail");
return;
}
//只需要自己创建一块与st1相同大小的堆空间,其他的还是拷贝st1的数据
memcpy(_array, st._array, _capacity = st._capacity);
_size = st._size;
_capacity = st._capacity;
}
用途:通常用来构建一个比较复杂的对象,一般是按照一定顺序分步步骤进行(比如构建服务器之间的消息体,有些是自定义消息,有些是protobuf二进制消息)
注意:①虚函数不能放在构造或析构函数里面
构成:日报包括标题、内容、结尾
①日报的标题构造类、②日报的内容构造类、③日报的结尾类、④利用三个类构造日报的导出类(这里有时候需要导出XML
,有时候导出文本
,那么就可以抽象出父类和子类,如下)
FileBuider* pfb = new TxtFileBuilder(); //父类指针指向子类对象,txt导数类和文本导出类继承自FileBuider
FileDirector* pDtr = new FileDirectore(pfb);//FileDirector是文本管理类
cout<< pDtr->Construct(xxx)<
①头文件
#pragma once
#include
#include
using namespace std;
class DailyHeaderData
{
public:
DailyHeaderData(string strDepName,string strGenDate)
:m_strDepName(strDepName),m_strGenDate(strGenDate){}
public:
string getDepName() { return m_strDepName; }
string getGenDate() { return m_strGenDate; }
private:
string m_strDepName;
string m_strGenDate;
};
class DailyContentData
{
public:
DailyContentData(string strContent, double dspendTime)
:m_strContent(strContent),m_dspendTime(dspendTime){}
public:
string getContent() { return m_strContent; }
double getDependTime() { return m_dspendTime; }
private:
string m_strContent;
double m_dspendTime;
};
class DailyFootData
{
public:
DailyFootData(string strUserName)
:m_strUserName(strUserName){}
public:
string getUserName()
{
return m_strUserName;
}
private:
string m_strUserName;
};
///
/// 文件构建着
///
class CFileBuilder
{
public:
virtual ~CFileBuilder(){}
public:
virtual void buildHeader(DailyHeaderData& dailyheaderobj) = 0;
virtual void buildBody(vector<DailyContentData*>& vec_dailyConObj) = 0;
virtual void buildFooter(DailyFootData& dailyfooterobj) = 0;
string getResult()
{
return m_strResult;
}
protected:
string m_strResult;
};
//纯文本构建器
class TxtFileBuilder :public CFileBuilder
{
public:
virtual void buildHeader(DailyHeaderData& dailyheaderobj)
{
m_strResult += dailyheaderobj.getDepName() + "," + dailyheaderobj.getGenDate() + "\n";
}
virtual void buildBody(vector<DailyContentData*>& vec_dailyConObj)
{
for (auto iter = vec_dailyConObj.begin();iter != vec_dailyConObj.end();++iter)
{
ostringstream oss;
oss << (*iter)->getDependTime();
m_strResult += (*iter)->getContent() + ":(花费时间:" + oss.str() + "小时)" + "\n";
}
}
virtual void buildFooter(DailyFootData& dailyfooterobj)
{
m_strResult += "报告人:" + dailyfooterobj.getUserName() + "\n";
}
};
//XML构建器
class XmlFileBuilder :public CFileBuilder
{
public:
virtual void buildHeader(DailyHeaderData& dailyheaderobj)
{
m_strResult += "\n";
m_strResult += "\n" ;
m_strResult += "\n" ;
m_strResult += "" + dailyheaderobj.getDepName() + "\n";
m_strResult += "" + dailyheaderobj.getGenDate() + "\n";
m_strResult += "\n";
}
virtual void buildBody(vector<DailyContentData*>& vec_dailyConObj)
{
for (auto iter = vec_dailyConObj.begin(); iter != vec_dailyConObj.end(); ++iter)
{
ostringstream oss;
oss << (*iter)->getDependTime();
m_strResult += (*iter)->getContent() + ":(花费时间:" + oss.str() + "小时)" + "\n";
}
}
virtual void buildFooter(DailyFootData& dailyfooterobj)
{
m_strResult += ";
m_strResult += "报告人:" + dailyfooterobj.getUserName() + "\n";
m_strResult += "<\Footer>\n";
m_strResult += "\n";
}
};
文件指挥者
class CFileDirector
{
public:
CFileDirector(CFileBuilder* ptmpBuider)
:m_pFileBuilder(ptmpBuider){}
public:
//组装文件
string Construct(DailyHeaderData& dailyheadobj,vector<DailyContentData*>& vec_dailyconobj,DailyFootData& dailyfooterobj)
{
m_pFileBuilder->buildHeader(dailyheadobj);
m_pFileBuilder->buildBody(vec_dailyconobj);
m_pFileBuilder->buildFooter(dailyfooterobj);
return m_pFileBuilder->getResult();
}
private:
CFileBuilder* m_pFileBuilder;
};
②main函数
#include
#include
#include
#include
#include "Fighter.h"
using namespace std;
int main()
{
DailyHeaderData* pdhd = new DailyHeaderData("研发一部", "11月1日");
DailyContentData* pdcd1 = new DailyContentData("完成A项目的需求分析工作", 3.5);
DailyContentData* pdcd2 = new DailyContentData("确定A项目的需求分析工作", 4.5);
vector<DailyContentData*> vec_dcd;
vec_dcd.push_back(pdcd1);
vec_dcd.push_back(pdcd2);
DailyFootData* pdata = new DailyFootData("小李");
CFileBuilder* pfb = new TxtFileBuilder();
CFileDirector* pDtr = new CFileDirector(pfb);
std::cout << pDtr->Construct(*pdhd,vec_dcd,*pdata) << std::endl;
return 0;
}
①使用者
②物品
③main函数
①使用者
#ifndef __FIGHTER__
#define __FIGHTER__
//补血丹类型
enum ItemAddLife
{
IAL_MIN,
IAL_BXD,
IAL_DHD,
IAL_SHD,
IAL_MAX,
};
class CItemStrategy;
//战斗者父类
class CFighter
{
public:
explicit CFighter(int life,int magic,int attack)
:m_life(life),m_magic(magic),m_attack(attack){}
virtual ~CFighter() {}
void SetItemStrategy(CItemStrategy* strategy);
void UseItem();
int GetLife();
void SetLife(int life);
private:
int m_life;
int m_magic;
int m_attack;
CItemStrategy* pItemStrategy = nullptr;
};
//战士类
class F_Warrior :public CFighter
{
public:
F_Warrior(int life,int magic,int attack)
:CFighter(life,magic,attack){}
};
//魔法师类
class F_Mage :public CFighter
{
public:
F_Mage(int life, int magic, int attack)
:CFighter(life, magic, attack) {}
};
void CFighter::SetItemStrategy(CItemStrategy* itemStrategy)
{
pItemStrategy = itemStrategy;
}
void CFighter::UseItem()
{
pItemStrategy->useItem(this);
}
int CFighter::GetLife()
{
return m_life;
}
void CFighter::SetLife(int life)
{
m_life = life;
}
#endif // !_FIGHTER
②物品
#ifndef __ITEMSTRATEGY__
#define __ITEMSTRATEGY__
class CFighter;
class CItemStrategy
{
public:
virtual void useItem(CFighter* mainobj) = 0;
virtual ~CItemStrategy(){}
};
//+200
class CItemS_BXD:public CItemStrategy
{
public:
virtual void useItem(CFighter* mainobj)
{
mainobj->SetLife(mainobj->GetLife() + 200);
}
};
//+300
class CItemS_DXD :public CItemStrategy
{
public:
virtual void useItem(CFighter* mainobj)
{
mainobj->SetLife(mainobj->GetLife() + 300);
}
};
//+500
class CItemS_SXD :public CItemStrategy
{
public:
virtual void useItem(CFighter* mainobj)
{
mainobj->SetLife(mainobj->GetLife() + 500);
}
};
#endif //__ITEMSTRATEGY__
③main函数
#include
using namespace std;
#include "Fighter.h"
#include "ItemStrategy.h"
int main()
{
CFighter* prole_war = new F_Warrior(1000, 0, 200);
CItemStrategy* straregy = new CItemS_BXD();
prole_war->SetItemStrategy(straregy);
prole_war->UseItem();
CItemStrategy* straregy2 = new CItemS_DXD();
prole_war->SetItemStrategy(straregy);
prole_war->UseItem();
delete prole_war;
prole_war = nullptr;
delete straregy;
straregy = nullptr;
delete straregy2;
straregy2 = nullptr;
return 0;
}
结构
①main函数
②头文件
具体代码
①main函数
#include
using namespace std;
#include "Fighter.h"
#include "ItemStrategy.h"
int main()
{
CFighter* pPlayerobj1 = new F_Warrior(10, "张三");
pPlayerobj1->SetFamilyID(100);
CFighter* pPlayerobj2 = new F_Warrior(20, "李四");
pPlayerobj2->SetFamilyID(100);
CNotifier* pNotify = new CTalkNotifier();
pNotify->addToList(pPlayerobj1);
pNotify->addToList(pPlayerobj2);
pPlayerobj1->SayWords("阿巴啊把", pNotify);
pNotify->removeFromList(pPlayerobj1);
pPlayerobj2->SayWords("米西碧玺", pNotify);
delete pPlayerobj1;
delete pPlayerobj2;
delete pNotify;
pPlayerobj1 = nullptr;
pPlayerobj2 = nullptr;
pNotify = nullptr;
return 0;
}
②头文件
#ifndef __FIGHTER__
#define __FIGHTER__
#include
#include
class CFighter;
class CNotifier
{
public:
virtual void addToList(CFighter* fighter) = 0;
virtual void removeFromList(CFighter* player) = 0;
virtual void notify(CFighter* talker, string tmpContent) = 0;
virtual ~CNotifier(){}
};
//战斗者父类
class CFighter
{
public:
explicit CFighter(int playerID,string playerName)
:m_iPlayerID(playerID),m_sPlayerName(playerName)
{
m_iFamilyID = -1;
}
virtual ~CFighter() {}
public:
void SetFamilyID(int tmpID)
{
m_iFamilyID = tmpID;
}
int GetFamilyID()
{
return m_iFamilyID;
}
void SayWords(string tmpContent, CNotifier* notifier)
{
notifier->notify(this, tmpContent);
}
void NotifyWords(CFighter* talker,string tmpContent)
{
//xxxxxxxxx
}
private:
int m_iPlayerID; //玩家ID
string m_sPlayerName;
int m_iFamilyID;
};
//战士类
class F_Warrior :public CFighter
{
public:
F_Warrior(int playerID, string playerName)
:CFighter(playerID,playerName){}
};
//魔法师类
class F_Mage :public CFighter
{
public:
F_Mage(int playerID, string playerName)
:CFighter(playerID, playerName){}
};
class CTalkNotifier :public CNotifier
{
public:
virtual void addToList(CFighter* fighter);
virtual void removeFromList(CFighter* player);
virtual void notify(CFighter* talker, string tmpContent);
private:
map<int, list<CFighter*>> m_familyList;
};
void CTalkNotifier::addToList(CFighter* fighter)
{
int tmpFamilyID = fighter->GetFamilyID();
if (tmpFamilyID == -1) return;
auto iter = m_familyList.find(tmpFamilyID);
if (iter != m_familyList.end())
{
//没在家族就加入,上线推送
iter->second.push_back(fighter);
}
else
{
list<CFighter*> tmpPlayerList;
m_familyList.insert(make_pair(tmpFamilyID, tmpPlayerList));
m_familyList[tmpFamilyID].push_back(fighter);
}
}
void CTalkNotifier::removeFromList(CFighter* talker)
{
int tmpFamilyID = talker->GetFamilyID();
if (tmpFamilyID == -1) return;
auto iter = m_familyList.find(tmpFamilyID);
if (iter == m_familyList.end()) return;
m_familyList[tmpFamilyID].remove(talker);
}
void CTalkNotifier::notify(CFighter* talker, string tmpContent)
{
int tmpFamilyID = talker->GetFamilyID();
if (tmpFamilyID == -1) return;
auto itermap = m_familyList.find(tmpFamilyID);
if (itermap == m_familyList.end()) return;
for (auto& mem : itermap->second)
{
(*mem).NotifyWords(mem, tmpContent);
}
}
#endif // !_FIGHTER