java原型设计模式对象创建

时间:2012-07-29 03:57:02

标签: java design-patterns prototype-pattern

我正在经历原型设计模式,并有一些问题。

我已经理解Prototype设计模式用于创建在内存或资源方面成本高昂的对象。在这种情况下,我们使用已经可用的对象的克隆。

那么创建new对象和clone()之间有什么区别?对象存储在内存中的哪个位置?

3 个答案:

答案 0 :(得分:4)

Java clone()方法只创建一个新对象并将成员变量值复制到其中。通常,它既不比创建新对象更贵也更便宜。唯一一次clone()可能比用new创建一个对象便宜,那就是当一个对象的构造函数做了一些昂贵的事情时:例如,如果构造函数接受了参数并将它们作为一部分用于数据库查询?在这种情况下,使用clone()会更便宜,因为不会发生昂贵的查询操作。

使用此设计模式还有其他原因:大多数情况下,对象在使用前需要复杂的设置,这在构造函数中无法方便地完成。想象一下,一个对象有20个需要设置的属性。如果你用构造函数参数设置它们,那个构造函数会非常难看 - 想象一个带有20个参数的构造函数!相反,您可以构造一个可能没有参数的对象,使用mutator方法设置20个值,然后clone()该对象在需要时制作现成的副本。 clone()根本不需要任何参数,所以它显然不那么难看。如果您需要此对象的多个不同版本的多个副本,那么原型模式将变得具有吸引力。

答案 1 :(得分:4)

原型设计模式可节省两种成本 - 节省时间和节省空间。

在创建对象需要昂贵的辅助信息访问权限(例如,从文件,数据库或网络请求配置数据)时,会节省时间。例如,如果要从存储在Web服务器上的模板构建大量页面,则读取模板一次并克隆它以获取每个新页面的起点更便宜,而不是单独查询Web服务器每页。

通过重用不可变对象来节省内存:如果原始文件包含大量字符串,则创建新实例需要创建全新的不可变字符串,或者手动处理字符串实习。通过让克隆共享模板的不可变部分,优雅地使用原型模式可以避免这个问题。

答案 2 :(得分:0)

当对象的创建占用过多的系统资源和性能时,会使用原型设计模式,当我们想要有很多类的实例时,我们会使用这种设计模式,这些实例是相似的,所以我们不要我真的想要使用例如运算符“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

就像你看到这些对象的地址不同,因为它们不同。

  

注意!   我只使用“三星”这个名称作为例子。