创建型模式--6.原型模式【杰尔马66】

1. 克隆人

在海贼王世界中,杰尔马王国拥有一支强大的科学作战部队 -- 杰尔马66军团,其先锋是文斯莫克家族,他们作为雇佣军活跃在世界各地。

这支部队战斗力强悍,没有情感,不畏生死,勇往直前。从某种意义上来讲,他们不能被称之为人,因为他们是科学的结晶,他们都出自文斯莫克·伽治之手。

伽治曾和海贼世界中的顶级科学家贝加庞克是同事,一起发现了血统因子,于是才有了现在这么多的杰尔马士兵,对,你没有看错他们都是被克隆出来的。

克隆是一种最直接、最快捷的创建新对象的方式,它不仅隐藏了创建新对象的诸多细节,还保留了源对象的属性信息,保证了这两个对象能够一模一样。

血统因子士兵这是一个复杂而又艰辛的过程,一旦研发成功,之后的事情就是基于母体进行复制(克隆)。我猜伽治不仅是一名科学家,可能还是一位架构师,因为他懂设计模式,这种制作克隆人的模式就是原型模式

原型模式就是能够复制已有的对象,而又无需使代码依赖它们所属的类。换种说法,就是通过已有对象克隆出另一个新的对象,并且克隆这个对象不需要使用构造函数。

2. 这是在脱了裤子放屁吗

懂C++的亲们看了上面关于原型模式的描述肯定是满脑子问号。因为在C++中只要定义一个类,这个类就默认自带六大函数,其中一个就是拷贝构造函数,这个函数的作用就是通过一个已有对象克隆出一个新的对象。一个拷贝构造函数就能搞定的事情为啥还要搞出一种设计模式呢?

这是脱了裤子放屁吗?肯定不是,因为这里边还隐藏着一个细节。

  • 对于伽治来说,他可能想通过一代士兵克隆出更优秀的二代士兵
  • 对于程序猿来说,我们可能想要通父类指针或引用把指向的子类对象克隆出来
    通过这个描述,就可以从里面挖掘出一个重要的信息:克隆可能会在父类和子类之间进行,并且可能是动态的,很明显通过父类的拷贝构造函数无法实现对子类对象的拷贝,其实这就是一个多态,我们需要给父类提供一个克隆函数并且是一个虚函数

现在逻辑关系已经说明白了,来看一下对应UML类图

3. 量产士兵

根据上面的UML类图,我们就可以把对应的代码写出了,示例代码如下:

复制代码
#include <iostream>
using namespace std;

class GermaSoldier
{
public:
    virtual GermaSoldier* clone() = 0;
    virtual string whoAmI() = 0;
    virtual ~GermaSoldier() {}
};

class Soldier66 : public GermaSoldier
{
public:
    GermaSoldier* clone() override
    {
        return new Soldier66(*this);
    }
    string whoAmI() override
    {
        return string("我是杰尔马66的超级士兵!!!");
    }
};

class Soldier67 : public GermaSoldier
{
public:
    GermaSoldier* clone()
    {
        return new Soldier67(*this);
    }
    string whoAmI() override
    {
        return string("我是杰尔马67的超级士兵!!!");
    }
};

int main()
{
    GermaSoldier* obj = new Soldier66;
    GermaSoldier* soldier = obj->clone();
    cout << soldier->whoAmI() << endl;
    delete soldier;
    delete obj;

    obj = new Soldier67;
    soldier = obj->clone();
    cout << soldier->whoAmI() << endl;
    delete soldier;
    delete obj;
}

代码中的main()函数对应的就是UML类图中的客户端角色。

  • 第41行通过父类指针克隆了子类Soldier66的对象
  • 第47行通过父类指针克隆了子类Soldier67的对象
  • 在这两个士兵子类的clone()函数体内部是通过当前子类的拷贝构造函数复制出了一个新的子类对象。

程序执行的结果如下:

复制代码
我是杰尔马66的超级士兵!!!
我是杰尔马67的超级士兵!!!

通过输出的结果可以看到通过父类指针克隆子类的对象成功了。

相关推荐
想吃火锅10053 天前
【前端手撕】instanceof
前端·javascript·原型模式
UXbot3 天前
帮助企业低门槛开展AI应用开发的平台推荐
前端·低代码·ui·交互·产品经理·原型模式·web app
UXbot4 天前
如何选择适合公司项目的UI设计工具?企业选型指南
前端·低代码·ui·团队开发·原型模式·设计规范·web app
UXbot4 天前
原型设计工具如何帮助新人快速进入产品行业?
前端·低代码·ui·交互·团队开发·原型模式·web app
sunny.day8 天前
js原型与原型链
开发语言·javascript·原型模式·js原型链
UXbot9 天前
AI网页开发工具能替代工具吗?5大平台对比
前端·人工智能·低代码·ui·原型模式·web app
weixin_307779139 天前
从“大海捞针”到“主动推理”:AI如何重塑云原生故障诊断的根因链
开发语言·人工智能·算法·自动化·原型模式
swordbob9 天前
prototype 注入到 singleton 里,prototype是否还是线程安全的
安全·spring·单例模式·原型模式
isNotNullX10 天前
企业数据中台建设,ETL工具选错了会踩哪些坑?
数据仓库·etl·原型模式
半个烧饼不加肉10 天前
JS 底层探究-- 普通函数和构造函数
开发语言·javascript·原型模式