专栏首页爱敲代码的猫java设计模式(4)-原型设计模式

java设计模式(4)-原型设计模式

这篇推文学习创建型模式最后一种-原型模式,该模式的思想是将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象,以便使用

首先需要了解对象深、浅复制的概念:

浅拷贝:将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的。深拷贝:将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。简单来说,就是深拷贝进行了完全彻底的复制,而浅拷贝不彻底。 Animal:具体原型类。实现克隆的具体操作。 Manager(这边用测试类代替):管理者类。让一个原型克隆自身,从而获得一个新的对象。所有的Java类都继承至Object,而Object类提供了一个clone()方法,该方法可以将一个java对象复制一份,因此在java中可以直接使用clone()方法来复制一个对象。但是需要实现clone的Java类必须要实现一个接口:Cloneable.该接口表示该类能够复制且具体复制的能力,如果不实现该接口而直接调用clone()方法会抛出CloneNotSupportedException异常

Java中任何实现了Cloneable接口的类都可以通过调用clone()方法来复制一份自身然后传给调用者。一般而言,clone()方法满足:

对任何的对象x,都有x.clone() !=x,即克隆对象与原对象不是同一个对象。 对任何的对象x,都有x.clone().getClass()==x.getClass(),即克隆对象与原对象的类型一样。 如果对象x的equals()方法定义恰当,那么x.clone().equals(x)应该成立。

public class Animal implements Cloneable{

    private String name;
    private Integer age;

    @Override
    protected Object clone(){
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }

    public Animal(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Animal{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    
    //此处省略getter setter
}

测试:

public class CloneTest {
    
    public static void main(String[] args) {

        //创建
        Animal cat = new Animal("cat", 2);

        //克隆
        Animal cat_2 = (Animal) cat.clone();

        //cat
        System.out.println("cat:" + cat);
        //cat_2
        System.out.println("cat_2:" + cat_2);

        //同个对象?false
        System.out.println( cat == cat_2);
        //x.clone().getClass()==x.getClass(),即克隆对象与原对象的类型一样
        System.out.println( cat.getClass() == cat_2.getClass());/true
    }
}

优点

如果创建新的对象比较复杂时,可以利用原型模式简化对象的创建过程,能够提高效率。可以使用深克隆保持对象的状态。原型模式提供了简化的创建结构。

缺点

在实现深克隆的时候可能需要比较复杂的代码。需要为每一个类配备一个克隆方法,而且这个克隆方法需要对类的功能进行通盘考虑,这对全新的类来说不是很难,但对已有的类进行改造时,不一定是件容易的事,必须修改其源代码,违背了“开闭原则”。

使用场景

如果创建新对象成本较大,我们可以利用已有的对象进行复制来获得。如果系统要保存对象的状态,而对象的状态变化很小,或者对象本身占内存不大的时候,也可以使用原型模式配合备忘录模式来应用。相反,如果对象的状态变化很大,或者对象占用的内存很大,那么采用状态模式会比原型模式更好。 需要避免使用分层次的工厂类来创建分层次的对象,并且类的实例对象只有一个或很少的几个组合状态,通过复制原型对象得到新实例可能比使用构造函数创建一个新实例更加方便。

本文分享自微信公众号 - 爱敲代码的猫(aquanrun),作者:Leemus

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-03-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 1月份GitHub上最热门的JavaScript项目

    明天相信大多数程序猿们都回归工作岗位啦,不知道是否调整好心态了呢?1月份GitHub上最热门的JavaScript开源项目新鲜出炉,还是一起来看看都有哪些项目上...

    爱敲代码的猫
  • 用代码生成一首现代诗~

    爱敲代码的猫
  • java设计模式(11)-组合模式

    这篇文章分享一下组合模式,具体类似于树形的数据结构,二叉树中有具体运用,有兴趣的可以翻阅资料。

    爱敲代码的猫
  • 设计模式实战 - 责任链模式

    JavaEdge
  • 梳理 50 年人机交互界面发展史,得出这个规律,开发框架的选择不再迷茫

    框架的英文是 Framework,与之经常并提的另一个词汇是 Library。两者的区别有哪些?

    李艺
  • 软件工程的那些图

    小编最近在画各种图,正好和大家一起复习一下。说到软件工程,不得不说一个语言:UML,即Unified Modeling Language ,统一建模语言...

    聚沙成塔
  • Jackson转换对象为json的时候报java.lang.stackoverflowerror

    无论在将一个对象转为json字符串的时候采用何种算法,如果你的对象的属性的类型不是基本类型或对应的引用类型,转换应该都不会就此结束,那么有一种方式可以导致这种转...

    程序员一一涤生
  • java设计模式-观察者模式

    基本概念:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己...

    哲洛不闹
  • DOM对象与jquery对象有什么不同

    1.jQuery对象和DOM对象 DOM对象,即是我们用传统的方法(javascript)获得的对象,jQuery对象即是用jQuery类库的选择器获得的对象;...

    用户5640963
  • [转]深复制与浅复制

    转自文章  http://iaman.actor/blog/2016/04/17/copy-in-python

    闪电gogogo

扫码关注云+社区

领取腾讯云代金券