原型模式
1.过程相同,但结果不一样。2.数据内容完全一样,但实例不同(比如java中的clone。不走构造方法,直接copy字节码,生成一个新的对象
浅克隆
package com.gupaoedu.vip.prototype.simple;
import java.util.ArrayList;
public class ConcretePrototype implements Cloneable{
private int age;
private String name;
public ArrayList<String> list = new ArrayList<String>();
protected Object clone() throws CloneNotSupportedException {
ConcretePrototype prototype = null;
try{
prototype = (ConcretePrototype)super.clone();
prototype.list = (ArrayList)list.clone();
//克隆基于字节码的
//用反射,或者循环
}catch(Exception e){
}
return prototype;
}
//定义上100个属性
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.gupaoedu.vip.prototype.simple;
import java.util.ArrayList;
import java.util.List;
public class CloneTest {
public static void main(String[] args) {
ConcretePrototype cp = new ConcretePrototype();
cp.setAge(18);
cp.setName("Tom");
//cp.list.add("Tom");
try {
ConcretePrototype copy = (ConcretePrototype)cp.clone();
System.out.println(copy.list == cp.list);
System.out.println(copy.getAge() + "," + copy.getName() + copy.list.size());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
//就是一个现成的对象,这个对象里面有已经设置好的值
//当我要新建一个对象,并且要给新建的对象赋值,而且赋值内容要跟之前的一模一样
//ConcretePrototype cp = new ConcretePrototype();
//cp.setAge(18);
//ConcretePrototype copy = new ConcretePrototype();
//copy.setAge(cp.getAge());
//copy.setName(cp.getName());
//用循环,用反射,确实可以的(反射性能并不高)
//字节码复制newInstance()
//ConcretePrototype copy = cp;
//ORM的时候经常用到的
//能够直接拷贝其实际内容的数据类型/只支持9种,八大基本数据类型+String 浅拷贝
//深拷贝
}
}
深克隆
package com.gupaoedu.vip.prototype.greatestsage;
import java.util.Date;
//猴子
public class Monkey {
//身高
protected int height;//基本
//体重
protected int weight;
//生日
protected Date birthday;//不是基本类型
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
package com.gupaoedu.vip.prototype.greatestsage;
import java.io.Serializable;
/**
* 金箍棒
* @author Tom
*
*/
public class GoldRingedStaff implements Serializable{
private float height = 100; //长度
private float diameter = 10;//直径
/**
* 金箍棒长大
*/
public void grow(){
this.diameter *= 2;
this.height *= 2;
}
/**
* 金箍棒缩小
*/
public void shrink(){
this.diameter /= 2;
this.height /= 2;
}
}
package com.gupaoedu.vip.prototype.greatestsage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;
/**
* 齐天大圣
* @author Tom
*
*/
public class TheGreatestSage extends Monkey implements Cloneable,Serializable{
//金箍棒
private GoldRingedStaff staff;
//从石头缝里蹦出来
public TheGreatestSage(){
this.staff = new GoldRingedStaff();
this.birthday = new Date();
this.height = 150;
this.weight = 30;
System.out.println("------------------------");
}
//分身技能
public Object clone(){
//深度克隆
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try {
//return super.clone();//默认浅克隆,只克隆八大基本数据类型和String
//序列化
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(this);
//反序列化
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
TheGreatestSage copy = (TheGreatestSage)ois.readObject();
copy.birthday = new Date();
return copy;
} catch (Exception e) {
e.printStackTrace();
return null;
}finally{
try {
bos.close();
oos.close();
bis.close();
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//变化
public void change(){
TheGreatestSage copySage = (TheGreatestSage)clone();
System.out.println("大圣本尊生日是:" + this.getBirthday().getTime());
System.out.println("克隆大圣的生日是:" + copySage.getBirthday().getTime());
System.out.println("大圣本尊和克隆大圣是否为同一个对象:" + (this == copySage));
System.out.println("大圣本尊持有的金箍棒跟克隆大圣持有金箍棒是否为同一个对象:" + (this.getStaff() == copySage.getStaff()));
}
public GoldRingedStaff getStaff() {
return staff;
}
public void setStaff(GoldRingedStaff staff) {
this.staff = staff;
}
}
package com.gupaoedu.vip.prototype.greatestsage;
public class TestPrototype {
public static void main(String[] args) {
TheGreatestSage sage = new TheGreatestSage();
sage.change();
//跟《西游记》中描述的一致,怎么办?
}
}