三角色
- 客户: 提出创建对象请求
- 抽象原型:是一个抽象角色,由一个抽象接口或抽象类实现,给出所有的具体原型类所需要的接口。
- 具体原型:该角色是被复制的对象,必须实现抽象原型接口
克隆:
-
实现Cloneable接口
-
覆盖object的clone方法
浅克隆 Shollow Clone
public Object clone() {
Object clone = null;
try {
clone = super.clone(); //可能涉及的强制类型转换
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone; //可以return 0;
}
main(){
Obj b = (Obj)a.clone();
}
深克隆
当开发人员自定义赋值构造函数时,会涉及
当类中包含有一些对象时,对对象中的非基本类型的属性调用clone() 方法 完成深复制
实现
package 原型模式;
import java.util.Date;
public class Student implements Cloneable{
String nameString;
public Date date ;
public Student(String name){
this.nameString = name;
this.date = new Date();
}
public Date getDate(){
return date;
}
public Student clone() {
Student clone = null;
try {
clone = (Student) super.clone(); //可能涉及的强制类型转换
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}//实现深复制
clone.date = (Date) this.date.clone();
return clone;
}
public void setname(String name){
nameString = name;
}
public String toString(){
return nameString+date.toString();
}
}
package 原型模式;
public class ShenClone {
public static void main(String []args){
Student s1 = new Student("强月城");
System.out.println(s1.toString());
Student s2 = s1.clone();
System.out.println(s2.toString());
s2.setname("qyc");
System.out.println(s2.toString());
System.out.println(s1.toString());
}
}
强月城Sun Jun 23 19:57:56 CST 2019
强月城Sun Jun 23 19:57:56 CST 2019
qycSun Jun 23 19:57:56 CST 2019
强月城Sun Jun 23 19:57:56 CST 2019
浅克隆与深克隆的区别
浅复制仅仅复制所考虑的对象,不复制所引用的对象
深复制那些引用其他对象的变量将指向被复制的新对象,而不是用来的那些被引用的对象,深复制把复制的对象所引用的对象都复制了一遍
对比
克隆
package com.qyc.创建型模式.Prototype.prototype;
import java.util.Date;
public class XiaoBing implements NPC, Cloneable {
private String names;
private Date date;
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getNames() {
return names;
}
public void setNames(String names) {
this.names = names;
}
@Override
public void show() {
// TODO 自动生成的方法存根
// System.out.println(date+"--"+System.identityHashCode(date)+"--我是小兵!"+names+"-野怪-"+yeGuai.getName());
}
public XiaoBing clone() throws CloneNotSupportedException {
XiaoBing xiaobing = null;
xiaobing = (XiaoBing) super.clone();
// TODO 自动生成的 catch 块date = (Date) this.date.clone();
return xiaobing;
}
}
正常
package com.qyc.创建型模式.Prototype.prototype;
import java.util.Date;
public class YeGuai implements NPC{
private String names;
private Date date;
public YeGuai(String names, Date date) {
super();
this.names = names;
this.date = date;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getNames() {
return names;
}
public void setNames(String names) {
this.names = names;
}
@Override
public void show() {
// TODO 自动生成的方法存根
}
}
测试
package com.qyc.创建型模式.Prototype;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.qyc.创建型模式.Prototype.prototype.NPC;
import com.qyc.创建型模式.Prototype.prototype.XiaoBing;
import com.qyc.创建型模式.Prototype.prototype.YeGuai;
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
// XiaoBing x = new XiaoBing();
// x.setNames("法拉利");
// x.setDate(new Date());
List<YeGuai> y = new ArrayList<>();
long star = System.currentTimeMillis();
for(int i = 0;i<10000000;i++){
y.add(new YeGuai("测试", new Date()));
}
long end = System.currentTimeMillis();
System.out.println(end-star);
System.out.println(5677/2784);
}
}
仅代表个人:我测试的是生成一千万个对象, 克隆需要2.7秒,new需要5.6秒,在对象多的情况下会有将近一倍的效率差,所以克隆还是很棒的!!