原型模式类似克隆技术,通过以某个对象为原型,复制出新对象。克隆出的对象属性和原型对象相同。但克隆出的新对象不会改变原来对象。
优势:对象某些创建对象代价高可以使用该模式,效率高。
实现:java语言直接支持原型模式,因为所有java对象继承自Object, 里面由一个clone()方法,可以将一个对象复制一份。但要使该对象支持复制
需要实现一个接口Cloneable。如果直接调用clone方法不实现接口编译器会抛出CloneNotSupoortedException异常。
简单说明下java对象的复制:
1.java语言提供 的Cloneable接口,只是起到在运行时期告诉jvm可以在该类上使用clone()方法。通过该方法得到一个对象的复制。
2.Object类本身不实现Cloneable接口。所以需要复制的类没有实现该接口会抛异常。
/**
*测试克隆
**/
public class TestClone implements Cloneable { private Integer age; private String name; public TestClone(Integer age, String name) { this.age = age; this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override protected Object clone() throws CloneNotSupportExcetion{ return (TestClone)super.clone(); } @Override public String toString() { return "TestClone{" + "age=" + age + ", name=‘" + name + ‘\‘‘ + ‘}‘; } public static void main(String[] args) { TestClone temp1 = new TestClone(1, "tom"); TestClone temp2 = (TestClone) temp1.clone(); System.out.println("temp1: "+ temp1);//temp1: TestClone{age=1, name=‘tom‘} System.out.println("temp2: "+ temp2);//temp2: TestClone{age=1, name=‘tom‘} System.out.println(temp1 == temp2); //false } }
结果上,克隆对象和原对象性质一样。但不是同一个对象。这里体现的是浅克隆。深克隆和它区别是,克隆后的对象引用是另一个对象。
这个例子深克隆和浅克隆表现一直,是因为属性是基本类型,以及string类型。
关于深克隆和浅克隆这里就不扩展了。
回到模式上:原型模式主要两种,这两种本质上其实是一致。只是表现新式不一样。
1. 简单形式:和例子中一样的方式。
2. 登记形式:将简单新式跟进一步抽象化。增加对需要创建的原型对象管理类。
/**
* 抽象原型角色
*/
public interface Prototype extends Cloneable{
public Object clone();
}
/**
* 具体原型角色实现抽象原型角色的接口,也就是clone()方法
*/
public class ConcretePrototype implements Prototype {
@Override
public Object clone() {
try {
return (Prototype)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
}
/**
* 原型管理器,管理所有原型对象,并提供对外界添加原型对象和获取原型对象
*/
public class PrototypeManager {
private List<Prototype> objects = new ArrayList<>();
/**
* 增加一个对象
* @param obj
*/
public void add(Prototype obj){
objects.add(obj);
}
/**
* 获取一个对象
*/
public Prototype get(int id){
return objects.get(id);
}
}
public class Client {
public static void main(String[] args) {
PrototypeManager mgr = new PrototypeManager();
Prototype prototype = new ConcretePrototype();
Prototype copyPrototype = (Prototype) prototype.clone();
mgr.add(copyPrototype);
copyPrototype = mgr.get(0);
}
}
两种形式各有长短处。如果需要创建的原型对象数目少就可以直接简单新式。如果要创建的原型对象数目多不固定,
则建议以登记形式管理原型对象。
原文:https://www.cnblogs.com/gcm688/p/10163887.html