菜鸟教程
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用
大话设计模式
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
《Android源码设计模式解析与实践》
最大的特点是:implements Cloneable;但凡实现Cloneable接口的一般都满足原型模式。当然也不排除有其他变种情况,不过目前没有碰到。如果有请留言分享,或者后期我碰到后再补充。
注意事项:
与通过对一个类进行实例化来构造新对象不同的是,原型模式是通过拷贝一个现有对象生成新对象的。浅拷贝实现 Cloneable,重写,深拷贝是通过实现 Serializable 读取二进制流。
使用场景- 简历模板
- 历史文档修改记录(比如:飞书、腾讯等在线编辑文档)
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。
深拷贝把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象
Glide原型模式应用包路径:com.bumptech.glide.TransitionOptions
/**
* A base class for setting a transition to use on a resource when a load completes.
*
* @param The implementation of this class to return to chain methods.
* @param The type of resource that will be animated.
*/
public abstract class TransitionOptions
implements Cloneable {
private TransitionFactory transitionFactory = NoTransition.getFactory();
/**
* Removes any existing animation put on the builder. Will be overridden by subsequent calls that
* put an animation.
*
* @return This request builder.
*/
@NonNull
public final CHILD dontTransition() {
return transition(NoTransition.getFactory());
}
/**
* Sets an {@link android.view.animation.Animation} to run on the wrapped target when an resource
* load finishes. Will only be run if the resource was loaded asynchronously (i.e. was not in the
* memory cache).
*
* @param viewAnimationId The resource id of the {@link android.view.animation} to use as the
* transition.
* @return This request builder.
*/
@NonNull
public final CHILD transition(int viewAnimationId) {
return transition(new ViewAnimationFactory(viewAnimationId));
}
/**
* Sets an animator to run a {@link android.view.ViewPropertyAnimator} on a view that the target
* may be wrapping when a resource load finishes. Will only be run if the load was loaded
* asynchronously (i.e. was not in the memory cache).
*
* @param animator The {@link com.bumptech.glide.request.transition.ViewPropertyTransition
* .Animator} to run.
* @return This request builder.
*/
@NonNull
public final CHILD transition(@NonNull ViewPropertyTransition.Animator animator) {
return transition(new ViewPropertyAnimationFactory(animator));
}
/**
* Uses the given {@link TransitionFactory} to build a {@link
* com.bumptech.glide.request.transition.Transition} for each request started with these {@code
* TransitionOptions}.
*
* @return This request builder.
*/
@NonNull
public final CHILD transition(
@NonNull TransitionFactory transitionFactory) {
this.transitionFactory = Preconditions.checkNotNull(transitionFactory);
return self();
}
@SuppressWarnings({
// cast to CHILD is safe given the generic argument represents the object's runtime class
"unchecked",
// CHILD is the correct class name.
"PMD.CloneMethodReturnTypeMustMatchClassName",
// we don't want to throw to be user friendly
"PMD.CloneThrowsCloneNotSupportedException"
})
@Override
public final CHILD clone() {
try {
return (CHILD) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
final TransitionFactory getTransitionFactory() {
return transitionFactory;
}
@SuppressWarnings("unchecked")
private CHILD self() {
return (CHILD) this;
}
}
被RequestBuilder调用,同时RequestBuilder也是原型模式,两者结合正好说明浅拷贝和深拷贝。TransitionOptions属于浅拷贝那种 RequestBuilder调用了TransitionOptions的clone()属于深拷贝那种。当然深浅拷贝取舍也是根据实际业务场景设定的。
/**
* A generic class that can handle setting options and staring loads for generic resource types.
*
* @param The type of resource that will be delivered to the {@link
* com.bumptech.glide.request.target.Target}.
*/
// Public API.
@SuppressWarnings({"unused", "WeakerAccess"})
public class RequestBuilder extends BaseRequestOptions
implements Cloneable, ModelTypes {
。。。
@NonNull
@SuppressWarnings("unchecked")
private TransitionOptions transitionOptions;
/**
* Returns a copy of this request builder with all of the options put so far on this builder.
*
* This method returns a "deep" copy in that all non-immutable arguments are copied such that
* changes to one builder will not affect the other builder. However, in addition to immutable
* arguments, the current model is not copied so changes to the model will affect both builders.
*/
@SuppressWarnings({
// we don't want to throw to be user friendly
"PMD.CloneThrowsCloneNotSupportedException"
})
@CheckResult
@Override
public RequestBuilder clone() {
RequestBuilder result = super.clone();
result.transitionOptions = result.transitionOptions.clone();
if (result.requestListeners != null) {
result.requestListeners = new ArrayList(result.requestListeners);
}
if (result.thumbnailBuilder != null) {
result.thumbnailBuilder = result.thumbnailBuilder.clone();
}
if (result.errorBuilder != null) {
result.errorBuilder = result.errorBuilder.clone();
}
return result;
}
再补充一个BaseRequestOptions
/**
* A base object to allow method sharing between {@link RequestOptions} and {@link
* com.bumptech.glide.RequestBuilder}.
*
* This class is not meant for general use and may change at any time.
*
* @param The particular child implementation
*/
@SuppressWarnings({"PMD.UseUtilityClass", "unused"})
public abstract class BaseRequestOptions implements Cloneable {
private static final int UNSET = -1;
private static final int SIZE_MULTIPLIER = 1
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?