zoukankan      html  css  js  c++  java
  • 设计模式之prototype原型模式

    definition

    Specify the kind of objects to create using a prototypical instance, and create new objects by copying this prototype

    participants

        The classes and/or objects participating in this pattern are:

    • Prototype  (ColorPrototype)
      • declares an interface for cloning itself
    • ConcretePrototype  (Color)
      • implements an operation for cloning itself
    • Client  (ColorManager)
      • creates a new object by asking a prototype to clone itself

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

    public abstract class AbstractSpoon implements Cloneable{
      String spoonName;
    
      public void setSpoonName(String spoonName) {
                this.spoonName = spoonName;
          }
      public String getSpoonName() {return this.spoonName;}
    
      public Object clone(){
        Object object = null;
        try {
          object = super.clone();
        } catch (CloneNotSupportedException exception) {
          System.err.println("AbstractSpoon is not Cloneable");
        }
        return object;
      }
    }

    个具体实现(ConcretePrototype):

    public class SoupSpoon extends AbstractSpoon{
      public SoupSpoon(){
        setSpoonName("Soup Spoon");
      }
    }

    调用Prototype模式很简单:

    AbstractSpoon spoon = new SoupSpoon();
    AbstractSpoon spoon2 = spoon.clone();

    当然也可以结合工厂模式来创建AbstractSpoon实例。

    在Java中Prototype模式变成clone()方法的使用,此方法执行的是该对象的“浅表复制”,而不“深层复制”操作。

    AbstractSpoon实现clone时调用super.clone()的原理:

    ava super.clone   实现Cloneable接口

    首先,如果允许本来被克隆,需要实现 实现Cloneable接口

    并且重写clone方法,且方法最好为public,这样方便别人调用

    其中:super.clone并不是简单的说成是调用父类的clone方法,这样的话你很难想通,为什么调用父类的clone,对吧?

    因为Object的clone方法使用了RTTI(运行时类型识别)机制,可以动态的找到目前正在调用clone方法的那个引用,并找到它指向的对象,然后根据这个对象的大小去申请内存空间,然后进行bitwise(逐位)的复制, 将该对象的内存空间完全复制到新的空间中去,

    从而达到克隆的目的.

    即,谁调用clone方法,就克隆这引用指向的对象

     子类没有clone方法,使用this.clone()则直接异常,,因为是子类继承Object的 

    比如你有一个Student类实现了Cloneable接口,重写了clone方法,但是重写的clone方法里的执行super.clone,并不是说和自身无关,

     例如:     Student stu=new student();

                     Student stu1=(Student)stu.clone();

    当执行stu.clone();时候,虽然clone方法里面执行的是super.clone(),但是Object的clone方法会寻找当前正在调用clone方法的那个引用,这里这个引用就是stu,然后自动的去找stu指向的对象,然后进行逐位赋值,从而达到克隆的目的,

    还有继承的时候,A类实现了Cloneable接口,重写了了clone方法,那继承A类的类就不必实现Cloneable接口以及重写clone方法了,因为A类已经这么做了。而当子类调用clone方法的时候,是根据调用clone方法的当前引用去克隆的,

    还是那句话,谁调用clone方法,就克隆当前引用指向的对象。

    说明: 
    克隆必须满足的条件: 
    a.对任何的对象x,都有:x.clone() != x,即克隆对象与原对象不是同一个对象。 
    b.对任何的对象x,都有:x.clone().getClass() == x.get getClass(),即克隆对象与原对象的类型是一样的。 c.如果对象x的equals()方法定义恰当的话,那么x.clone().equals(x)应当是成立的。 
    在java中实现clone()应该满足这三个条件。 

    浅复制复制了值类型对象,对于引用类型对象,只复制了引用,它指向原来引用的对象。Java中clone为浅复制。 
    深复制对值类型和引用类型的对象都生成一份新的拷贝. Java中可以通过串行化来进行深复制,前提是对象以及对象内部所引用的对象都是可串行化的,否则需要考虑将那些不可串行化的对象可否设为transient,排除     在复制过程之外。

  • 相关阅读:
    IM的扫码登录功能如何实现?一文搞懂主流的扫码登录技术原理
    IM“扫一扫”功能很好做?看看微信“扫一扫识物”的完整技术实现
    2020年了,Android后台保活还有戏吗?看我如何优雅的实现!
    P2P技术详解(三):P2P中的NAT穿越(打洞)方案详解(进阶分析篇)
    微信团队分享:极致优化,iOS版微信编译速度3倍提升的实践总结
    史上最通俗,彻底搞懂字符乱码问题的本质
    你知道,HTTPS用的是对称加密还是非对称加密?
    IM开发基础知识补课(七):主流移动端账号登录方式的原理及设计思路
    面视必备,史上最通俗计算机网络分层详解
    阿里钉钉技术分享:企业级IM王者——钉钉在后端架构上的过人之处
  • 原文地址:https://www.cnblogs.com/youxin/p/2950190.html
Copyright © 2011-2022 走看看