原型模式

亦称: 克隆、Clone、Prototype

意图

原型模式是一种创建型设计模式, 使你能够复制已有对象, 而又无需使代码依赖它们所属的类。

一图说明:

还是老话,请在阅读本篇文章后,记住此图

图解:

原型模式解决的实际问题:

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

不错! 但有个小问题。 并非所有对象都能通过这种方式进行复制, 因为有些对象可能拥有私有成员变量, 它们在对象本身以外是不可见的。

直接复制还有另外一个问题。 因为你必须知道对象所属的类才能创建复制品, 所以代码必须依赖该类。 即使你可以接受额外的依赖性, 那还有另外一个问题: 有时你只知道对象所实现的接口, 而不知道其所属的具体类, 比如可向方法的某个参数传入实现了某个接口的任何对象。

原型模式的解决方案

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

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

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

真实世界类比

现实生活中, 产品在得到大规模生产前会使用原型进行各种测试。 但在这种情况下, 原型只是一种被动的工具, 不参与任何真正的生产活动。

由于工业原型并不是真正意义上的自我复制, 因此细胞有丝分裂 (还记得生物学知识吗?) 或许是更恰当的类比。 有丝分裂会产生一对完全相同的细胞。 原始细胞就是一个原型, 它在复制体的生成过程中起到了推动作用。

解构原型模式的几大组成

伪代码实现

在本例中, 原型模式能让你生成完全相同的几何对象副本, 同时无需代码与对象所属类耦合。

所有形状类都遵循同一个提供克隆方法的接口。 在复制自身成员变量值到结果对象前, 子类可调用其父类的克隆方法。

// 基础原型。
abstract class Shape isfield X: intfield Y: intfield color: string// 常规构造函数。constructor Shape() is// ……// 原型构造函数。使用已有对象的数值来初始化一个新对象。constructor Shape(source: Shape) isthis()this.X = source.Xthis.Y = source.Ythis.color = source.color// clone(克隆)操作会返回一个形状子类。abstract method clone():Shape// 具体原型。克隆方法会创建一个新对象并将其传递给构造函数。直到构造函数运
// 行完成前,它都拥有指向新克隆对象的引用。因此,任何人都无法访问未完全生
// 成的克隆对象。这可以保持克隆结果的一致。
class Rectangle extends Shape isfield width: intfield height: intconstructor Rectangle(source: Rectangle) is// 需要调用父构造函数来复制父类中定义的私有成员变量。super(source)this.width = source.widththis.height = source.heightmethod clone():Shape isreturn new Rectangle(this)class Circle extends Shape isfield radius: intconstructor Circle(source: Circle) issuper(source)this.radius = source.radiusmethod clone():Shape isreturn new Circle(this)// 客户端代码中的某个位置。
class Application isfield shapes: array of Shapeconstructor Application() isCircle circle = new Circle()circle.X = 10circle.Y = 10circle.radius = 20shapes.add(circle)Circle anotherCircle = circle.clone()shapes.add(anotherCircle)// 变量 `anotherCircle(另一个圆)`与 `circle(圆)`对象的内// 容完全一样。Rectangle rectangle = new Rectangle()rectangle.width = 10rectangle.height = 20shapes.add(rectangle)method businessLogic() is// 原型是很强大的东西,因为它能在不知晓对象类型的情况下生成一个与// 其完全相同的复制品。Array shapesCopy = new Array of Shapes.// 例如,我们不知晓形状数组中元素的具体类型,只知道它们都是形状。// 但在多态机制的帮助下,当我们在某个形状上调用 `clone(克隆)`// 方法时,程序会检查其所属的类并调用其中所定义的克隆方法。这样,// 我们将获得一个正确的复制品,而不是一组简单的形状对象。foreach (s in shapes) doshapesCopy.add(s.clone())// `shapesCopy(形状副本)`数组中包含 `shape(形状)`数组所有// 子元素的复制品。

实现方式

1.创建原型接口, 并在其中声明 克隆方法。 如果你已有类层次结构, 则只需在其所有类中添加该方法即可。

2.原型类必须另行定义一个以该类对象为参数的构造函数。 构造函数必须复制参数对象中的所有成员变量值到新建实体中。 如果你需要修改子类, 则必须调用父类构造函数, 让父类复制其私有成员变量值。

3.如果编程语言不支持方法重载, 那么你可能需要定义一个特殊方法来复制对象数据。 在构造函数中进行此类处理比较方便, 因为它在调用 new运算符后会马上返回结果对象。

4.克隆方法通常只有一行代码: 使用 new运算符调用原型版本的构造函数。 注意, 每个类都必须显式重写克隆方法并使用自身类名调用 new运算符。 否则, 克隆方法可能会生成父类的对象。

你还可以创建一个中心化原型注册表, 用于存储常用原型。

你可以新建一个工厂类来实现注册表, 或者在原型基类中添加一个获取原型的静态方法。 该方法必须能够根据客户端代码设定的条件进行搜索。 搜索条件可以是简单的字符串, 或者是一组复杂的搜索参数。 找到合适的原型后, 注册表应对原型进行克隆, 并将复制生成的对象返回给客户端。

