• 六个创建模式之原型模式(Prototype Pattern)


    定义:
    使用原型实例指定创建对象的种类,并通过拷贝这个原型的属性创建新的对象。

    结构图:

    • Prototype:抽象原型类,声明克隆方法的接口,并是所有原型类的公共父类。在Java中,Object类为该角色。
    • ConcretePrototype:具体原型类,实现克隆方法,返回自己的一个克隆对象。
    • Client:从一个已有的原型对象,调用其克隆方法,获得该对象的克隆对象,针对抽象原型类编程,方便进行扩展和修改。

    浅克隆(Shallow Clone)

    • 浅克隆中,如果原型对象的成员变量是值类型,则进行复制,不会相互影响,如果是引用类型,则将其地址复制,实质上指向的是同一个对象。
    • 在Java语言中可以覆盖Object中的clone()方法来实现浅克隆,其中具体原型类必需要实现Cloneable接口。如果没有实现这个接口,则会抛出CloneNotSupportedException。
    class ConcretePrototype implements  Cloneable
    {
    ……
    public Prototype  clone()
    {
      Object object = null;
      try {
         object = super.clone();
      } catch (CloneNotSupportedException exception) {
         System.err.println("Not support cloneable");
      }
      return (Prototype )object;
    }
    ……
    }
    

    深克隆(Deep Clone)

    • 无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象。
    • 在Java中可以通过序列化(Serialization)来进行深克隆,即原型对象实现Serializable接口,然后写入到ObjectOutputStream,则从该Stream读出对象即可。
     //使用序列化技术实现深克隆
    public object deepClone() throws  IOException, ClassNotFoundException, OptionalDataException{
    	//将对象写入流中
    	ByteArrayOutputStream bao=new  ByteArrayOutputStream();
    	ObjectOutputStream oos=new  ObjectOutputStream(bao);
    	oos.writeObject(this);
    	
    	//将对象从流中取出
    	ByteArrayInputStream bis=new  ByteArrayInputStream(bao.toByteArray());
    	ObjectInputStream ois=new  ObjectInputStream(bis);
    	return  (WeeklyLog)ois.readObject();
    }
    

    原型管理器
    原型管理器是将多个原型对象存储在一个集合中供客户端使用,专门负责克隆对象的工厂,类似于简单工厂方法,通过key来获取一个新的对象。

    • 原型管理器中往往使用一个HashTable来管理所有原型对象。
    • 可以提供一个默认的原型对象,如果有新的写入,可以将原有的对象进行覆盖。
    • 读取时,从HashTable中获得原型对象,然后调用原型对象的clone方法获得一个新的对象。

    优点:

    • 当创建一个对象比较复杂时,原型模式可以简化其创建过程,通过复制获得和已有实例相同的对象。
    • 简化创建结构,不需要专门的工厂存在,仅需要实现克隆方法即可。

    缺点:

    • 克隆方法位于类的内部,家中了类的职责,对已有类进行改造时,需要修改源码。
    • 在实现深克隆时需要较为复杂的代码,存在多重嵌套的问题。

    适用场景:

    • 创建新对象的成本比较大,新的对象可以通过原型模式对已有对象进行复制来获得。
    • 如果系统要保存对象状态,并且对象本身占用内存很少,可以使用原型模式配合备忘录模式来实现。

    实例:

    PrototypePattern.java

  • 相关阅读:
    IOS 关于分辨率的那点事
    IOS多线程编程之NSOperation和NSOperationQueue的使用
    UI应遵循的三大网站设计原则
    Xcode 4.4中LLVM compiler 4.0带来的ObjectiveC新语法特性
    iPhone实战:操作SQLite
    flock()函数使用示例
    libtool: syntax error near unexpected token `]*'
    求职简历撰写要点
    thrift的js客户端收到含汉字字符中显示为乱码解决方法
    多写引发的思考
  • 原文地址:https://www.cnblogs.com/zhangfei614/p/5998034.html
Copyright © 2020-2023  润新知