设计模式之原型模式

原型模式(Prototype),其意图是用原型实例指定创建对象的种类,并且通过拷贝这些这些原型创建新的对象。原型模式意在通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝原型自己来实施创建过程。其允许一个对象再创建另外一个可定制的对象,无需知道任何创建的细节。

其适用性:

当一个系统应该独立于它的产品创建、构成和表示时,要使用Prototype模式;以及

当要实例化的类是在运行时刻指定时,例如,通过动态装载;或者

为了避免创建一个与产品类层次平行的工厂类层次时;或者

当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。

我们常在文件系统或者办公软件中见到的“粘贴-复制”是同样的道理,我们只需复制原来的内容,然后粘贴就出现与之前一样的内容,原型也就是这个道理。如

                      设计模式之原型模式

Prototype模式最主要的部分是正确实现Clone操作,我们常见的拷贝操作有两种方式,一种是浅拷贝,另一种是深拷贝,此处的深浅我们可以理解成是层次,如浅拷贝是指将一个对象复制后,基本数据类型的变量都会重新创建,引用类型指向的还是源对象所指向的;而深拷贝是指讲一个对象复制后,不论是基本数据类型还是引用数据类型,都会重新创建,层次更深些。

如下面的例子中,Shape类是抽象基类,它由一个info和copyShape方法,两者都是抽象方法,Circle类继承了Shape,实现了两个方法,如下:

Shape.java

 package org.designpattern.creational.prototype;

     public abstract class Shape implements  Cloneable {
           public abstract void info();
           public abstract Shape copyShape() throws CloneNotSupportedException;
     }

  Circle.java

      package org.designpattern.creational.prototype;
      public class Circle extends Shape {
         @Override
         public void info() {
               // TODO Auto-generated method stub
               System.out.println("this is a circle!");
         }
         @Override
         public Shape copyShape() throws CloneNotSupportedException {
               Circle circle = (Circle)super.clone();
                return circle;  //To change body of implemented methods use File | Settings | File Templates.
         }
      } 

  客户端类如下:

    package org.designpattern.creational.prototype;
    public class Main {
    /**
     * @param args
     
*/
    public static void main(String[] args)  {
        // TODO Auto-generated method stub
        try{
            Shape circle = new Circle();
            circle.info();
            Circle circleCp = (Circle) circle.copyShape();
            circleCp.info();
        }catch(CloneNotSupportedException ex){
            System.out.println("not support this clone!");
        }

     }

    }     

  原型模式的主要缺陷是每一个Prototype的子类都必须实现Clone操作,这样可能会很困难,如果类已经存在想要去克隆时添加Clone操作就不好了,而且如果内部包括一些无法拷贝的对象时,克隆会较困难。该模式常被使用于别的模式当中。