原型模式指定的是用原型实例指定创建对象的种类,并用拷贝这些原型来创建新的对象。某些对象可以从头创建,而其他对象可以创建为现有对象的复制项并进行修改,但是使用
这些对象的系统或流程不会根据它们的实际创建方式区分它们。在相似的方式下,在使用“原型”模式时,客户系统应独立于它使用的对象的创建、合成和表示等详细信息。
原型适用性:
1.当一个系统应该独立于它的产品创建、构成和表示时。 2.当要实例化的类是在运行时刻指定时,例如,通过动态装载。 3.为了避免创建一个与产品类层次平行的工厂类层次时。 4.当一个类的实例只能有几个不同状态组合中的一种时。 建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。
在java中有浅复制和深复制,浅复制是使用内置java.lang.Object的clone()方法来实现;深复制是覆盖Clone方法来实现。
浅复制:如果是基本数据类型,就会全部复制,若是引用对象则仅仅复制对象的引用,而不复制他所引用的对象。所以改变了其中一个对象的地址,会影响到另一个对象。
package com.yu.jian;
/**
* 被引用的对象
* @author maojycom
*
*/
public class User{
private String userName;
public User() {
super();
}
public User(String userName) {
super();
this.userName = userName;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
package com.yu.jian;
/**
* @author maojycom
*
*/
public class People implements Cloneable{
private String name;
private User user;
public People() {
super();
}
public People(String name) {
this.name = name;
this.user = new User(name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
/**
* 覆盖父类的clone方法
*/
@Override
protected Object clone(){
try {
//浅复制:调用父类的clone方法
return super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
}
package com.yu.jian;
/**
* java浅复制和深复制测试
* @author Administrator
*
*/
public class Test {
public static void main(String[] args) {
People p = new People("www");
//复制一份People出来
People p1 = (People) p.clone();
//false 对象的引用类型不同
System.out.println(p == p1);
//true 对象的class相同
System.out.println(p.getClass() == p1.getClass());
//原始对象改变了name属性
p.setName("ggg");
//复制对象name属性没有改变
System.out.println(p1.getName());
//对people中的引用对象user改变其属性
p.getUser().setUserName("aaa");
//复制对象中的username属性改变了
System.out.println(p1.getUser().getUserName());
}
}
输出:false
true
www
aaa
深复制:把要复制的对象所引用的对象都复制了一遍。是把引用的对象动态分配的内存也一并复制过来,对象和它所引用的对象一起复制。
User类和Test类没有改变,只是改变了People中的clone方法。
package com.yu.jian;
/**
* @author maojycom
*
*/
public class People implements Cloneable{
private String name;
private User user;
public People() {
super();
}
public People(String name) {
this.name = name;
this.user = new User(name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
/**
* 覆盖父类的clone方法
*/
@Override
protected Object clone(){
//深复制:复制该类的一个新对象,使其与原始对象相互独立。
People cloneObj = new People("maojy");
return cloneObj;
}
}
输出:false
true
maojy
maojy
还有序列化复制和延迟复制就不写了,了解就行。
如果复制的对象都是基本类型,就用浅复制;如果复制的对象有引用类型,且对象引用的地址不会经常改变,就用浅复制,若经常需要改变,就用深复制。