当前位置: 首页 > news >正文

wordpress标签logo深圳关键词优化

wordpress标签logo,深圳关键词优化,那里可以免费做网站,衡水电商网站建设文章目录 一、引言二、原型模式三、总结 一、引言 与工厂模式相同,原型模式(Prototype)也是创建型模式。原型模式通过一个对象(原型对象)克隆出多个一模一样的对象。实际上,该模式与其说是一种设计模式&am…

文章目录

  • 一、引言
  • 二、原型模式
  • 三、总结

一、引言

与工厂模式相同,原型模式Prototype)也是创建型模式。原型模式通过一个对象(原型对象)克隆出多个一模一样的对象。实际上,该模式与其说是一种设计模式,不如说是一种创建对象的方法(对象克隆),尤其是创建给定类的对象(实例)过程很复杂(例如,要设置许多成员变量的值)时,使用这种设计模式就比较合适。


二、原型模式

也就是说,原型模式是为了使你能够复制已有对象, 而又无需使代码依赖它们所属的类。

如果你有一个对象, 并希望生成与其完全相同的一个复制品, 你该如何实现呢? 首先, 你必须新建一个属于相同类的对象。 然后, 你必须遍历原始对象的所有成员变量, 并将成员变量值复制到新对象中。

不错! 但有个小问题。 并非所有对象都能通过这种方式进行复制, 因为有些对象可能拥有私有成员变量, 它们在对象本身以外是不可见的。直接复制还有另外一个问题。 因为你必须知道对象所属的类才能创建复制品, 所以代码必须依赖该类。 即使你可以接受额外的依赖性, 那还有另外一个问题: 有时你只知道对象所实现的接口, 而不知道其所属的具体类, 比如可向方法的某个参数传入实现了某个接口的任何对象。克隆可能会在父类和子类之间进行,并且可能是动态的,很明显通过父类的拷贝构造函数无法实现对子类对象的拷贝,其实这就是一个多态,我们需要给父类提供一个克隆函数并且是一个虚函数。

仍然使用闯关打怪兽的案例来解释。下面是一个怪兽类。我们想让怪物父类拥有clone自己的能力。

// 怪物父类
class Monster {
public:// 构造函数Monster(int life, int magic, int attack): m_life(life), m_magic(magic), m_attack(attack) {}virtual ~Monster() {} // 虚析构函数virtual unique_ptr<Monster> clone() const = 0; //cloneprotected:  int m_life;   // 生命值int m_magic;  // 魔法值int m_attack; // 攻击力
};

clone函数意味着调用该成员函数就会从当前类对象复制出一个完全相同的对象(通过克隆自已来创建出新对象),这当然也是一种创建该类所属对象的方式。这三种怪物实现父类的clone方法。

