一.原型模式
通过 n e w 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。 \color{red}{通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。} 通过 n e w 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
就是java中的克隆技术,以某个对象为原型,复杂出新的对象。显然,新的对象具备原型对象的特点。
优势: 效率高(直接克隆,避免了重新执行构造过程步骤)。
克隆类似new,但是不同于new。new创建新的对象属性采用的是默认值。克隆出的对象的属性值完全和原型对象相同。并且克隆出的新对象改变不会影响原型对象。然后,再改变克隆对象的值。
原型模式一般很少单独出现,一般是和工厂方法模式一起出现,通过 c l o n e 方法创建一个对象,然后由工厂方法提供给调用者。 \color{red}{原型模式一般很少单独出现,一般是和工厂方法模式一起出现,通过clone方法创建一个对象,然后由工厂方法提供给调用者。} 原型模式一般很少单独出现,一般是和工厂方法模式一起出现,通过 c l o n e 方法创建一个对象,然后由工厂方法提供给调用者。
二.原型模式实现
cloneable接口和clone方法;
利用序列化和反序列化实现深克隆。
三.浅克隆和深克隆
所谓浅克隆、深克隆指的是:克隆对象和原型对象属性对象引用是否同一个,是同一个就是浅克隆,否则就是深克隆。
四.代码展示
public class Sheep implements Cloneable {
private String name;
private Date birthday;
@Override
protected Object clone ( ) throws CloneNotSupportedException {
Object obj= super . clone ( ) ;
return obj;
}
public Sheep ( ) {
}
public Sheep ( String name, Date birthday) {
this . name = name;
this . birthday = birthday;
}
public String getName ( ) {
return name;
}
public Date getBirthday ( ) {
return birthday;
}
public void setName ( String name) {
this . name = name;
}
public void setBirthday ( Date birthday) {
this . birthday = birthday;
}
}
public class App {
public static void main ( String [ ] args) throws CloneNotSupportedException {
Date date= new Date ( 123123123L ) ;
Sheep s1= new Sheep ( "多利" , date) ;
Sheep s2= ( Sheep ) s1. clone ( ) ;
System . out. println ( s1+ "\t" + s1. getName ( ) + "---->" + s1. getBirthday ( ) ) ;
date. setTime ( 321213543123L ) ;
System . out. println ( s1+ "\t" + s1. getName ( ) + "---->" + s1. getBirthday ( ) ) ;
s2. setName ( "多多利" ) ;
System . out. println ( s2+ "\t" + s2. getName ( ) + "---->" + s2. getBirthday ( ) ) ;
}
}
com.reyco.prototype.Sheep@7852e922 多利----> Fri Jan 02 18 :12:03 CST 1970
com.reyco.prototype.Sheep@7852e922 多利----> Fri Mar 07 01:59:03 CST 1980
com.reyco.prototype.Sheep@55f96302 多多利----> Fri Mar 07 01:59:03 CST 1980
浅克隆调用结果:原型对象的引用属性改变后,克隆对象也会跟着改变。
public class Sheep2 implements Cloneable {
private String name;
private Date birthday;
@Override
protected Object clone ( ) throws CloneNotSupportedException {
Object obj= super . clone ( ) ;
Sheep2 s= ( Sheep2 ) obj;
s. birthday= ( Date ) this . birthday. clone ( ) ;
return obj;
}
public Sheep2 ( ) {
}
public Sheep2 ( String name, Date birthday) {
this . name = name;
this . birthday = birthday;
}
public String getName ( ) {
return name;
}
public Date getBirthday ( ) {
return birthday;
}
public void setName ( String name) {
this . name = name;
}
public void setBirthday ( Date birthday) {
this . birthday = birthday;
}
}
public class App2 {
public static void main ( String [ ] args) throws CloneNotSupportedException {
Date date= new Date ( 123123123L ) ;
Sheep2 s= new Sheep2 ( "多利" , date) ;
Sheep2 s2= ( Sheep2 ) s. clone ( ) ;
System . out. println ( s. getName ( ) + "---->" + s. getBirthday ( ) ) ;
date. setTime ( 321213543123L ) ;
System . out. println ( s. getName ( ) + "---->" + s. getBirthday ( ) ) ;
s2. setName ( "多多利" ) ;
System . out. println ( s2. getName ( ) + "---->" + s2. getBirthday ( ) ) ;
}
}
多利---->Fri Jan 02 18:12:03 CST 1970
多利---->Fri Mar 07 01:59:03 CST 1980
多多利---->Fri Jan 02 18:12:03 CST 1970
深克隆调用结果:原型对象的引用属性改变后,克隆对象不会跟着改变。
五.序列化和反序列化实现深克隆
public class Sheep implements Serializable {
private String name;
private Date birthday;
public Sheep ( ) {
}
public Sheep ( String name, Date birthday) {
this . name = name;
this . birthday = birthday;
}
public String getName ( ) {
return name;
}
public Date getBirthday ( ) {
return birthday;
}
public void setName ( String name) {
this . name = name;
}
public void setBirthday ( Date birthday) {
this . birthday = birthday;
}
}
public static void main ( String [ ] args) throws Exception {
Date date= new Date ( 123123123L ) ;
Sheep s= new Sheep ( "多利" , date) ;
System . out. println ( s. getName ( ) + "---->" + s. getBirthday ( ) ) ;
ByteArrayOutputStream bos= new ByteArrayOutputStream ( ) ;
ObjectOutputStream oos= new ObjectOutputStream ( bos) ;
oos. writeObject ( s) ;
byte [ ] bytes = bos. toByteArray ( ) ;
ByteArrayInputStream bis= new ByteArrayInputStream ( bytes) ;
ObjectInputStream ois= new ObjectInputStream ( bis) ;
Sheep s2= ( Sheep ) ois. readObject ( ) ;
date. setTime ( 321213543123L ) ;
System . out. println ( s. getName ( ) + "---->" + s. getBirthday ( ) ) ;
s2. setName ( "多多利" ) ;
System . out. println ( s2. getName ( ) + "---->" + s2. getBirthday ( ) ) ;
}