C++设计模式---原型模式

本文介绍了如何从工厂方法模式演变为原型模式,以解决游戏中的怪物克隆功能。通过在怪物类中添加拷贝构造函数和克隆接口,实现了不同类型的怪物对象高效克隆。原型模式允许直接复制已有对象,减少了创建新对象的成本。此外,还对比了工厂方法和原型模式在创建对象时的异同点。
摘要由CSDN通过智能技术生成


如何从工厂方法模式演变到原型模式

假设你还是一名游戏程序员,上次三种类型怪物的工厂设计模式游戏策划非常喜欢,他接着又提出了新的需求,怪物在被玩家攻击以后,会损失一些状态(比如生命值、攻击力)。
现在怪物有了一个新的能力,他能够克隆出一个新的自己,并且状态完全和自己一样。
你该如何实现呢?

如果我们仍然使用以前的工厂模式来实现这个功能,会遇到一个麻烦,那就是我们需要获取我们当前怪物对象的属性,然后再通过工厂模式实现创建新的对象。这样太麻烦了,因为我们通过构造函数,就可以构造出和他一模一样的对象出来。

因此,我们只需要给父类增加拷贝构造,然后在子类中实现一个克隆接口就可以了。

#include <iostream>
using namespace std;
namespace hjl_project1
{
    //怪物父类
    class Monster
    {
    public:
        Monster(int life, int magic, int attack)
            : m_life(life), m_magic(magic), m_attack(attack)
        {
        }
        //父类实现其构造函数
        Monster(const Monster &m)
            : m_life(m.m_life), m_magic(m.m_magic), m_attack(m.m_attack)
        {
        }
        //增加一个克隆函数
        virtual Monster *clone() = 0;
        virtual ~Monster() {}

    protected:
        //怪物属性
        int m_life;
        int m_magic;
        int m_attack;
    };
    //亡灵类怪物
    class M_Undead : public Monster
    {
    public:
        M_Undead(int life, int magic, int attack)
            : Monster(life, magic, attack)
        {
            cout << "创建了一个亡灵类怪物" << endl;
        }
        M_Undead(const M_Undead &m)
            : Monster(m)
        {
            cout << "进行了一次克隆" << endl;
            printf("克隆对象的生命值:%d 魔法值:%d 攻击力%d\n", m.m_life, m.m_magic, m.m_attack);
        }
        Monster *clone()
        {
            return new M_Undead(*this);
        }
    };
    //元素类怪物
    class M_Element : public Monster
    {
    public:
        M_Element(int life, int magic, int attack)
            : Monster(life, magic, attack)
        {
            cout << "创建了一个元素类怪物" << endl;
        }
        M_Element(const M_Undead &m)
            : Monster(m)
        {
        }
        Monster *clone()
        {
            return new M_Element(*this);
        }
    };
    //机械类怪物
    class M_Mechanic : public Monster
    {
    public:
        M_Mechanic(int life, int magic, int attack)
            : Monster(life, magic, attack)
        {
            cout << "创建了一个机械类怪物" << endl;
        }
        M_Mechanic(const M_Undead &m)
            : Monster(m)
        {
        }
        Monster *clone()
        {
            return new M_Mechanic(*this);
        }
    };

    //实现工厂模式,代码省略
}

int main()
{

    hjl_project1::Monster *p1 = new hjl_project1::M_Undead(400, 0, 1);
    hjl_project1::Monster *p2 = p1->clone();
    return 0;
}

在这里插入图片描述

在这里插入图片描述


原型模式的定义与特点

原型模式是用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。它属于创建型设计模式,用于创建重复的对象,同时又能保证性能(用这种方式创建对象非常高效)。

优缺点:

  1. 原型模式实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。
  2. 原型模式不存在额外的等级结构,即不需要额外的工厂类。
  3. 有些情况下,产品类中存在克隆方法,也会给开发提供一些遍历,比如抽象类的怪物指针指向具体的怪物类,但是并不知道具体指向哪个怪物类,如果不使用原型模式来克隆,就需要先判断抽象类指针指向哪一个子类对象。
    在这里插入图片描述

工厂方法模式与原型模式在创建对象时的异同点

  1. 这两种设计模式都不需要程序员知道所创建对象所属的类名。
  2. 工厂方法模式中的createMonster函数仍旧属于根据类名来生成对象。原型模式则是根据现有对象的构造函数来生产对象的拷贝。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今天也要写bug、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值