模式概述:
使你能够复制已有对象, 而又无需使代码依赖它们所属的类。
使用场景:
1.如果你需要复制一些对象, 同时又希望代码独立于这些对象所属的具体类, 可以使用原型模式。
2.如果子类的区别仅在于其对象的初始化方式, 那么你可以使用该模式来减少子类的数量。 别人创建这些子类的目的可能是为了创建特定类型的对象。
代码样例:
/**
* 用户
*/
public class UserInfo implements Cloneable{
public String name;
public int age;
public Location location;
public UserInfo(String name, int age, Location location) {
this.name = name;
this.age = age;
this.location = location;
}
@Override
public String toString() {
return "UserInfo{" +
"name='" + name + '\'' +
", age=" + age +
", location=" + location +
'}';
}
/**
* 重写clone方法
*/
@Override
public UserInfo clone() throws CloneNotSupportedException {
UserInfo userInfo = (UserInfo) super.clone();
userInfo.location=this.location.clone();//对应的引用类型也需要clone下,实现深拷贝
return userInfo;
}
}
/**
* 用户地址
*/
public class Location implements Cloneable{
public String street;
public int roomNo;
public Location(String street, int roomNo) {
this.street = street;
this.roomNo = roomNo;
}
@Override
public String toString() {
return "Location{" +
"street='" + street + '\'' +
", roomNo=" + roomNo +
'}';
}
/**
* 重写clone方法
* 作为userinfo的属性,location为引用数据类型;为实现深拷贝,location同样需要重写clone方法
*/
@Override
public Location clone() throws CloneNotSupportedException {
return (Location) super.clone();
}
}
public class TestPrototype {
public static void main(String[] args) throws Exception{
UserInfo userInfo = new UserInfo("张三",19,new Location("北京路",22));
UserInfo userInfoCopy = userInfo.clone();
System.out.println(userInfo.toString());
System.out.println(userInfoCopy.toString());
/**
* 浅拷贝时,在被拷贝者和所有拷贝者中任意一个location更新,所有useinfo的location都同步变更
* 深拷贝时,拷贝出来的对象相当于时new的,不会相等
*/
System.out.println(userInfoCopy.location == userInfo.location);//浅拷贝为true,深拷贝为false
userInfoCopy.location.street = "上海";
System.out.println(userInfo.toString());
System.out.println(userInfoCopy.toString());
}
}
注意事项: java中实现原型有两步,第一是类实现Cloneable接口,第二是重写clone方法;其中注意类中如果有引用类型的话,对应的引用类型也需要重写clone方法以此来是实现深拷贝。原型模式拷贝的对象都应是深拷贝。