JAVA设计模式 2【创建型】原型模式的理解与使用、理解浅克隆和深克隆
2020-06-21 22:45
387 查看
在本节中,我们将学习和使用原型模式;这一节学习的原型模式也是`创建型` 模式的其中之一。再次复习一下:`创建型` 模式就是描述如何去更好的创建一个对象。
我们都知道,在JAVA 语言中。使用`new` 关键字创建一个新对象。将新的对象放到`堆内存` 里面。当然,这个内存肯定是有大小限制的,况且,JAVA 不同于C语言等。 有内存管理机制,就是我们常说的`垃圾回收器GC`,才可以保证内存不被溢出。
说这些其实就是为了表示:为啥要用单例模式,能节省内存的时候,能用一个对象解决重复的事情,绝对不会创建多个。
## 概述
原型模式描述的如何快速创建重复的对象,并且减少new 关键字的使用。
- 抽象原型类
- 具体原型类
- 访问类
容我来一个一个解释:
**抽象原型类** 也就是我们具体要实现的某个类,这个类在JAVA 里面是有具体的接口的,其实是一个空接口,`Cloneable`
```java
* @author unascribed
* @see java.lang.CloneNotSupportedException
* @see java.lang.Object#clone()
* @since JDK1.0
*/
public interface Cloneable {
}
```
我们会发现,这个类没有任何的方法,怎么来实现它,不要慌。先接着走。
**具体原型类** 也就是我们具体要`克隆` 的对象。比如我们重复的要创建100个`学生Student` 对象,那么具体的学生对象就是`具体原型类`
```java
public class Student implements Cloneable {
private int id;
private String name;
private int sex;
}
```
**访问类** 我就不必多说了
## 浅克隆和深克隆
原型模式其实也分浅克隆和深克隆。如何理解这两个概念呢?
### 浅克隆
```java
protected native Object clone() throws CloneNotSupportedException;
```
浅克隆,只需要`具体原型类` 实现Cloneable 接口,并且重写父类`Object`类的clone() 方法,即可实现对象的浅克隆。
```java
Student student1 = new Student(1, "李四");
Student student2 = student1.clone();
System.out.println(student1);
System.out.println(student2);
System.out.println(student1 == student2);
---------------------
学号:1,姓名:李四
学号:1,姓名:李四
false
```
- 通过执行`clone()` 方法即可创建一个相同的,具有同样属性的对象。
- 并且是新的对象,内存地址有所不同。
我们来看看,对于引用类型的变量,浅克隆是否可以进行克隆;
```java
Teacher teacher = new Teacher(1, "张老师");
Student student1 = new Student(1, "李四", teacher);
Student student2 = student1.clone();
System.out.println(student1);
System.out.println(student2);
System.out.println(student1 == student2);
------------
学号:1,姓名:李四,老师=Teacher@1b6d3586
学号:1,姓名:李四,老师=Teacher@1b6d3586
false
```
我们发现,引用类型并没有被克隆,也就是说:
### 特点
- 浅克隆对于基本类型,可以进行完全的克隆,并且克隆的对象是一个新的对象
- 但是对象里面的引用,是无法被克隆的。
### 深克隆(序列化)
何谓序列化?
我们创建的都是保存在内存里面的,只要被虚拟机GC进行回收,那么这个对象的任何属性都是消失,我们能不能找一个方法,将内存中这种对象的属性以及对象的状态通过某种东西保存下来,比如保存到数据库,下次从数据库将这个对象`还原`到内存里面。 这就是序列化。
- 序列化 `内存对象->序列字符`
- 反序列化 `序列字符->内存对象`
>请参考: https://baike.baidu.com/item/%E5%BA%8F%E5%88%97%E5%8C%96/2890184
### JAVA 序列化
```java
* @see java.io.Externalizable
* @since JDK1.1
*/
public interface Serializable {
}
```
JAVA 提供了一个空接口,其实这个接口和上面的`Cloneable` 一样,都是一个空接口,其实这个空接口就是作为一种`标识` 你的对象实现了这个接口,JAVA 认为你的这个就可以被序列化 ,就是这么简单。
```java
Teacher teacher = new Teacher(1, "张老师");
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ObjectOutputStream stream = new ObjectOutputStream(outputStream);
stream.writeObject(teacher);
System.out.println(Arrays.toString(outputStream.toByteArray()));
----------
[-84, -19, 0, 5, 115, 114, 0, 7, 84, 101, 97,。。。。。。
```
通过将对象序列化、其实也就是将内存中的对象转化为二进制 `字节数组`
### 反序列化
```
Teacher teacher = new Teacher(1, "张老师");
System.out.println(teacher);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ObjectOutputStream stream = new ObjectOutputStream(outputStream);
stream.writeObject(teacher);
System.out.println(Arrays.toString(outputStream.toByteArray()));
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(outputStream.toByteArray());
ObjectInputStream inputStream = new ObjectInputStream(byteArrayInputStream);
Teacher teacher1 = (Teacher) inputStream.readObject();
System.out.println(teacher1);
---------------
id=1,name=张老师
[-84, -19, 0, 5, 115, xxxxx,-127, -27, -72, -120]
id=1,name=张老师
```
通过序列化和反序列化,即可对象的深克隆
## 小结
这一节,在讲述 原型模式的同时,将原有实现原型模式的`clone()` 浅克隆,延伸到深克隆这一概念。其实JAVA 的原型模式,实现起来较为简单。但还是要按需要实现,Object 类提供的 `clone 浅克隆` 是没办法克隆对象的引用类型的。需要克隆引用类型,还是需要`序列化` 深克隆
### 参考
http://c.biancheng.net/view/1343.html
https://www.liaoxuefeng.com/wiki/1252599548343744/1298366845681698
### 代码示例
https://gitee.com/mrc1999/Dev-Examples
### 欢迎关注
![](https://file.chaobei.xyz/blogs/banner_1591192617234.jpg)
相关文章推荐
- Java技术_每天掌握一种设计模式(006)_使用场景及简单实例(创建型:原型模式)
- Java常用的设计模式05:常用设计模式之原型模式(创建型模式)
- JAVA设计模式(5) —<创建型>原型模式(Prototype)
- 设计模式理解(二)创建型——单例、原型
- java设计模式——创建型之原型模式
- Java设计模式——创建型模式——原型模式(Prototype Pattern)
- 设计模式(Design Pattern) - 创建型模式(Creational Pattern) - 原型模式(Prototype) - Java实现
- Java设计模式_(创建型)_原型模式
- 克隆复制可使用原型( Prototype)设计模式
- 05 【创建型】原型模式 理解克隆对象~
- java设计模式之--原型模式(克隆模式)
- Java技术_每天掌握一种设计模式(004)_使用场景及简单实例(创建型:抽象工厂)
- Java技术_每天掌握一种设计模式(002)_使用场景及简单实例(创建型:单例模式)
- GOF23设计模式之观察者模式的理解与实现2(使用java自带的观察者类和接口)
- java设计模式学习笔记--原型模式(浅克隆和深克隆)
- Java与设计模式(十四)创建型--原型模式
- JAVA设计模式(05):创建型-原型模式(Prototype)
- Java设计模式之原型模式(属于创建型模式)
- java-设计模式(创建型)-【原型模式】
- JAVA设计模式(05):创建型-原型模式(Prototype)