原型模式(Prototype Pattern)
是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。
题目
现在有一个房子,房子里面有条狗,要将房子和狗一起克隆
类图
house类
package PrototypePattern;
//实现了Cloneable接口的抽象类
public class House implements Cloneable {
private String dog;
// private String house;
public String getDog() {
return dog;
}
public void setDog(String dog) {
this.dog = dog;
}
// public String getHouse() {
// return house;
// }
//
// public void setHouse(String house) {
// this.house = house;
// }
@Override
public String toString() {
return "House [dog=" + dog + "]";
}
public House showclone(){
try {
return (House) super.clone();
} catch (CloneNotSupportedException e) {
// TODO: handle exception
e.printStackTrace();
}
return null;
}
}
Test测试类
package PrototypePattern;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建狗和房子对象
House house = new House();
house.setDog("狗");
// house.setHouse("大房子");
//克隆
House house2 = house.showclone();
System.out.println("原来的"+house);
System.out.println("克隆"+house2);
}
}
运行结果:
但是上面的深克隆写法是错误的
我真的是****了,最近比较忙,上课做别的事情去了没有听,结果网上查了别人的资料,后面就是翻车,老师说做错了。
后面我又翻书,问了下别人,最后修改了。
正确的深克隆
House类
//创建实现了Cloneable接口的抽象类
/*
深克隆浅克隆区别:
浅克隆只是将变量和变量名复制了一份,还是引用的同一个对象。
深克隆是分别引用的不同的对象。
所以深克隆是要写入磁盘在取出来的,网上那些人只是写了一个接口而没有实现,所以还是算是浅克隆,大家最后对比一下就可以了。
* */
package PrototypePattern3;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
//创建实现了Cloneable接口的抽象类
/*
深克隆浅克隆区别:
浅克隆只是将变量和变量名复制了一份,还是引用的同一个对象。
深克隆是分别引用的不同的对象。
* */
public class House implements Cloneable,Serializable {
private String houseName;
private String dogAge;
private String dogName;
public String getHouseName() {
return houseName;
}
public void setHouseName(String houseName) {
this.houseName = houseName;
}
public String getDog() {
return dogAge;
}
public void setDogAge(String dogAge) {
this.dogAge = dogAge;
}
public String getDogName() {
return dogName;
}
public void setDogName(String dogName) {
this.dogName = dogName;
}
@Override
public String toString() {
return "House [dogAge=" + dogAge + ", dogName=" + dogName + ", houseName="
+ houseName + "]";
}
//浅克隆
public House shallowclone(){
try {
return (House) super.clone();
} catch (CloneNotSupportedException e) {
// TODO: handle exception
e.printStackTrace();
}
return null;
}
/*深克隆(错误的写法)
public House deepClone(){
try {
House house = (House) super.clone();
return house;
} catch (CloneNotSupportedException e) {
// TODO: handle exception
e.printStackTrace();
}
return null;
}
*/
//深克隆
public House deepColne(){
try {
//将对象写入流中
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(this);
//将对象从流中取出
ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
return (House) objectInputStream.readObject();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
return null;
}
}
}
Test测试类
package PrototypePattern3;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建对象
House house1 = new House();
//初始化对象
house1.setDogName("大狗");
house1.setHouseName("大房子");
house1.setDogAge("5");
//house2浅克隆
House houseShallow = house1.shallowclone();
System.out.println("原型"+house1);
System.out.println("浅克隆"+houseShallow);
//比较
System.out.println("狗的房子是否相同?"+(houseShallow == house1));
System.out.println("狗是否相同?"+(houseShallow.getDog() == house1.getDog()));
//深克隆
House houseDeep = house1.deepColne();
System.out.println("深克隆"+houseDeep);
System.out.println("狗的房子是否相同?"+(houseShallow == houseDeep));
System.out.println("狗是否相同?"+(houseShallow.getDog() == houseDeep.getDog()));
}
}
结果