原型模式(Prototype):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。说白了,就是从利用一个存在的对象再创建另外一个对象,而且不需要知道任何创建的细节。
- 1.首先创建一个原型类
package com.zcbl.client.zcblsdk.prototypemode;
/**
* Created by serenitynanian on 2018/2/11.
* 原型抽象类
* 在java中要实现克隆操作,继承Cloneable,重写clone
*/
public abstract class Prototype implements Cloneable{
private String id ;
protected String type ;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
/**
* 创建当前对象的浅表副本。
* 该方法是创建一个新对象,然后将当前对象的非静态字段复制到该对象。
* 如果该字段是值类型,则对该字段执行逐位复制--也就是直接拷贝一份。
* 如果该字段是引用类型,则复制引用但不复制引用的对象(C语言中也就是复制指针的地址,还是指向同一内存区域);因此,原始对象及其副本引用同一对象
* @return
*/
public Object clone(){
Object obj = null ;
try {
obj = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return obj;
}
/**
* 深拷贝
* @param concretePrototype1
* @return
*/
public Object deepClone(ConcretePrototype1 concretePrototype1){
ConcretePrototype1 copy = new ConcretePrototype1();
copy.type = concretePrototype1.type;
return copy ;
}
abstract void say();
}
- 2.具体的原型实现类
package com.zcbl.client.zcblsdk.prototypemode;
/**
* Created by serenitynanian on 2018/2/11.
*/
public class ConcretePrototype1 extends Prototype {
public ConcretePrototype1() {
type = "ConcretePrototype1";
}
@Override
void say() {
System.out.println("------------ConcretePrototype1---------->"+type);
}
}
- 3.客户端创建相同的原型如下:
package com.zcbl.client.zcblsdk.prototypemode;
/**
* Created by serenitynanian on 2018/2/11.
*/
public class PrototypeClientTest {
public static void main(String[] args){
ConcretePrototype1 p1 = new ConcretePrototype1();
p1.type = "ConcretePrototype1-----p1";
ConcretePrototype1 p2 = (ConcretePrototype1) p1.clone();
p2.type = "ConcretePrototype1-----p2";
p1.say();
p2.say();
/**
* 打印结果如下:
* ------------ConcretePrototype1---------->ConcretePrototype1-----p1
* ------------ConcretePrototype1---------->ConcretePrototype1-----p2
*/
}
}
注意:上面的拷贝是:字段是值类型的拷贝,如果是引用类型,则复制的是引用(C语言中:指针)而不是复制引用的对象。
一般在初始化信息不发生变化的情况下,克隆是最好的方法。这既隐藏了创建对象的细节,又对性能大大提高了--不用重新初始化对象,而是动态的获取对象运行时的状态。
说到复制,就有‘浅复制’ 和 ‘深复制’区别?
- ‘浅复制’:被复制对象的所有变量都含有与原来对象相同的值,而所有的其他对象的引用仍指向原来的对象;也就是说,如果被复制的对象中的变量都是值类型,那么将原来对象的变量复制到一个新的对象上返回;如果被复制的是引用类型,那么指向的是同一个对象。
- ‘深复制’:把引用对象的变量指向复制过来(或者新创建)的新对象,而不是原有的被引用的对象。