最后还要将对子类构造函数的直接调用替换为对原型注册表工厂方法的调用。

原型模式优缺点

看图记设计模式【五】,创建模式系列:原型模式相关推荐

  1. Java设计模式之创建型:原型模式

    一.什么是原型模式: 原型模式主要用于对象的创建,使用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象.UML类图如下: 原型模式的核心是就是原型类 Prototype,Prototype ...

  2. Java设计模式之创建型:建造者模式

    一.什么是建造者模式: 建造者模式将复杂产品的创建步骤分解在在不同的方法中,使得创建过程更加清晰,从而更精确控制复杂对象的产生过程:通过隔离复杂对象的构建与使用,也就是将产品的创建与产品本身分离开来, ...

  3. 看图记设计模式【二】,创建模式系列:工厂模式

    工厂模式 亦称: 虚拟构造函数.Virtual Constructor.Factory Method 意图 工厂方法模式是一种创建型设计模式, 其在父类中提供一个创建对象的方法, 允许子类决定实例化对 ...

  4. 创建型模式:原型模式

    前方高能:<一故事一设计模式>PDF 电子书已经上线,关注公众号即可获取. 个人公众号原文: 创建型模式:原型模式 五大创建型模式之五:原型模式. 简介 姓名 :原型模式 英文名 :Pro ...

  5. 设计模式学习笔记九:原型模式(Prototype Pattern)

    1.概述     意图:我们将已经存在的对象作为原型,用户可以通过复制这些原型创建新的对象.     使用场合:当一个系统应该独立于产品的创建.构造和表示时,可以使用原型模式.在原型模式中,产品的创建 ...

  6. Java设计模式(工厂模式>抽象工厂模式和原型模式)

    Java设计模式Ⅱ 1.工厂模式 1.1 简单工厂模式 1.2 工厂方法模式 2.抽象工厂模式 3.总结 4.原型模式 4.1 原型模式 4.2 浅拷贝 4.3 深拷贝 5.建造者模式 1.工厂模式 ...

  7. 建造者模式与原型模式/builder模式与prototype模式/创建型模式

    建造者模式 定义 用于简化复杂对象的创建 JDK中的建造者模式 java.lang.StringBuilder中的append()方法,每次调用后返回修改后的对象本身. public StringBu ...

  8. [19/04/24-星期三] GOF23_创建型模式(建造者模式、原型模式)

    一.建造者模式 本质:分离了对象子组件的单独构造(由Builder负责)和装配的分离(由Director负责),从而可以构建出复杂的对象,这个模式适用于:某个对象的构建过程十分复杂 好处:由于构建和装 ...

  9. 设计模式-Prototype模式(原型模式)

    目录 原型模式是什么? 为什么要用原型模式? 原型模式是什么? Prototype模式:不根据类来生成实例,而是根据实例来生成新实例. 怎么理解呢?举个例子,就是比如现在我们只有两个类,球(Ball) ...

  10. 【设计模式】对象的克隆-原型模式

    原型模式是对象的创建模式.原型模式使用原型实例指定创建对象的类型,通过克隆原型来创建新的对象,其实就是复制对象. 原型模式在我们的生活中处处都存在,大家应该用过很多软件,都有模板,就拿我现在用的思维导 ...

最新文章

  1. (C++)字符数组的四种输入输出方式
  2. 问题1:U盘可以识别但无法打开;问题2:U盘成为启动盘之后如何恢复成普通U盘。
  3. linq学习笔记(2):DataContext
  4. go同一个目录下的go文件里面不能有多个package
  5. 南通市交巡警支队同城异地容灾备份系统项目中标结果公告
  6. 在64位的linux中运行32位的应用程序
  7. 【LiveVideoStack线上分享】FFmpeg深度学习模块架构与代码实践
  8. Zookeeper知识点详解
  9. 常见电脑字符编码总结
  10. 毕业之后,这些年薪 50w+ 的 90 后程序员都经历了什么?纯水贴
  11. python读取shp文件,
  12. 测试用例--测试大纲(提纲)法
  13. 简单两步实现安卓软件自动升级(自动升级工具类)
  14. c语言中进入临界区函数,VC/MFC 临界区使用方法事例
  15. 准备启动一个开源项目 - 技术族谱 - 先期利用Goolge云计算平台
  16. Fluent的porous jump边界条件
  17. for循环嵌套 正三角和倒三角
  18. Linux中的tail命令
  19. 【高等数学】-积分再现公式
  20. 蓝鲸智云App应用部署(完整版)

热门文章

  1. 数值计算——牛顿插值法
  2. 不懂甘特图,你还怎么做项目进度管理
  3. java中的垃圾回收算法与垃圾回收器
  4. Android Weekly #32 - 面对畏惧之人,便说笨方法是行动的勇敢
  5. AtCode ABC249 - A - Jogging
  6. 双十一大促|20%商家拥有头部资源,剩下80%商家怎么办?
  7. 李飞飞:我们怎么教计算机理解图片
  8. 【VS2017】【Windows SDK】【MSB803】找不到 Windows SDK 版本10.0.17134.0的解决办法
  9. 北斗微信与服务器怎么联接,微信怎么绑定北斗导航
  10. 2021年CFA二三级机考题目大变!