1.原型模式的定義及使用場景
定義:
用原型實(shí)例指定創(chuàng)建對象的種類嚣崭,并通過拷貝這些原型創(chuàng)建新的對象
使用場景:
類初始化需要消耗非常多的資源笨触,這個資源包括數(shù)據(jù)、硬件資源等雹舀,通過原型拷貝避免這些消耗
通過new產(chǎn)生一個對象需要非常繁瑣的數(shù)據(jù)準(zhǔn)備或訪問權(quán)限芦劣,這時(shí)可以使用原型模式
一個對象需要提供給其他對象訪問,而且各個調(diào)用者可能都需要修改其值時(shí)说榆,可以考慮使用原型模式拷貝多個對象供調(diào)用者使用虚吟,即保護(hù)性拷貝
2.原型模式的優(yōu)缺點(diǎn)
2.1優(yōu)點(diǎn)
性能優(yōu)良原型模式是在內(nèi)存二進(jìn)制流的拷貝,要比直接new一個對象性能好签财,特別是要在一個循環(huán)體內(nèi)產(chǎn)生大量的對象時(shí)串慰,原型模式可以更好地體現(xiàn)其優(yōu)點(diǎn)
2.2缺點(diǎn)
逃避構(gòu)造函數(shù)的約束這既是他的優(yōu)點(diǎn)也是缺點(diǎn),直接在內(nèi)存中拷貝唱蒸,構(gòu)造函數(shù)不會執(zhí)行邦鲫。需要在實(shí)際應(yīng)用時(shí)考慮
3.注意實(shí)現(xiàn)
構(gòu)造函數(shù)默認(rèn)不執(zhí)行
淺拷貝及深拷貝
Object類提供的方法clone只是拷貝本對象,其對象內(nèi)部的數(shù)組神汹、引用對象等都不拷貝庆捺,還是指向原型對象的內(nèi)部元素地址,這種拷貝為淺拷貝屁魏。如需要深拷貝疼燥,對應(yīng)的成員也需指向clone方法
要使用clone方法,類的成員變量上不要增加final關(guān)鍵字
4.原型模式的實(shí)現(xiàn)方式
ProtoType:
public class ProtoType implements Cloneable {
public ProtoType() {
System.out.println("ProtoType is excute...");
}
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
protected ProtoType clone() {
ProtoType protoType = null;
try {
protoType = (ProtoType) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return protoType;
}
@Override
public String toString() {
return "ProtoType{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}```
Text:
public class Test {
public static void main(String args[]) {
ProtoType type = new ProtoType();
type.setId(1);
type.setName("張三");
System.out.println(type);
ProtoType clone = type.clone();
clone.setId(2);
clone.setName("李四");
System.out.println(clone);
}
}```
Objec的clone源碼:
/**
* Creates and returns a copy of this {@code Object}. The default
* implementation returns a so-called "shallow" copy: It creates a new
* instance of the same class and then copies the field values (including
* object references) from this instance to the new instance. A "deep" copy,
* in contrast, would also recursively clone nested objects. A subclass that
* needs to implement this kind of cloning should call {@code super.clone()}
* to create the new instance and then create deep copies of the nested,
* mutable objects.
*
* @return a copy of this object.
* @throws CloneNotSupportedException
* if this object's class does not implement the {@code
* Cloneable} interface.
*/
protected Object clone() throws CloneNotSupportedException {
if (!(this instanceof Cloneable)) {
throw new CloneNotSupportedException("Class " + getClass().getName() +
" doesn't implement Cloneable");
}
return internalClone();
}
/*
* Native helper method for cloning.
*/
private native Object internalClone();```
可見執(zhí)行了一個native方法執(zhí)行二進(jìn)制流的拷貝
**5.原型模式在Android中的實(shí)際應(yīng)用**
Intent:
@Override
public Object clone() {
return new Intent(this);
}
/**
- Copy constructor.
*/
public Intent(Intent o) {
this.mAction = o.mAction;
this.mData = o.mData;
this.mType = o.mType;
this.mPackage = o.mPackage;
this.mComponent = o.mComponent;
this.mFlags = o.mFlags;
this.mContentUserHint = o.mContentUserHint;
if (o.mCategories != null) {
this.mCategories = new ArraySet<String>(o.mCategories);
}
if (o.mExtras != null) {
this.mExtras = new Bundle(o.mExtras);
}
if (o.mSourceBounds != null) {
this.mSourceBounds = new Rect(o.mSourceBounds);
}
if (o.mSelector != null) {
this.mSelector = new Intent(o.mSelector);
}
if (o.mClipData != null) {
this.mClipData = new ClipData(o.mClipData);
}
}```
出處:http://huangjunbin.com/page/2/