0
点赞
收藏
分享

微信扫一扫

【设计模式】原型模式——Android SDK源码中的原型模式

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中的元素并没有实现。



举报

相关推荐

0 条评论