android中的原型模式,Android中的原型模式

8388ebb363ba

设计模式.png

定义

原型的是一种创建型的设计模式,主用来创建的复杂的对象和构建耗时的实例。通过克隆已有的对象来创建的新的对象,从而节省时间和内存。通过克隆一个已经存在的实例可以使我们的程序运行的更高效。

8388ebb363ba

原型模式UML.jpg

使用场景

(1)类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等,通过原型拷贝避免这些消耗。

(2)通过new产生的一个对象需要非常繁琐的数据准备或者权限,这时可以使用原型模式。

(3)一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用,即保护性拷贝。

如何实现

首先我们得实现Cloneable接口,复写clone方法

implements Cloneable

@Override

protected User clone() {

User user = null;

try{

user = (User)super.clone();

} catch (CloneNotSupportedException e){

e.printStackTrace();

}

return user;

}

我们需要注意,clone这个方法不是Cloneable接口中的,我们来看Cloneable的定义,是一个空的接口。

* @author unascribed

* @see java.lang.CloneNotSupportedException

* @see java.lang.Object#clone()

* @since JDK1.0

*/

public interface Cloneable {

}

那么clone是哪来的呢,其实clone是Object中的方法,Cloneable是一个标识接口,它表明这个类的对象是可以拷贝的。如果没有实现Cloneable接口却调用了clone()函数将抛出异常。

浅拷贝和深拷贝

那么在实现clone方法的时候,需要注意个问题,像上面那样,直接调用

user = (User)super.clone();

这样只是简单的拷贝了对象,实际上并不是将原始文档的所有字段都重新构造了一份,而是副本文档的字段引用原始文档的字段。我们需要自己赋值其成员变量,尤其当成员变量为引用型对象时,边涉及到了浅拷贝和深拷贝的问题。

8388ebb363ba

拷贝.png

那么什么是深拷贝呢,如何做? 其实就是拷贝时,我们的引用对象也得拷贝,更有甚者,比如Android中的Intent的深拷贝直接是new一个。

那我们来看一下深拷贝的demo代码:

@Override

public WordDocument clone() {

try {

WordDocument doc = (WordDocument) super.clone();

doc.mText = this.mText;

doc.mImages = (ArrayList) this.mImages.clone();

return doc;

} catch (CloneNotSupportedException e) {

}

return null;

}

应用

那么原型模式,在我们的Android中有什么经典应用呢。此时我打开了AndroidStudio,直接跳到了我们的Intenet源码。

*

*

These are the possible flags that can be used in the Intent via

* {@link #setFlags} and {@link #addFlags}. See {@link #setFlags} for a list

* of all possible flags.

*/

public class Intent implements Parcelable, Cloneable {

...

@Override

public Object clone() {

return new Intent(this);

}

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(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);

}

}

...

}

可以见到,我们的Intent是深度拷贝,而且是直接new一个的深度拷贝。可见其设计初衷不是因为其不是为了解决构建复杂对象的资源消耗问题。

总结

原型模式本质上就是对象拷贝,与 C++ 中的拷贝构造函数有些类似,它们之间容易出现的问题也都是深拷贝、浅拷贝。使用原型模式可以解决构建复杂对象的资源消耗问题,能够在某些场景下提升创建对象的效率。还有一个重要的途径就是保护性拷贝,也就是某个对象对外可能是只读的,为了防止外部对这个只读对象修改,通常可以通过返回一个对象拷贝的形式实现只读的限制。

优点:原型模式是在内存中二进制流的拷贝,要比直接 new 一个对象性能好很多,特别是要在一个循环体内产生大量的对象时,原型模式可以更好滴体现其优点。

缺点:这既是它的优点也是缺点,直接在内存中拷贝,构造函数是不会执行的,在实际开发中应该注意这个潜在问题,优点就是减少了约束,缺点也是减少了约束,需要大家在实际应用是考虑。

谢谢大家阅读,如有帮助,来个喜欢或者关注吧!

本文作者:Anderson/Jerey_Jobs

简书地址:[Anderson大码渣][1]

1、home桌面规则及划屏操作 1.1home桌面规则 桌面页数最大为9屏,开机默认显示第1屏即时钟widget。 1.2桌面划屏操作 (请用鼠标划屏体验) 桌面页面可划屏切换,切换的效果为桌面滚动。每向左划一次屏则桌面亦向左滚动一屏,页码栏的小圆点前进一个页码,同时背景图要向左移动微量移动;向右则相反。提示页码的小圆点在页码即将变化时呈逐级缩放的渐变效果,缩放级数为四级。 2、主菜单(应用程序列表)的切换及划屏操作 2.1 桌面与主菜单界面切换 (请用鼠标点击界面底部的“主菜单/主页“图标体验) 点界面底部Launcher快捷栏的主菜单图标切换到主菜单界面。主菜单界面从下方弹出(注意过渡效果,弹出时间为300ms)。默认的页码为第1页。主菜单背景图以从哪个桌面进入就以哪个桌面的背景为背景图,并叠加一半透明灰色效果以区别于home桌面背景。进入主菜单后再划屏,背景位置不变。 2.3主菜单界面划屏操作 (请用鼠标划屏体验) 划屏时可循环切换 ,即持续往一个方向划屏时会循环显示各页面。(请用鼠标操作体验)。划屏过程在页码即将改变时,页码栏的小圆点发生四级缩放的变化。 3、页码栏的操作 3.1home桌面页码栏操作 (请用鼠标点击小圆点体验) 表示页码的小圆点桌面页码栏支持点击操作。点击小圆点时,被点击的小圆点逐级放大并显示页码数字;与此同时显示点击之前页码数字的小圆点逐级缩小且数字消失。同时屏幕会滚动到该页。 3.2主菜单页码栏操作 页码栏只支持点击操作。效果同2.1。 4、多点触控(pinch)操作(请用鼠标点击右边的手势模拟效果) 桌面或主菜单界面都支持pinch操作。pinch动作后会进入缩略图界面。点击缩略图即可进入相应的页面。这里要做成逐级缩放的效果。即pinch动作后,当前页面逐级缩小(分六至八级),透明度亦逐级变小,最后展现缩略图界面。点击缩略图时,相应的页面缩略图则逐级放大,透明度亦逐级放大,最后展现普通界面。 缩略图超过4页以九宫格排列。低于4页则以4宫格排列。在桌面缩略图界面可进行桌面管理,如桌面重排、桌面隐藏、桌面恢复、桌面增加和删除等。详见动画演示文档。 5、Launcher快捷栏操作(请用鼠标拖动体验) Launcher快捷栏的图标分左右两页,每页四个图标。可左右拖动,支持循环切换,即持续拖动时会循环显示两页内容(请拖动试试)。 在home界面点“主菜单”图标,会切换到主菜单界面。同时该图标变成“主页”(注意两页同时变化)。在主菜单界面点“主页”图标,则切换到home桌面,且该图标变成“主菜单”。(请点击体验) Launcher快捷栏除“通话”、“信息”、“联系人”、“主页/主菜单“图标不可替换外,其它图标可替换。替换方法详见动画演示文档。 6、menu键、back键、home键 从桌面进menu菜单,可更换壁纸(背景图),添加桌面内容(widget、应用、文件夹等 (演示 略) 主界面点 back 返回桌面。(演示 略) 长按home键,显示最近使用过的应用程序。(演示 略)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值