创建型模式--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的超级士兵!!!

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

相关推荐
小凯 ོ1 天前
实战原型模式案例
java·后端·设计模式·原型模式
JuneXcy6 天前
28.原型
开发语言·javascript·原型模式
楚禾Noah7 天前
【设计模式实战】原型模式 + 工厂模式:AI Agent 配置中心
人工智能·设计模式·原型模式
找不到、了15 天前
Java设计模式之《原型模式》--深、浅copy
java·设计模式·原型模式
阿维的博客日记1 个月前
@Scope(value = WebApplicationContext.SCOPE_REQUEST)和@Scope(“prototype“)区别
原型模式
果粒chenl1 个月前
06-原型和原型链
前端·javascript·原型模式
谢尔登1 个月前
【JavaScript】手写 Object.prototype.toString()
前端·javascript·原型模式
源代码•宸1 个月前
深入浅出设计模式——创建型模式之原型模式 Prototype
c++·经验分享·设计模式·原型模式
zhysunny1 个月前
05.原型模式:从影分身术到细胞分裂的编程艺术
java·原型模式
long_mingyue1 个月前
JavaScript 对象操作、继承与模块化实现
javascript·原型模式·xss