• 创建类模式(四):原型(Prototype)


    定义

    用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

    原型模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。

    UML

    优点

    1. 使用原型模式创建对象比直接new一个对象在性能上要好的多,因为Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。
    2. 使用原型模式的另一个好处是简化对象的创建,使得创建对象就像我们在编辑文档时的复制粘贴一样简单。

    缺点

    1. 复制对象有时相当复杂。

    应用场景

    1. 需要重复地创建相似对象时可以考虑使用原型模式。比如需要在一个循环体内创建对象,假如对象创建过程比较复杂或者循环次数很多的话,使用原型模式不但可以简化创建过程,而且可以使系统的整体性能提高很多。

    注意事项

    1. 使用原型模式复制对象不会调用类的构造方法。因为对象的复制是通过调用Object类的clone方法来完成的,它直接在内存中复制数据,因此不会调用到类的构造方法。不但构造方法中的代码不会执行,甚至连访问权限都对原型模式无效。还记得单例模式吗?单例模式中,只要将构造方法的访问权限设置为private型,就可以实现单例。但是clone方法直接无视构造方法的权限,所以,单例模式与原型模式是冲突的,在使用时要特别注意。
    2. 深拷贝与浅拷贝。Object类的clone方法只会拷贝对象中的基本的数据类型,对于数组、容器对象、引用对象等都不会拷贝,这就是浅拷贝。如果要实现深拷贝,必须将原型模式中的数组、容器对象、引用对象等另行拷贝。

    在Java中深复制如下:

     1 public class Prototype implements Cloneable
     2 {
     3     private ArrayList list = new ArrayList();
     4     
     5     public Prototype clone()
     6     {
     7         Prototype prototype = null;
     8         try
     9         {
    10             prototype = (Prototype) super.clone();
    11             prototype.list = (ArrayList) this.list.clone();
    12         }
    13         catch (CloneNotSupportedException e)
    14         {
    15             e.printStackTrace();
    16         }
    17         return prototype; 
    18     }
    19 }

    由于ArrayList不是基本类型,所以成员变量list,不会被拷贝,需要我们自己实现深拷贝,幸运的是java提供的大部分的容器类都实现了Cloneable接口。所以实现深拷贝并不是特别困难。

    深拷贝与浅拷贝问题中,会发生深拷贝的有java中的8中基本类型以及他们的封装类型,另外还有String类型。其余的都是浅拷贝。

    示例

    使用原型模式创建对象。

    Java

     1 public class Main
     2 {
     3     public static void main(String[] args)
     4     {
     5         ConcretePrototype cp = new ConcretePrototype();
     6         for (int i=0; i< 10; i++)
     7         {
     8             ConcretePrototype clonecp = (ConcretePrototype)cp.clone();
     9             clonecp.show();
    10         }
    11     }
    12     
    13     public static class Prototype implements Cloneable
    14     {
    15         public Prototype clone()
    16         {
    17             Prototype prototype = null;
    18             try
    19             {
    20                 prototype = (Prototype)super.clone();
    21             }
    22             catch(CloneNotSupportedException e)
    23             {
    24                 e.printStackTrace();
    25             }
    26             return prototype; 
    27         }
    28     }
    29 
    30     public static class ConcretePrototype extends Prototype
    31     {
    32         public void show()
    33         {
    34             System.out.println("原型模式实现类");
    35         }
    36     }
    37 }
    View Code
  • 相关阅读:
    20140710 sequence 前缀和
    20140709 testC 数学题
    20140708 testA 组合数学
    20140708 testB DP 组合数学
    Sad :(
    已经是一个废人了……
    Game Theory
    HDU Math Problems
    2-sat问题
    并查集
  • 原文地址:https://www.cnblogs.com/hammerc/p/4743770.html
Copyright © 2020-2023  润新知