java - 原型(prototype)设计模式Java实现困惑

标签 java oop design-patterns prototype-pattern

我刚刚学习了原型(prototype)设计模式。

我是一个 Java 人,所以显然我学习了 Java 实现。但我对不同来源的示例实现有些困惑。

我认为这些例子可能是错误的

Prototype Using new
Prototype Using new

上面的示例在其克隆方法实现中使用了 new 关键字。

以下示例很好,因为它完全实现了原型(prototype)定义中所述的实现。

Prototype Without new

现在,我的问题是,

  • 为什么上面两个例子使用了 new 关键字?
  • 如果我们使用 new 关键字,那么这种模式的好处不就消失了吗?
  • 如果我对上述 2 个示例的理解有误,请在您的回答中说明原因。
  • 最后,哪个是正确的实现?为什么?

2013 年 6 月 28 日更新

感谢大家的回答和评论。尽管有些人仍然不明白这里问的是什么。

以上所有作品是实际问题的序言,我一直试图解决的是 我有一个 Cache 对象,其中包含按输入顺序排列的 30K 条目。现在,在用户界面中,我必须根据用户选择以升序或降序显示这些数据。我只能处理缓存对象本身,所以想为什么不使用原型(prototype)模式克隆给定的缓存对象,然后根据用户选择重新排列克隆的缓存对象的内容并向他们显示?

我做出了正确的决定吗? 我不是新运营商的敌人,但在这种特定情况下它不是很昂贵吗? ?

注意

将数据加载到缓存中也不在我手中,也没有任何 UI 端数据操作。

我能做的只是操作预填充的缓存数据。

谢谢米希尔

最佳答案

克隆并不是要避免使用 new运算符,但创建一个与正在克隆的对象具有相同状态(其成员字段的值)的新实例。

所以,您可以使用clone() (内部仅使用 new) 或自己创建一个 new 实例(使用复制构造函数或在构造后显式触发 setter )镜像源对象的状态。

在你的第三个例子中

clonedAnimal = (Animal) super.clone();

实际上是在调用Object.clone()它在此处创建实例。

另外,尝试删除 clonedAnimal.setXXX()方法后记,它应该仍然有效,因为默认情况下,Object.clone() 应该已经创建了浅拷贝 。他们可能为了便于理解而将它们留在那里。

编辑:(回应OP的评论)
当你 clone()你基本上是在委托(delegate) new obj()调用原始对象本身。

为什么?因此,它也复制状态。但是,这并不能保证 new 不会被使用;只是该对象的类公开了 clone()实现自行承担创建副本的负担。

这就是事情变得有趣的地方。 Object.clone() native 方法。它是在 JVM 中实现的,它执行 C++ 操作来分配堆内存和所有其他爵士乐。但是,当您自己调用 new 运算符时,JVM 所做的事情实际上是相同的(除了复制对象状态之外)。

但是,这不是重点。重要的是要了解何时return super.clone()将真正返回一个独立克隆对象。即使对于中等复杂的对象,答案也是大多数情况下不,因为它执行浅复制

因此,如果您的缓存对象占用大量资源,您就必须提供自己的实现来克隆缓存对象。举个例子:假设您的缓存有 LinkedHashMap最近访问的对象。如果您依赖super.clone()独自的;您克隆的缓存对象(通过浅拷贝)将仅具有对您的Map的引用的副本,这意味着如果您清除其中一个缓存,另一个缓存也会被清除。

因此,当我说new是通过委托(delegate)clone()来雇用的;我指的是为克隆提供自己的深复制实现(几乎总是如此)的类。而且,由于他们是在 Java 的范围内执行此操作,因此他们的第一步(除了 Reflection API)是使用 new 运算符实例化一个新对象。

关于java - 原型(prototype)设计模式Java实现困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17314931/

相关文章:

javascript - 选择原型(prototype)以避免 if-else

PHP,哎呀;为可变深度的分类项目选择正确的设计模式并显示项目链接

java - 使用流畅的构建器模式,无需内部静态类的工作流程

java - 读取和存储数组中的唯一值(JAVA)

java - Thread.sleep(60 * 1000) 让我的程序 hibernate 半小时或更长时间

java - 为什么我们在实例化它们之前首先将子类型声明为它们的父类(super class)型?

java - 在 Java 中创建全局对象的最佳模式

java - Oracle 是否有官方文档说我们不应该在新项目中使用 java.util.Date

java - runOnUiThread 在应用程序被销毁时停止工作

c# - 封装..最精确的描述?