➢通过“对象创建”模式绕开new,来避免对象创建(new) 过程中所导致的紧耦合(依赖具体类), 从而支持对象创建的稳定。它是接口抽象之后的第一步工作。
➢典型模式
➢在软件系统中,经常面临着“某些结构复杂的对象’的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥有比较稳定一致的接口。
➢如何应对这种变化?如何向“客户程序(使用这些对象的程序)"隔离出“这些易变对象”,从而使得“依赖这些易变对象的客户程序”不 随着需求改变而改变?
使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。
——《设计模式:可复用面向对象软件的基础》
➢原型的优点
➢原型的用途和缺点
你设计的游戏中,需要怪兽的特征能够随着场景的变换而演化。例如在海底世界,创建海怪;在沙漠中,创建沙蝎怪物;在天空中,创建鸟人怪。由于创建怪物的过程比较复杂,需要在特定的类中统一复制创建,达到解耦的目的。
怪物 抽象基类
//Monster.h
//怪物 抽象基类
#ifndef PROTOTYPEPATTERN_MONSTER_H
#define PROTOTYPEPATTERN_MONSTER_H
#include
class Monster {
public:
Monster() = default;
~Monster() = default;
Monster(std::string scene, std::string name);
[[nodiscard]] const std::string &getScene() const;
void setScene(const std::string &scene);
[[nodiscard]] const std::string &getName() const;
void setName(const std::string &name);
Monster clone(); //克隆函数
private:
std::string m_scene; //场景
std::string m_name; //名字
};
#endif //PROTOTYPEPATTERN_MONSTER_H
//Monster.cpp
#include "Monster.h"
Monster::Monster(std::string scene, std::string name) {
this->m_scene = scene;
this->m_name = name;
}
const std::string &Monster::getScene() const {
return m_scene;
}
void Monster::setScene(const std::string &scene) {
m_scene = scene;
}
const std::string &Monster::getName() const {
return m_name;
}
void Monster::setName(const std::string &name) {
m_name = name;
}
Monster Monster::clone() {
Monster monster;
monster.setScene(this->m_scene);
monster.setName(this->m_name);
return monster;
}
海怪 类
//SeaMonster.h
// 海怪 类
#ifndef PROTOTYPEPATTERN_SEAMONSTER_H
#define PROTOTYPEPATTERN_SEAMONSTER_H
#include "Monster.h"
class SeaMonster : public Monster{
public:
SeaMonster(std::string scene, std::string name);
SeaMonster(std::string name);
};
#endif //PROTOTYPEPATTERN_SEAMONSTER_H
//SeaMonster.cpp
#include "SeaMonster.h"
SeaMonster::SeaMonster(std::string scene, std::string name) : Monster(scene, name) {
}
SeaMonster::SeaMonster(std::string name) {
Monster("Sea", name);
}
沙蝎 类
//Scorpion.h
//沙蝎 类
#ifndef PROTOTYPEPATTERN_SCORPION_H
#define PROTOTYPEPATTERN_SCORPION_H
#include "Monster.h"
class Scorpion : public Monster{
public:
Scorpion(std::string scene, std::string name);
Scorpion(std::string name);
};
#endif //PROTOTYPEPATTERN_SCORPION_H
//Scorpion.cpp
#include "Scorpion.h"
Scorpion::Scorpion(std::string scene, std::string name) : Monster(scene, name) {
}
Scorpion::Scorpion(std::string name) {
Monster("sand", name);
}
鸟人 类
//Birdy.h
//鸟人 类
#ifndef PROTOTYPEPATTERN_BIRDY_H
#define PROTOTYPEPATTERN_BIRDY_H
#include "Monster.h"
class Birdy : public Monster{
public:
Birdy(std::string scene, std::string name);
Birdy(std::string name);
};
#endif //PROTOTYPEPATTERN_BIRDY_H
//Birdy.cpp
#include "Birdy.h"
Birdy::Birdy(std::string scene, std::string name) : Monster(scene, name) {
}
Birdy::Birdy(std::string name) {
Monster("sky", name);
}
怪物注册 类
//MonsterRegistry.h
// 怪物注册 类
#ifndef PROTOTYPEPATTERN_MONSTERREGISTRY_H
#define PROTOTYPEPATTERN_MONSTERREGISTRY_H
#include
#include
#include "Monster.h"
class MonsterRegistry {
public:
MonsterRegistry();
~MonsterRegistry();
Monster getMonster(std::string scene);
private:
std::unique_ptr<std::unordered_map<std::string, Monster*>> monsterDB;
};
#endif //PROTOTYPEPATTERN_MONSTERREGISTRY_H
//MonsterRegistry.cpp
#include "MonsterRegistry.h"
#include "SeaMonster.h"
#include "Scorpion.h"
#include "Birdy.h"
MonsterRegistry::MonsterRegistry() {
monsterDB = std::make_unique<std::unordered_map<std::string, Monster*>>();
monsterDB->insert({"sea", new Monster{"sea","Sea Monster"}});
monsterDB->insert({"sand", new Monster{"sand","Sand Scorpion"}});
monsterDB->insert({"sky", new Monster{"sky","Birdy"}});
}
Monster MonsterRegistry::getMonster(std::string scene) {
return monsterDB->find(scene)->second->clone();
}
MonsterRegistry::~MonsterRegistry() {
for(auto msdb : *monsterDB){
delete msdb.second;
msdb.second = nullptr;
}
}
怪物生成 类
//MonsterMarker.h
//怪物生成 类
#ifndef PROTOTYPEPATTERN_MONSTERMARKER_H
#define PROTOTYPEPATTERN_MONSTERMARKER_H
#include
#include "MonsterRegistry.h"
class MonsterMarker {
public:
MonsterMarker();
~MonsterMarker() = default;
void makeRandomMonster(std::string scen);
private:
std::unique_ptr<MonsterRegistry> registry;
std::default_random_engine random{47};
};
#endif //PROTOTYPEPATTERN_MONSTERMARKER_H
MonsterMarker.cpp
#include
#include "MonsterMarker.h"
MonsterMarker::MonsterMarker() {
registry = std::make_unique<MonsterRegistry>();
}
void MonsterMarker::makeRandomMonster(std::string scene) {
std::uniform_int_distribution u{5, 9};
int count = u(random);
std::string name = "";
for(int i = 0; i<count; i++){
Monster monster = registry->getMonster(scene);
name = monster.getName();
}
std::cout << "You wiil fight with " << count << " " << name << " in " << scene << "." << std::endl;
}
测试代码
//main.cpp
//测试代码
#include
#include "MonsterMarker.h"
int main()
{
std::unique_ptr<MonsterMarker> monsterMake = std::make_unique<MonsterMarker>();
std::cout << "You're in sea." << std::endl;
monsterMake->makeRandomMonster("sea");
std::cout << "You're in sky." << std::endl;
monsterMake->makeRandomMonster("sky");
std::cout << "You're in sand." << std::endl;
monsterMake->makeRandomMonster("sand");
}
欢迎关注公众号:c_302888524
发送:“设计模式:可复用面向对象软件的基础” 获取电子书