类型对象
当子类过多,并且子类的属性相似时,可以用类型对象来将“类型”模块化,从继承的模式中独立
出来。
例子:我们有一个Monster基类,如果是继承模式,我们需要创建很多个子类来表示具体的怪物,
比如龙子类,史莱姆子类等,但是这些子类都有相似的属性,比如血量攻击力等,只是他们的值
不同。这样会游戏数据耦合进代码中,给修改和添加带来许多麻烦。因此,我们可以使用一个单
一的Monster类,所有怪物都是这个类的实例,在这个Monster类中加入一个Tpye类实例,这
个类包含了怪物的血量、攻击力、种类等信息。
/*---------------------------------类型对象-----------------------------
*/
// -------------------------------Demo-----------------------------//
/*
生成怪物的流程:
1、从JSON文件中读取Type的属性值,如血量、名字啥的
2、组成一个Type对象,保存在某处(这一步是否可以用持久化数据结构来做?)
3、用这个type对象构造Monster
*/
class Monster
{
friend class Type;
private:
Monster(Type &type) : _health(type.getStartHealth()), _type(type) {}
int _health; // 当前的血量
Type &_type; // 怪物类型
public:
~Monster() {}
int getHealth() const { return _health; }
Type &getType() const { return _type; }
};
class Type
{
private:
int _startHealth; // 初始血量
string _typeName;
public:
Type(int startHealth) : _startHealth(startHealth) {}
~Type() {}
Monster *newMonster() { return new Monster(*this); }
int getStartHealth() const { return _startHealth; }
string &getTypeName() const { return _typeName; }
};
享元模式
实际上,享元模式类似与类的抽象,将需要共享的属性整合进一个类中,程序运行开始时预先创
建需要的实例对象集合(或许可以用枚举类实现?),访问者只需要构造一个指针数组,指向
这个类的实例对象,即可得到对应的属性。(其实就是某种意义上的继承,区别在于继承会复
制父类的属性到子类,而享元模式用指针实现内存共享访问)
/*---------------------------------享元模式-----------------------------
*/
// -------------------------------Demo-----------------------------//
// 场景:创建一个存在多棵树的世界,树的高度和宽度是固定的
class Tree
{
private:
int _hight;
int _width;
public:
int getHeight() const { return _hight; }
int getWidth() const { return _width; }
Tree(int hight, int width) : _hight(hight), _width(width) {}
~Tree() {}
};
class World
{
private:
// 创建一个指针数组,代表在100*100的方格上放置树
Tree *_tiles[100][100];
// 树的种类集合
Tree ATree, BTree, CTree;
public:
// 在世界创建时,初始化这些对象
World() : ATree(1, 1), BTree(1, 2), CTree(2, 2) {}
~World() {}
// 生成树
void genTree()
{
for (int i = 0; i < 100; i++)
for (int j = 0; j < 100; j++)
{
_tiles[i][j] = &ATree;
}
}
};
子类沙箱
基类负责与其他所有外部系统耦合,子类只与基类耦合,不调用任何系统外的方法。在基类中提供
各种控制的函数,子类只需要调用这些函数就能完成控制对象的目的。这样构成了一个扁平化的继
承树。
/*---------------------------------子类沙箱-----------------------------
*/
// -------------------------------Demo-----------------------------//
// 基类与其他系统(如物理系统,渲染系统耦合)
class Superpower
{
protected:
virtual void active() = 0;
void move(double x, double y)
{
// 实现代码,与其他系统耦合
}
void playSound(double volume)
{
// 实现代码,与其他系统耦合
}
public:
virtual ~Superpower() {}
};
class Fly : public Superpower
{
protected:
virtual void active() override
{
move(1, 2);
playSound(1.0f);
}
};