设计模式 - 原型模式

news/2024/11/25 19:26:16/

传统方式

public class Sheep {private String name;private int age;private String color;public Sheep(String name, int age, String color) {super();this.name = name;this.age = age;this.color = color;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}@Overridepublic String toString() {return "Sheep [name=" + name + ", age=" + age + ", color=" + color + "]";}public static void main(String[] args) {//传统的方法Sheep sheep = new Sheep("tom", 1, "白色");Sheep sheep2 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());Sheep sheep3 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());Sheep sheep4 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());Sheep sheep5 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());//....System.out.println(sheep);System.out.println(sheep2);System.out.println(sheep3);System.out.println(sheep4);System.out.println(sheep5);}
}

优点:

比较好理解,简单易操作

缺点:

  • 在创建新的对象时,总是需要重新获取原始对象的属性,如果创建的对象比较复杂 时,效率较低
  • 总是需要重新初始化对象,而不是动态地获得对象运行时的状态, 不够灵活

原型模式

基本介绍:

  • 原型模式(Prototype模式)是指:用原型实例指定创建对象的种类,并且通过拷 贝这些原型,创建新的对象
  • 原型模式是一种创建型设计模式,允许一个对象再创建另外一个可定制的对象, 无需知道如何创建的细节
  • 工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建 的对象通过请求原型对象拷贝它们自己来实施创建,即 对象.clone()

浅拷贝

基本介绍:

  • 对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将 该属性值复制一份给新的对象
  • 对于数据类型是引用数据类型的成员变量,比如说成员变量是某个数组、某个类 的对象等,那么浅拷贝会进行引用传递,也就是只是将该成员变量的引用值(内 存地址)复制一份给新的对象。因为实际上两个对象的该成员变量都指向同一个 实例。在这种情况下,在一个对象中修改该成员变量会影响到另一个对象的该成 员变量值
  • 使用默认的 clone()方法来实现

示例代码:

public class Sheep implements Cloneable {private String name;private int age;private String color;private String address = "蒙古羊";public Sheep friend; //是对象, 克隆是会如何处理public Sheep(String name, int age, String color) {super();this.name = name;this.age = age;this.color = color;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}@Overridepublic String toString() {return "Sheep [name=" + name + ", age=" + age + ", color=" + color + ", address=" + address + "]";}//克隆该实例,使用默认的clone方法来完成@Overrideprotected Object clone()  {Sheep sheep = null;try {sheep = (Sheep)super.clone();} catch (Exception e) {// TODO: handle exceptionSystem.out.println(e.getMessage());}// TODO Auto-generated method stubreturn sheep;}public static void main(String[] args) {System.out.println("原型模式完成对象的创建");// TODO Auto-generated method stubSheep sheep = new Sheep("tom", 1, "白色");sheep.friend = new Sheep("jack", 2, "黑色");Sheep sheep2 = (Sheep)sheep.clone(); //克隆Sheep sheep3 = (Sheep)sheep.clone(); //克隆Sheep sheep4 = (Sheep)sheep.clone(); //克隆Sheep sheep5 = (Sheep)sheep.clone(); //克隆System.out.println("sheep2 =" + sheep2 + "sheep2.friend=" + sheep2.friend.hashCode());System.out.println("sheep3 =" + sheep3 + "sheep3.friend=" + sheep3.friend.hashCode());System.out.println("sheep4 =" + sheep4 + "sheep4.friend=" + sheep4.friend.hashCode());System.out.println("sheep5 =" + sheep5 + "sheep5.friend=" + sheep5.friend.hashCode());}
}

深拷贝

基本介绍:

  • 复制对象的所有基本数据类型的成员变量值
  • 为所有引用数据类型的成员变量申请存储空间,并复制每个引用数据类型成员变 量所引用的对象,直到该对象可达的所有对象。也就是说,对象进行深拷贝要对 整个对象进行拷贝

实现方式:

