Android SDK源码中很多地方都用到了原型模式
Intent
Intent是Android四大组件之间的桥梁,Intent和原型模式有关的源码如下:
public class Intent implements Parcelable, Cloneable {
// ……代码省略……
/**
* Copy constructor.
*/
public Intent(Intent o) {
this(o, COPY_MODE_ALL);
}
private Intent(Intent o, @CopyMode int copyMode) {
this.mAction = o.mAction;
this.mData = o.mData;
this.mType = o.mType;
this.mIdentifier = o.mIdentifier;
this.mPackage = o.mPackage;
this.mComponent = o.mComponent;
this.mOriginalIntent = o.mOriginalIntent;
// ……代码省略……
}
@Override
public Object clone() {
return new Intent(this);
}
// ……代码省略……
}
可见Intent实现了Cloneable接口,也重写了clone()方法,但和我们平时使用的 clone() 方法的方式不一样,Intent 类并没有调用 super.clone() ,而是专门写了一个构造函数用来拷贝对象,使用 clone() 或直接new 需要根据构造函数的成本来决定,如果对象的构造成本比较高或者构造较为麻烦,那么使用 clone 函数效率较高,否则可以直接使用 new 的形式。
Bundle
Bundle主要用于在Activity之间传输数据,它保存的数据,是以key-value的形式存储的。Bundle与原型模式相关的代码如下:
public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
// ……代码省略……
/**
* Clones the current Bundle. The internal map is cloned, but the keys and
* values to which it refers are copied by reference.
*/
@Override
public Object clone() {
return new Bundle(this);
}
// ……代码省略……
}
可见Bundle实现原型模式的原理与Intent类似,不做过多解释。
Shape及其子类
Shape类源码如下:
/**
* Defines a generic graphical "shape."
* <p>
* Any Shape can be drawn to a Canvas with its own draw() method, but more
* graphical control is available if you instead pass it to a
* {@link android.graphics.drawable.ShapeDrawable}.
* <p>
* Custom Shape classes must implement {@link #clone()} and return an instance
* of the custom Shape class.
*/
public abstract class Shape implements Cloneable {
// ……代码省略……
@Override
public Shape clone() throws CloneNotSupportedException {
return (Shape) super.clone();
}
// ……代码省略……
}
注意注释写的是Shape的每个子类必须重写clone()方法,返回具体子类的一个实例。Shape类的子类RectShape类源码如下:
public class RectShape extends Shape {
// ……代码省略……
@Override
public RectShape clone() throws CloneNotSupportedException {
final RectShape shape = (RectShape) super.clone();
shape.mRect = new RectF(mRect);
return shape;
}
// ……代码省略……
}
可见RectShape的clone()方法返回的是RectShape实例。
Animation
Animation类与原型模式有关的源码如下:
与Shape类不同的是,Animation类的子类都没有实现Cloneable接口,也都没有重写clone()方法。
SparseArray
SparseArray是Android中特有的数据结构,小巧却精悍,其中与原型模式有关的代码如下:
public class SparseArray<E> implements Cloneable {
private int[] mKeys;
private Object[] mValues;
// ……代码省略……
@Override
@SuppressWarnings("unchecked")
public SparseArray<E> clone() {
SparseArray<E> clone = null;
try {
clone = (SparseArray<E>) super.clone();
clone.mKeys = mKeys.clone();
clone.mValues = mValues.clone();
} catch (CloneNotSupportedException cnse) {
/* ignore */
}
return clone;
}
// ……代码省略……
}
可见clone()方法里边,两个数组mKeys和mValues也分别调用了clone()方法,这是一种最基础的深拷贝。为什么说是最基础的深拷贝呢?因为仅仅两个Array实现了深拷贝,而Array中的元素并没有实现。