版权声明:本文为博主原创,未经博主允许不得转载。 https://blog.csdn.net/weixin_36904568/article/details/90137252
1. 定义
用一个原型对象指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象。
2. 使用
(1)简单形式
- 抽象原型
- 具体原型:被复制的对象
- 客户:提出创建对象的请求(明确对象个数)
package PrototypePattern;
/**
* 抽象接口
*/
public interface Prototype {
public Object clone();
}
package PrototypePattern;
/**
* 具体实例
*/
public class PrototypeA implements Prototype {
@Override
public Object clone() {
return new PrototypeA();
}
}
package PrototypePattern;
public class Test {
private Prototype prototype;
public Test(Prototype prototype){
this.prototype = prototype;
}
public Prototype clone(){
return (Prototype) prototype.clone();
}
public static void main(String[] args) {
Prototype prototype = new PrototypeA();
Test test = new Test(prototype);
System.out.println(test.clone());
}
}
(2)登记形式
- 抽象原型
- 具体原型:被复制的对象
- 客户:提出创建对象的请求(不确定对象个数)
- 原型管理器:创建具体原型类的对象并记录
package PrototypePattern.RegisterPrototype;
/**
* 抽象接口
*/
public interface Prototype {
public Object clone();
public void setName(String name);
public String getName();
}
package PrototypePattern.RegisterPrototype;
/**
* 具体实例
*/
public class PrototypeA implements Prototype {
private String name;
@Override
public Object clone() {
return new PrototypeA();
}
@Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "PrototypeA{" +
"name='" + name + '\'' +
'}';
}
}
package PrototypePattern.RegisterPrototype;
/**
* 具体实例
*/
public class PrototypeB implements Prototype {
private String name;
@Override
public Object clone() {
return new PrototypeB();
}
@Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "PrototypeB{" +
"name='" + name + '\'' +
'}';
}
}
package PrototypePattern.RegisterPrototype;
import java.util.HashMap;
import java.util.Map;
/**
* 原型管理者
*/
public class PrototypeRegistry {
private Map<String,Prototype> map;
public PrototypeRegistry(){
map = new HashMap<>();
}
public void add(String id,Prototype prototype){
map.put(id,prototype);
}
public void remove(String id){
map.remove(id);
}
public Prototype getPrototype(String id){
Prototype prototype = map.get(id);
if (prototype != null)
return (Prototype) prototype.clone();
return null;
}
}
package PrototypePattern.RegisterPrototype;
public class Test {
public static void main(String[] args) {
PrototypeRegistry registry = new PrototypeRegistry();
//创建原型
Prototype a = new PrototypeA();
Prototype b = new PrototypeB();
registry.add("a",a);
registry.add("b",b);
//获取原型的复制
Prototype c = registry.getPrototype("a");
c.setName("我是a的复制");
System.out.println(c);
//获取原型的复制
Prototype d = registry.getPrototype("b");
d.setName("我是b的复制");
System.out.println(d);
Prototype e = registry.getPrototype("c");
System.out.println(e);
}
}
3. 特点
- 隐藏创建对象的复杂性
- 允许在运行时动态改变具体的实现类型
- 每一个类都必须配备一个克隆方法
4. JAVA的克隆
(1)条件
- 克隆对象与原对象不是同一个对象。
- 克隆对象与原对象的类型相同
- 如果对象x的equals()方法定义其恰当的话,那么x.clone().equals(x)应当成立
(2)分类
浅度克隆
只负责克隆按值传递的数据(基本数据类型、String类型),而不复制它所引用的对象
实现:Java语言的所有类都会继承一个clone()方法
深度克隆
除了浅度克隆要克隆的值外,还负责克隆引用类型的数据。其他被引用的对象的变量将指向被复制过的新对象
实现:利用序列化实现深度克隆。
- 先使对象实现Serializable接口
- 将对象序列化
- 将对象反序列化
public Object deepClone() throws IOException, ClassNotFoundException{
//将对象写到流里
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
//从流里读回来
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}