在玩一款叫《杀戮尖塔》的游戏时,里面有一个boss怪物叫史莱姆之王,它的技能是在低于自身血量一般时,分裂成两个血量上限为分裂前剩余血量的史莱姆。
那么。我们如何使用C++来模拟这一行为呢?
我们就要提到C++设计模式之一——原型模式。
#include <iostream>
using namespace std;
namespace _SlayTheSpire{
class Monster{
public:
Monster(int m_hp, int m_atk, int m_def) : hp(m_hp), atk(m_atk), def(m_def) {
cout << "战斗!" << endl;
}
virtual ~Monster() {}
virtual Monster* clone() = 0;
protected:
int hp;
int atk;
int def;
};
class ShiLaimu : public Monster {
public:
ShiLaimu(int m_hp, int m_ack, int m_def) : Monster(m_hp, m_ack, m_def) {
cout << "史莱姆之王 is coming" << endl;
}
ShiLaimu(const ShiLaimu& slm) : Monster(slm) {
cout << "分裂" << endl;
}
virtual Monster* clone() {
return new ShiLaimu(*this);
}
};
void FenLie(Monster* pMonster) {
Monster* m_Monster = pMonster->clone();
/* 业务逻辑 */
delete m_Monster;
}
}; //namespace _SlayTheSpire
int main() {
_SlayTheSpire::Monster* slm = new _SlayTheSpire::ShiLaimu(100, 50, 50);
_SlayTheSpire::Monster* slm1 = slm->clone();
delete slm;
delete slm1;
return 0;
}
原型模式:通过一个对象(原型对象)克隆出多个一模一样的对象。
(1)通过工厂方法模式演变到原型模式
- 克隆对象自身实际上是需要调用类的拷贝构造函数。
- 克隆对象意味着复制出一个全新的对象,所以设计到深浅拷贝时都要实现深拷贝
(2)引入原型(Prototype)模式
- 定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。简单说来就是通过克隆来创建新的对象实例。
- 原型模式的两种角色:
a)Prototype(抽象原型类):Monster类。
b)ConcretePrototype(具体原型类):ShiLaimu类。
如果对象内部数据比较复杂多变并且在创建对象的时候希望保持对象的当前状态,那么用原型模式显然比用工厂方法模式更合适。
(3)工厂方法模式和原型模式在创建对象时的异同点:
- 都不需要程序员知道所创建对象所属的类名。
- 工厂方法模式中的createMonster仍旧属于根据类名来生成新对象。
- 原型模式中的clone是根据现有对象来生成新对象。
(4)原型模式优缺点:
- 如果创建的新对象内部数据比较复杂且多变,原型模式创建对象的效率可能会高很多。
- 原型模式不存在额外的等级结构——原型模式不需要额外的工厂类。
- clone接口的实现方法有多种。
- 有些情况下,产品类中存在一个克隆方法也会给开发提供一些明显便利。