小叮当买了一台新手机,小叮咚看了表示很喜欢,要买一台一模一样的。要怎么实现呢?需要注意的是,这里和单例模式不一样,单例模式只有一台汽车,但这里需要两台手机,但是属性要一样。一个简单粗暴的实现方法:

public class Demo {public static void main(String[] args) {Phone phone = new Phone("苹果", "星光色", "iPhone 14");System.out.println("小叮当买了一台"+phone+phone.hashCode());Phone phone1 = new Phone("苹果", "星光色", "iPhone 14");System.out.println("小叮咚买了一台"+phone1+phone.hashCode());}
}

复制一份代码,也就是把构造函数的参数设置一份一模一样的创建一个新的实例。这个是最简单实现。但是有一个缺点,实际开发中,对象的参数很多,然后买同样一款手机的人也很多,这样我们就要手动复制很多份代码设置超级多的参数,会让代码看着很臃肿。做为一个优雅的程序员,这种重复性的脏话,我们是要想办法避免的。下面我们使用浅克隆来实现自动复制属性。

1-浅克隆:实现Cloneable接口然后继承clone()方法。

public class Phone implements Cloneable {//品牌private String band;//颜色private String color;//型号private String type;public Phone(String band, String color, String type) {this.band = band;this.color = color;this.type = type;}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}@Overridepublic String toString() {return "Phone{" +"band='" + band + '\'' +", color='" + color + '\'' +", type='" + type + '\'' +'}';}
}

如何使用呢?

public class Demo {public static void main(String[] args) throws CloneNotSupportedException {Phone phone = new Phone("苹果", "星光色", "iPhone 14");System.out.println("小叮当买了一台"+phone+phone.hashCode());Phone clone = (Phone) phone.clone();System.out.println("小叮咚买了一台"+clone+clone.hashCode());}
}

可以看到使用克隆方法简洁了很多,不用再填构造函数里的参数了。更优雅的实现了我们的需求。

2-浅克隆存在的问题

如果我们在Phone类新增一个属性Owner

    private Owner owner;

Owner实现如下

public class Owner {private String name;public Owner(String name){this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}

再测试一下clone方法

可以看到Phone的子属性Owner没有被复制,指向的是同一个对象实例,实际上,不止自定义的类型会有这个问题,使用Intger等包装类型也会出现则会个问题。如何解决这个问题呢,下面我们用深拷贝来解决这个问题。

3-深拷贝

3-1第一个办法是把Owner也实现Clone接口;并重写Phone的clone方法

public class Owner implements Cloneable {private String name;public Owner(String name){this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}//重写Phone的clone方法@Overrideprotected Object clone() throws CloneNotSupportedException {Phone phone = (Phone) super.clone();phone.owner = (Owner) phone.getOwner().clone();return phone;}public Owner getOwner() {return owner;}

测试一下

可以看到Owner指向的实例不一样了,说明克隆成功了,但是这样写比较麻烦,每加一个属性就要重写一下clone方法,如果嵌套多层的话,很容易漏写或者其他原因导致出错。下面我们使用第二种深拷贝来实现。

3-2使用序列化实现深拷贝

首先Phone和Owner都要实现Serializable接口,不用实现Cloneable接口了,然后添加serialVersionUID,保证序列号过程中不出错,然后重写Phone中的clone()方法,完整代码如下:

public class Phone implements Serializable {//序列化版本号private static final long serialVersionUID = 123456789L;//品牌private String band;//颜色private String color;//型号private String type;private Owner owner;public Phone(String band, String color, String type, Owner owner) {this.band = band;this.color = color;this.type = type;this.owner = owner;}@Overrideprotected Object clone(){Phone phone = null;try(ByteArrayOutputStream bos = new ByteArrayOutputStream()) {ObjectOutputStream oos = new ObjectOutputStream(bos);oos.writeObject(this);ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bis);phone = (Phone) ois.readObject();} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}return phone;}@Overridepublic String toString() {return "Phone{" +"band='" + band + '\'' +", color='" + color + '\'' +", type='" + type + '\'' +", owner=" + owner +'}';}
}public class Owner implements Serializable {//序列化版本号private static final long serialVersionUID = 123456789L;private String name;public Owner(String name){this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Owner{" +"name='" + name + '\'' +'}' + hashCode();}
}

测试一下

hashcode不一致,但是属性一致,说明克隆成功了。

总结一下:克隆模式在实际生产中用到的比较少,所以我暂时总结不出啥有价值的东西。

使用Java实现克隆模式(原型模式)相关推荐

  1. Java设计模式5:原型模式

    原型模式 原型模式属于对象的创建模式,通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象,这就是原型模式的用意. 原型模式结构 原型模式要求对象实现一个 ...

  2. 设计模式-创建型模式-原型模式(Java)(创建重复对象)

    目录 原型模式 1 介绍 2 实现 具体实现步骤 原型模式 原型模式(Prototype Pattern)是⽤于创建重复的对象,同时⼜能保证性能.这种类型的设计模式属于创建型模式,它提供了⼀种创建对象 ...

  3. java设计模式之五(原型模式)

    什么是原型模式? 原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 当我们程序中有几个相似但又不 ...

  4. 创建者模式——原型模式(克隆)

    文章目录 什么是原型模式 原型模式结构 原型模式的克隆种类 案例 验证为什么是浅克隆 深克隆 代码下载 什么是原型模式 原型模式就是: 用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型 ...

  5. 【设计模式】单例模式-生成器模式-原型模式

    前面的几种工厂模式,主要用于选择实现,这里的三种模式:单例模式.生成器模式.原型模式,主要用于生成对象,在GoF的划分中,这是创建型的五种模式(不包括简单工厂,前面提到过,这不是一个标准意义上的设计模 ...

  6. 创建型模式—原型模式

    原文作者:C语言中文网 原文地址:原型模式(原型设计模式)详解 目录 原型模式的定义与特点 原型模式的结构与实现 原型模式的应用实例 原型模式的应用场景 原型模式的扩展 在有些系统中,存在大量相同或相 ...

  7. 《设计模式详解》创建型模式 - 原型模式

    原型模式 4.3 原型模式 4.3.1 概述 4.3.2 结构 4.3.3 实现 4.3.4 案例 4.3.5 使用场景 4.3.6 扩展 - 深克隆 引用对象的浅克隆 实现 1:文件流 + 对象流 ...

  8. 创建型设计模模式---原型模式

    设计模式 序号 内容 链接地址 1 设计模式七大原则 https://blog.csdn.net/qq_39668819/article/details/115390615 2 创建型设计模式–工厂模 ...

  9. C++创建型模式-原型模式

    1.1 原型模式 原型模式的设计思想:在软件系统中,创建某一类型的对象,为了简化创建的过程,可以只创建一个对象,然后通过克隆的方式复制出多个相同的对象. 原型模式(Prototype Pattern) ...

  10. 原型模式 java 深浅_Java设计模式——原型模式

    原型模式(Prototype) 原型模式虽然是创建型的模式,但是与工程模式没有关系,从名字即可看出,该模式的思想就是将一个对象作为原型,对其进行复制.克隆,产生一个和原对象类似的新对象.本小结会通过对 ...

最新文章

  1. Linux pwn入门教程——CTF比赛
  2. python详细安装步骤-Python的详细安装步骤
  3. C++纯虚函数和抽象类
  4. SAP Marketing Cloud的几大核心模块讲解
  5. bpmn2.0业务过程模型和符号_IT帮业务架构学习小组学习内容
  6. mysql-复习表的基本操作01
  7. linux环境安装jdk啊
  8. 高并发之——Guava Cache
  9. OpenLayers实例:打开ArcGIS Rest服务
  10. java 怎么把日期格式化时间_Java—格式化日期/时间
  11. 【张朝阳的物理课笔记】 5. 波动方程,声音在空气中的传播速度
  12. PHP复合函数,复合函数中的剥洋葱理论
  13. 毕业季深度学习方面神器----恒源云gpu算力平台
  14. 【RK3399 GMAC】Linux Debian9 gmac 主控输出clk ,即output模式
  15. android陀螺仪判断手机旋转方向,unity 陀螺仪判断手机方向
  16. 留言管理系统的设计与实现
  17. SAP中寄售补货的两种方法分析
  18. onload js函数不执行的原因分析及解决方法
  19. java计算机毕业设计教师教学质量评估系统源码+mysql数据库+系统+lw文档+部署 - 副本
  20. win7运行在哪_控制面板在哪,n卡控制面板打不开

热门文章

  1. android 设置电池状态
  2. Redis实现分布式锁(SETNX)
  3. 圣诞夜工程师写了12首表白情诗,你会沉迷哪一首?...
  4. 华为鸿蒙系统128g多少钱,华为宣布鸿蒙OS 2.0开源!明年4月将面向内存128MB-4GB设备开源...
  5. P20、21、22 事件详解
  6. 《Spring in action,3th》阅读笔记
  7. android+分享微信朋友圈带编辑功能,新功能 微信6.6.6安卓版发布:朋友圈编辑可保留...
  8. StarUML画类图
  9. 用Python+requests库批量下载知乎高赞回答中的所有表情包
  10. 两个经纬度之间距离和角度的计算