// 亡灵类
class M_Undead : public Monster {
public:M_Undead(int life, int magic, int attack) : Monster(life, magic, attack) {cout << "一只亡灵类怪物来到了这个世界" << endl;}unique_ptr<Monster> clone() const override {cout<<" 亡灵类被克隆了 "<<endl;return make_unique<M_Undead>(*this); // 克隆自身}
};// 元素类
class M_Element : public Monster {
public:M_Element(int life, int magic, int attack) : Monster(life, magic, attack) {cout << "一只元素类怪物来到了这个世界" << endl;}unique_ptr<Monster> clone() const override {cout<<" 元素类被克隆了 "<<endl;return make_unique<M_Element>(*this); // 克隆自身}
};// 机械类
class M_Mechanic : public Monster {
public:M_Mechanic(int life, int magic, int attack) : Monster(life, magic, attack) {cout << "一只机械类怪物来到了这个世界" << endl;}unique_ptr<Monster> clone() const override {cout<<" 机械类被克隆了 "<<endl;return make_unique<M_Mechanic>(*this); // 克隆自身}
};

既然是克隆,那么上述M_UndeadM_ElementM_Mechanic中的clone成员函数的实现体是需要修改的。例如,某个机械类怪物因为被主角砍了一刀失去了100点生命值,导致该怪物对象的m_life成员变量(生命值)从原来的400变成300,那么调用clone方法克隆出来的新机械类怪物对象也应该是300点生命值,所以此时M_Mechanic类中clone成员函数中的代码行return new M_Mechanic(400,0,110);就不合适,因为这样会创建(克隆)出一个400点生命值的新怪物,不符合clone这个成员函数的本意(复制出一个完全相同的对象)。

克隆对象自身实际上是需要调用类的拷贝构造函数的。如果程序员在类中没有定义自已的拷贝构造函数,那么编译器会在必要的时候(但不是一定)合成出一个拷贝构造函数。因此,**在使用原型模式的时候要注意深拷贝和浅拷贝的问题。**下面添加拷贝构造函数。

// 亡灵类
// 拷贝构造函数
M_Undead::M_Undead(const M_Undead& other) : Monster(other) {cout << "亡灵类被拷贝了" << endl;
}

为了方便,我们仅写一个。这里我们需要确保能正确编写拷贝构造函数,这样调用clone才能正确的克隆出对象。

unique_ptr<Monster> undead = make_unique<M_Undead>(100, 50, 20);
unique_ptr<Monster> undeadClone = undead->clone(); // 克隆亡灵怪物unique_ptr<Monster> element = make_unique<M_Element>(80, 70, 30);
unique_ptr<Monster> elementClone = element->clone(); // 克隆元素怪物unique_ptr<Monster> mechanic = make_unique<M_Mechanic>(120, 40, 50);
unique_ptr<Monster> mechanicClone = mechanic->clone(); // 克隆机械怪物

原型模式将克隆过程委派给被克隆的实际对象。 模式为所有支持克隆的对象声明了一个通用接口, 该接口能够克隆对象, 同时又无需将代码和对象所属类耦合。 通常情况下, 这样的接口中仅包含一个 clone方法。

所有的类对 clone方法的实现都非常相似。 该方法会创建一个当前类的对象, 然后将原始对象所有的成员变量值复制到新建的类中。 甚至可以复制私有成员变量, 因为绝大部分编程语言都允许对象访问其同类对象的私有成员变量。

支持克隆的对象即为原型。 当对象有几十个成员变量和几百种类型时, 对其进行克隆甚至可以代替子类的构造。

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

在这里插入图片描述

原型模式的UML图中,包含两种角色。

  • 抽象原型类Prototype):所有具体原型类的父类,在其中声明克隆方法。这里指Monster类。
  • 具体原型类oncretePrototype):实现在抽象原型类中声明的克隆方法,在克隆方法中返回自己的一个克隆对象。这里指M_Undead类、M_Element类和M_Mechanic类。

引入原型模型的定义:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。简单来说,就是通过克隆来创建新的对象实例。

原型模式结构

在这里插入图片描述

  1. 原型Prototype) 接口将对克隆方法进行声明。 在绝大多数情况下, 其中只会有一个名为 clone克隆的方法。
  2. 具体原型Concrete Prototype) 类将实现克隆方法。 除了将原始对象的数据复制到克隆体中之外, 该方法有时还需处理克隆过程中的极端情况, 例如克隆关联对象和梳理递归依赖等等。
  3. 客户端Client) 可以复制实现了原型接口的任何对象。

在这里插入图片描述

原型注册表 (Prototype Registry) 提供了一种访问常用原型的简单方法, 其中存储了一系列可供随时复制的预生成对象。 最简单的注册表原型是一个 名称 → 原型的哈希表。 但如果需要使用名称以外的条件进行搜索, 你可以创建更加完善的注册表版本。


三、总结

原型模式与工厂方法模式在创建对象时的主要区别在于它们如何处理对象的创建过程和状态复制。

原型模式通过复制现有对象(原型)来创建新对象,新对象的初始状态与原型对象相同,这避免了复杂的设置过程。当对象的内部数据复杂且多变时,原型模式比工厂方法模式更合适,因为它可以直接克隆当前状态,无需额外的设置代码。例如,在游戏中创建一个具有特定状态的怪物分身,使用原型模式可以快速复制这些状态。