  • 重写clone方法来实现深拷贝
  • 通过对象序列化实现深拷贝(推荐)

示例代码:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;public class DeepProtoType implements Serializable, Cloneable{public String name;	// String 类型public DeepCloneableTarget deepCloneableTarget;	// 引用类型public DeepProtoType() {super();}@Overrideprotected Object clone() throws CloneNotSupportedException {// 这里完成的基本数据类型(属性) 和 String 的克隆DeepProtoType obj = (DeepProtoType) super.clone();// 对引用类型的属性,进行单独处理obj.deepCloneableTarget = (DeepCloneableTarget) (obj.deepCloneableTarget.clone());return obj;}public Object deepClone() {ByteArrayOutputStream baos = null;ByteArrayInputStream bais = null;ObjectOutputStream oos = null;ObjectInputStream ois = null;try{// 序列化baos = new ByteArrayOutputStream();oos = new ObjectOutputStream(baos);oos.writeObject(this);		// 当前这个对象以对象流的方式输出// 反序列化bais = new ByteArrayInputStream(baos.toByteArray());ois = new ObjectInputStream(bais);DeepProtoType copyObj = (DeepProtoType)ois.readObject();return copyObj;}catch (Exception ex) {ex.printStackTrace();return null;}finally {// 关闭流try {baos.close();bais.close();oos.close();ois.close();}catch (Exception e2) {System.out.println(e2.getMessage());}}}public static void main(String[] args) throws CloneNotSupportedException {DeepProtoType p = new DeepProtoType();p.name = "宋江";p.deepCloneableTarget = new DeepCloneableTarget("大牛", "小牛");DeepProtoType p2 = (DeepProtoType) p.clone();System.out.println("p.name=" + p.name + " p.deepCloneableTarget=" + p.deepCloneableTarget.hashCode());System.out.println("p2.name=" + p.name + " p2.deepCloneableTarget=" + p2.deepCloneableTarget.hashCode());DeepProtoType p3 = (DeepProtoType) p.deepClone();System.out.println("p.name=" + p.name + " p.deepCloneableTarget=" + p.deepCloneableTarget.hashCode());System.out.println("p3.name=" + p3.name + " p3.deepCloneableTarget=" + p3.deepCloneableTarget.hashCode());}
}


http://www.ppmy.cn/news/83482.html

相关文章

关于I/O

I/O 1. 概念1.1 页缓存的简单工作流程1.2 页缓存的写机制或者写触发的时机1.3 为什么需要套字节缓冲区1.4 套接字缓冲区的简单流程 2. 传统I/O方式2.1 传统I/O读写流程2.2 传统 I/O的性能问题 3. DMA技术3.1 将数据写入磁盘的流程3.2 从磁盘读取数据的流程 4. 网络数据传输流程…

C++第一章:开始

开始目录 引言一、开发环境和参考书籍二、一个简单的C程序三、初识输入和输出标准输入输出对象 四、注释五、控制流while循环for循环 六、数量不定数据的输入七、C 缩进和格式八、类简介使用一个类书店处理书籍信息程序 九、术语表 引言 C在人们的眼中通常是“复杂”一词的代表…

【作为程序员,你有什么让人眼前一亮的代码实现方式?】

编程语言介绍 随着科技的不断发展,编程语言也在不断更新和改进。作为程序员,我们需要选取一种适合自己的高级编程语言来完成项目任务。下面将介绍常见的三种高级编程语言:Python、Java和C。 Python Python是一种高级编程语言,具…

Shell基础

目录 第1章 Shell概述 第2章 Shell脚本入门 第3章 变量 3.1 系统预定义变量 3.2 自定义变量 3.3 特殊变量 3.3.1 $n 3.3.2 $# 3.3.3 $*、$ 3.3.4 $? 第4章 运算符 第5章 条件判断 第6章 流程控制(重点) 6.1 if判断 6.2 case语…

STL --- 3、迭代器 Iterators

目录 1、std::iterator 的定义和作用 2、std::iterator常用的api 3、std::iterator 迭代器的种类 4、std::iterator迭代器的使用 5、std::iterator 迭代器的适配器 1、std::iterator 的定义和作用 (1)std::iterator 是 C STL 中的一个概念&#x…

基于机器学习的调制方式识别+电磁频谱数据的特征介绍

文章目录 1. 调制方式识别尝试1:换模型(有提升)尝试2:拼接多个功率谱特征(失败)尝试3:统计特征(失败)尝试4:变换域(未尝试)尝试5:机理分析(未尝试)2. 论文阅读:《电磁频谱数据的关联规则挖掘》2.1 异常信息2.2 底噪信息2.3 占用度信息2.4 预定时间功率值2.5 频…

【网络】- 计算机网络体系结构 - OSI七层模型、TCP/IP四层(五层)协议

目录 一、概述 二、计算机网络体系结构的形成  👉2.1 分层的网络体系结构  👉2.2 OSI 参考模型  👉2.3 TCP/IP - 事实的国际标准 三、OSI 参考模型 四、TCP/IP 协议 一、概述 但凡学习计算机网络知识,肯定绕不过网络协议的&…

【Java系列】深入解析枚举类型

序言 即便平凡的日子仿佛毫无波澜,但在某个特定的时刻,执着的努力便会显现出它的价值和意义。 希望这篇文章能让你不仅有一定的收获,而且可以愉快的学习,如果有什么建议,都可以留言和我交流 问题 思考一下这寄个问题&a…