【发布时间】:2012-07-27 05:40:24
【问题描述】:
我正在研究原型设计模式并且有一些问题。
我了解原型设计模式用于创建在内存或资源方面成本高昂的对象。在这种情况下,我们使用已经可用的对象的克隆。
那么创建new 对象和clone() 有什么区别?对象存储在内存中的什么位置?
【问题讨论】:
标签: java design-patterns prototype-pattern
我正在研究原型设计模式并且有一些问题。
我了解原型设计模式用于创建在内存或资源方面成本高昂的对象。在这种情况下,我们使用已经可用的对象的克隆。
那么创建new 对象和clone() 有什么区别?对象存储在内存中的什么位置?
【问题讨论】:
标签: java design-patterns prototype-pattern
当对象的创建占用过多的系统资源和性能时使用原型设计模式,而当我们希望拥有一个类的许多实例并且这些实例相似时我们使用这种设计模式,所以我们不' t 真的想使用例如操作符“new”,因为它的成本太高了,我们只需要根据已经创建的第一个对象来实例化这些对象。
优点是新对象将是独立的,并且不会像第一个那样创建太多资源。 这里有一个在 java 中使用这个概念的例子:
import java.util.Vector;
public class Samsung implements Cloneable{
private Vector<String> models;
public Samsung(){
models=new Vector<>();
//we suppose in this comments we access to a data Base to get models
//and then we get a full list of Samsung models
//... and finish
//Sadly we took to much of time to fetch the database
//we don't want to waste our time again because Samsung rarely update its database
models.add("Samsung S1");
models.add("Samsung S2");
models.add("galaxy note");
models.add("galaxy star");
}
public Samsung(Vector<String> models){
this.models=models;
}
public Samsung clone() {
Vector<String> modelsCopy=new Vector<>();
Samsung samsungCopy=null;
//here we don't need to access the database again, we will just copy the previous list
try{
for(String model:this.models){
modelsCopy.add(model);
}
samsungCopy=new Samsung(modelsCopy);
return samsungCopy;
}
catch(Exception e){
return null;
}
}
}
主程序:
public static void main(String[] args) {
Samsung usa_Samsung=new Samsung();
Samsung morocco_Samsung=usa_Samsung.clone();
System.out.println("original = " + usa_Samsung);
System.out.println("copy = " + morocco_Samsung);
}
输出:
original = Samsung@6d06d69c
copy = Samsung@7852e922
就像您看到这些对象的地址不同,因为它们不同。
注意! 我仅以“三星”这个名称为例。
【讨论】:
原型设计模式提供两种成本节省——时间节省和空间节省。
在创建对象需要昂贵的辅助信息访问(例如,从文件、数据库或通过网络请求配置数据)的情况下,可以节省时间。例如,如果您要从存储在 Web 服务器上的模板构建大量页面,则读取一次模板并克隆它以获得每个新页面的起点会更便宜,而不是单独查询 Web 服务器每一页。
重用不可变对象可以节省内存:如果您的原始对象包含大量字符串,则创建新实例需要创建全新的不可变字符串,或者手动处理字符串实习。通过让克隆共享模板的不可变部分,使用原型模式优雅地避免了这个问题。
【讨论】:
Java clone() 方法只是创建一个新对象并将成员变量值复制到其中。一般来说,它既不比创建新对象贵也不便宜。唯一一次clone() 可能比使用new 创建对象更便宜,那就是对象的构造函数做一些昂贵的事情:例如,如果构造函数接受参数并将它们用作数据库查询的一部分怎么办?在这种情况下,使用clone() 会更便宜,因为不会发生昂贵的查询操作。
使用这种设计模式还有其他原因:大多数情况下,对象在使用前需要复杂的设置,而这在构造函数中无法方便地完成。想象一下,一个对象有 20 个需要设置的属性。如果你用构造函数参数来设置它们,那个构造函数会非常丑陋——想象一个有 20 个参数的构造函数!相反,您可以构造一个可能没有参数的对象,使用 mutator 方法设置 20 个值,然后 clone() 该对象在需要时制作现成的副本。 clone() 根本不需要参数,所以它显然不那么难看。如果您需要该对象的多个不同版本的多个副本,那么原型模式就会变得很有吸引力。
【讨论】: