设计模式之原型模式

在人生的道路上,不管是潇洒走一回,或者是千山独行,皆须是自己想走的路,虽然,有的人并不是很快就能找到自己的方向和道路,不过,只要坚持到底,我相信,就一定可以找到自己的路,只要找到路,就不必怕路途遥远了。

导读:本篇文章讲解 设计模式之原型模式,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

5.原型模式

  • 原型模式:实现克隆
  • javaScript继承是通过原型链来实现的。Prototype
  • 以原来的对象为原型拷贝一份,进行修改,新对象和原对象一样
  • 创建复杂对象时提高效率
5.1 深拷贝和浅拷贝
  • 前提了解深拷贝和浅拷贝的区别:深拷贝和浅拷贝的区别

  • 要点1:深拷贝和浅拷贝是针对对象属性为对象的,因为基本数据类型在进行赋值操作时(也就是拷贝)是直接将值赋给了新的变量,也就是该变量是原变量的一个副本,是值引用,而对于对象或者引用数据来说在进行浅拷贝时,只是将对象的引用复制了一份,也就内存地址,即两个不同的变量指向了同一个内存地址(地址引用),那么在改变任一个变量的值都是该变这个内存地址的所存储的值,所以两个变量的值都会改变。

  • java对象赋值是地址引用,两个对象地址相同

  • java的clone()方法是不彻底的深拷贝

    • 完全深拷贝情况:对象内部都是基本数据类型属性
    • 不彻底的深拷贝:对象内部存在引用数据对象
    • 浅拷贝要转换深拷贝:实现Cloneable接口,覆盖并实现clone方法,除了调用父类中的clone方法得到新的对象, 还要将该类中的引用变量也clone出来
Object obj01 = (Person) obj.clone()
  • A类

    public class Aclass implements Cloneable{
    private Bclass bc;

      public Aclass() {
    
      }
      public Aclass(Bclass bc) {
          this.bc = bc;
      }
    
      public Bclass getBc() {
          return bc;
      }
    
      public void setBc(Bclass bc) {
          this.bc = bc;
      }
    
      @Override
      public Object clone() throws CloneNotSupportedException {
          Aclass ac = (Aclass)super.clone();
          ac.bc = (Bclass)bc.clone();
          return ac;
      }
    

    }

      - B类
    
public class Bclass implements Cloneable{
    private Cclass cc;

    public Bclass() {
    }

    public Bclass(Cclass cc) {
        this.cc = cc;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public Cclass getCc() {
        return cc;
    }

    public void setCc(Cclass cc) {
        this.cc = cc;
    }
}
  • C类
public class Cclass {
}
  • 测试
public class TestClone {
    @Test
    public void testClone01() throws CloneNotSupportedException {
       System.out.println("ac.hashCode() = "+ac.hashCode() +"|| ac1.hashCode() = "+ac1.hashCode());
        System.out.println("ac == ac1 : " + (ac == ac1));

        System.out.println(" ac.getBc().hashCode()=" + ac.getBc().hashCode() + "||ac1.getBc().hashCode()=" + ac1.getBc().hashCode());
        System.out.println("ac.getBc() == ac1.getBc() : " +  (ac.getBc() == ac1.getBc()));

        System.out.println("ac.getBc().getCc().hashCode()=" + ac.getBc().getCc().hashCode() + "||ac1.getBc().getCc().hashCode()=" + ac1.getBc().getCc().hashCode());
        System.out.println("ac.getBc().getCc() == ac1.getBc().getCc(): " +  (ac.getBc().getCc() == ac1.getBc().getCc()));
    
    }
}
  • 结果呈现了:对象内部引用对象实现Cloneable接口,覆盖并实现clone方法,将外层对象由浅拷贝要转换深拷贝过程
ac.hashCode() = 231685785|| ac1.hashCode() = 114935352
ac == ac1 : false
ac.getBc().hashCode()=2110121908||ac1.getBc().hashCode()=32374789
ac.getBc() == ac1.getBc() : false
ac.getBc().getCc().hashCode()=1973538135||ac1.getBc().getCc().hashCode()=1973538135
ac.getBc().getCc() == ac1.getBc().getCc(): true

5.2 深克隆的方式
  • 复制拷贝一种实现:IO流,效率低
  • 另一种实现:内存拷贝,但java难以直接操作内存,需要使用C++的功能所以java调用的clone是本地方法
protected native Object clone() throws CloneNotSupportedException;
  • 实现深克隆的方式

序列化反序列化,操作IO

将对象的属性也进行克隆

5.3 应用场景
  • spring bean实现单例模式、原型模式
  • 原型模式和工厂模式的协同使用

工厂模式中new->原型模式

  • 原型对象十分复杂的情况创建另一个相同对象成本较大,所以用克隆方式来节省开销

本专栏下一篇:设计模式之适配器模式

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/123930.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!