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,排除     在复制过程之外。

  • 相关阅读:
    Asynchronous AOF fsync is taking too long (disk is busy?). Writing the AOF buffer without waiting for fsync to complete, this may slow down Redis.
    DHCP "No subnet declaration for xxx (no IPv4 addresses)" 报错
    Centos安装前端开发常用软件
    kubernetes学习笔记之十:RBAC(二)
    k8s学习笔记之StorageClass+NFS
    k8s学习笔记之ConfigMap和Secret
    k8s笔记之chartmuseum搭建
    K8S集群集成harbor(1.9.3)服务并配置HTTPS
    Docker镜像仓库Harbor1.7.0搭建及配置
    Nginx自建SSL证书部署HTTPS网站
  • 原文地址:https://www.cnblogs.com/youxin/p/2950190.html
Copyright © 2011-2022 走看看