原型模式
概述:
用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象。
结构:
原型模式 = 抽象原型类+具体原型类+访问类
抽象原型类:规定具体原型类必须实现clone()方法
具体原型类:实现抽象原型类的clone(),他是可被复制的对象。
访问类:使用具体原型类中的clone()方法来复制新的对象。
实现:
克隆分为浅克隆、深克隆
浅克隆:新对象与原来对象完全相同,如果原对象中属性是非基本属性类型,则复制,如果不是则沿用原属性的对象地址(java中已有Cloneable接口进行浅克隆)
深克隆:新对象,新对象属性无论是基本数据类型的属性,还是非基本的属性都克隆一份,地址不同。
Person类
package com.boshwx.Study_DesignType23.CreatorType.ModelMode;
import java.io.Serializable;
/**
* 人类 继承可复制接口
* 属性:
* DNA 对象
*/
public class Person implements Cloneable, Serializable {
// private String name;
private DNA dna;
/**
*
* @return
* @throws CloneNotSupportedException
*/
@Override
protected Person clone() throws CloneNotSupportedException {
return (Person)super.clone();
}
public void sayHello(){
System.out.println("我的 DNA为"+this.getDna().getSerialize());
}
public DNA getDna() {
return dna;
}
public void setDna(DNA dna) {
this.dna = dna;
}
}
DNA类
package com.boshwx.Study_DesignType23.CreatorType.ModelMode;
import java.io.Serializable;
/**
* DNA 可复制
*/
public class DNA implements Cloneable , Serializable {
private String serialize ;
public DNA() {
setSerialize(Math.random()+"");
}
public String getSerialize() {
return serialize;
}
public void setSerialize(String serialize) {
this.serialize = serialize;
}
}
测试类
package com.boshwx.Study_DesignType23.CreatorType.ModelMode;
import java.io.*;
public class client {
public static void main(String[] args) throws CloneNotSupportedException {
/*
创建一个人类
复制一个人类
*/
Person person = new Person();
person.setDna(new DNA());
/*
方式一:浅克隆
*/
Person clonePerson = person.clone();
clonePerson.getDna().setSerialize(Math.random()+"");
/*
目的:证明浅克隆,对基本数据类型为复制,对象类属性复制了地址。
*/
person.sayHello();
clonePerson.sayHello();
if(person.getDna()==clonePerson.getDna()){
System.out.println("dna指向同一地址?"+true);
}else{
System.out.println("dna指向同一地址?"+false);
}
System.out.println("---------------------------------------------");
/*
方式二:深克隆(通过写入配置文件,再读取对象值,读取出的对象,
对象类型的属性也同样被复制,地址不同。)
*/
try {
ObjectOutputStream fos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\wx\\Desktop\\1.txt"));
fos.writeObject(person);
fos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\wx\\Desktop\\1.txt"));
Person clone = (Person)ois.readObject();
ois.close();
if(person.getDna()==clone.getDna()){
System.out.println("dna指向同一地址?"+true);
}else{
System.out.println("dna指向同一地址?"+false);
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
结果:
我的 DNA为0.42787839738935896
我的 DNA为0.42787839738935896
dna指向同一地址?true
---------------------------------------------
dna指向同一地址?false
方式一:
重写Cloneble接口的clone方法, ‘克隆person’ 对象即使修改了Dna中的属性值, ‘原person’ 的Dna与 ‘克隆person’ 的Dna指向同一地址。(浅克隆)
方式二:
将 ‘原person’ 通过写入文件,再通过流读取出 ‘克隆person’ 对象, ‘原person’ 的Dna与 ‘克隆person’ 的Dna指向不同地址。(深克隆)