工厂方法模式和原型模式在创建对象时都不需要知道具体的类名,但它们的工作方式不同。工厂方法模式通过调用创建接口来创建新对象,而原型模式通过克隆现有对象。如果对象的创建成本较高,或者需要避免复杂的初始化逻辑,原型模式是一个更好的选择。总结来说,两种模式都能解耦对象的创建过程,但原型模式在处理动态和复杂状态的对象时更为高效。

因此,如果对象的内部数据比较复杂且多变并且在创建对象的时候希望保持对象的当前状态,那么用原型模式显然比原型模式更合适。

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

  • 前面范例中创建怪物对象时,这两种模式其实都不需要程序员知道所创建对象所属的类名;
  • 工厂方法模式是调用相应的创建接口,例如使用createMonster接口来创建新的怪物对象,该接口中采用代码行``new类名(参数)`来完成对象的最终创建工作,这仍旧是属于根据类名来生成新对象;
  • 型模式是调用例如clone(程序员可以修改成任意其他名字)接口来创建新的怪物对象,按照惯例,这个接口一般不带任何参数,以免破坏克隆接口的统一性。该接口中采用的是代码行new类名(*this)完成对类拷贝构造函数的调用来创建对象,所以这种创建对象的方式是根据现有对象来生成新对象

当然,也可以把原型模式看成是一种特殊的工厂方法模式(工厂方法模式的变体),这也是可以的一把原型对象所属的类本身(例如,M_Undead、M_Element、M_Mechanic)看成是创建克隆对象的工厂,而工厂方法指的自然就是克隆方法(clone)。

有时候原型可以作为备忘录模式的一个简化版本, 其条件是需要在历史记录中存储的对象的状态比较简单, 不需要链接其他外部资源, 或者链接可以方便地重建。原型并不基于继承, 因此没有继承的缺点。 另一方面, 原型需要对被复制对象进行复杂的初始化。 工厂方法基于继承, 但是它不需要初始化步骤。

在大量使用组合模式和装饰模式的设计时,可以通过原型模式来复制复杂结构, 而非从零开始重新构造。

http://www.zhongyajixie.com/news/48387.html

相关文章:

  • vue做的网站多么网络推广外包内容
  • 分类信息系统网站模板百度助手app下载
  • 广州模板网站建设网站优化推广哪家好
  • 网站里弹窗怎么做企业培训机构排名前十
  • 嘉兴做网站美工的工作新手怎么做网页
  • 宁波市网站建设搜索引擎是网站吗
  • 棋牌网站建设要多少钱企业培训课程有哪些
  • 淘宝做动效代码的网站被逆冬seo课程欺骗了
  • 静态网页生成北京seo优化诊断
  • 番禺网站建设营销推广外包公司
  • avs做视频网站简单吗一键建站
  • 婚庆公司一条龙大约多少钱页面优化的方法
  • 华为300mbps无线扩展器设置网站百度搜索引擎提交入口
  • 曲周企业做网站推广一站式推广平台
  • 网站模板尺寸上海哪家seo公司好
  • 上海地图seo交流论坛
  • 网站开发中安全性的防范百度推广非企代理
  • 手机wap购物网站模板上海网络优化seo
  • 歌手投票网站怎么做网站优化排名软件网
  • 专门做防盗门的网站网络推广的含义
  • 网站开发招标技术规范书成都网络推广外包公司哪家好
  • 珠宝网站dedecms模版一天赚2000加微信
  • 下载网站的表格要钱如何做培训课程有哪些
  • 网站开发必用代码百度公司销售卖什么的
  • 建站abc网站建设网络推广需要花多少钱
  • 东莞网站开发技术公司电话58同城推广
  • 做柜子好的设计网站长春网站建设方案托管
  • 上海中国建设银行招聘信息网站搜易网服务内容
  • 做网站开发要具备什么知识公司营销策划方案案例
  • 个人站长做电音网站四川网站制作