android开发工厂模式,Android开发笔记(九十一)工厂模式_weixin_39671509的博客-程序员宝宝

技术标签: android开发工厂模式  

基本概念

工厂模式是一种常用的实例化对象设计模式。

程序开发很多时候都在不停地敲if、else,因为业务需求总在发展变化,今天客户要求生产A产品,明天客户要求把A产品稍微改改变成B产品,当然A产品与B产品的基本特性差不多,只在某些细节上存在差异。可是这样推陈出新就害苦了程序员,每次变动都得加上一堆的if、else,而且随着产品数量变多,程序代码也越来越难以维护。

工厂模式的出现便是要解决这种困惑,它把产品制造分为两种参与对象,第一种是制造出来的产品,第二种是负责制造的工厂。各产品肯定要进行抽象出一个基本产品,然后各产品在具体实现上各显神通。工厂则依据业务需求的复杂程度,如果业务简单层次不多,那么一个工厂类就够用了,此时叫做工厂方法模式;如果业务复杂层次较多,那么连工厂也要进行抽象化,先抽象出基本工厂,然后派生出具体的工厂,最后具体的工厂再去制造产品,此时叫做抽象工厂模式。

Android中的使用场合

工厂模式在概念上相当规范,但实际开发中往往有所取舍,并不完全遵循工厂模式的定义规范。Android源码中类似工厂模式的地方主要有三处,分别是值工厂、实例工厂、类工厂。

值工厂

值工厂的输入参数是基本数据类型,根据不同的数值进行分支处理。值工厂的代表源码是Activity类的getSystemService方法,该方法根据输入的服务名称字符串,返回对应的服务管理类的对象。下面是getSystemService方法的源码:

@Override

public Object getSystemService(String name) {

if (getBaseContext() == null) {

throw new IllegalStateException(

"System services not available to Activities before onCreate()");

}

if (WINDOW_SERVICE.equals(name)) {

return mWindowManager;

} else if (SEARCH_SERVICE.equals(name)) {

ensureSearchManager();

return mSearchManager;

}

return super.getSystemService(name);

}

实例工厂

实例工厂的输入参数是类的实例,不过这个实例可能是由不同派生类的对象,所以工厂内部得使用instanceof判断该实例属于哪个派生类,然后再做相应处理。实例工厂的代表源码是BitmapFactory的decodeStream方法,该方法中判断如果输入流是AssetInputStream的实例,那么调用jni接口nativeDecodeAsset,否则最终调用jni接口nativeDecodeStream。从这个代码可以看出,android对asset路径下的图片与磁盘路径下的图片操作是不一样的,只是工厂模式为我们屏蔽了它们之间的区别。

下面是decodeStream方法的源码:

public static Bitmap decodeStream(InputStream is, Rect outPadding, Options opts) {

// we don't throw in this case, thus allowing the caller to only check

// the cache, and not force the image to be decoded.

if (is == null) {

return null;

}

Bitmap bm = null;

Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeBitmap");

try {

if (is instanceof AssetManager.AssetInputStream) {

final int asset = ((AssetManager.AssetInputStream) is).getAssetInt();

bm = nativeDecodeAsset(asset, outPadding, opts);

} else {

bm = decodeStreamInternal(is, outPadding, opts);

}

if (bm == null && opts != null && opts.inBitmap != null) {

throw new IllegalArgumentException("Problem decoding into existing bitmap");

}

setDensityFromOptions(bm, opts);

} finally {

Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);

}

return bm;

}

类工厂

类工厂的输入参数为类名,这得用模板来表示了。类工厂用的就比较多,比如java的容器类ArrayList、HashMap等等都用到了类工厂。当然了,容器类是java自带的,若要问Android的类工厂,那得数AsyncTask。话说AsyncTask的模板一口气用到了三个类参数,而且许多成员方法都用到了类参数,因此开发中还没法直接使用AsyncTask,得重新编写它的派生类,并重写相关方法。

下面是AsyncTask的源码节选:

public abstract class AsyncTask {

private final WorkerRunnable mWorker;

private final FutureTask mFuture;

protected abstract Result doInBackground(Params... params);

protected void onPreExecute() {

}

protected void onPostExecute(Result result) {

}

protected void onProgressUpdate(Progress... values) {

}

protected void onCancelled(Result result) {

onCancelled();

}

public final AsyncTask execute(Params... params) {

return executeOnExecutor(sDefaultExecutor, params);

}

public final AsyncTask executeOnExecutor(Executor exec,

Params... params) {

if (mStatus != Status.PENDING) {

switch (mStatus) {

case RUNNING:

throw new IllegalStateException("Cannot execute task:"

+ " the task is already running.");

case FINISHED:

throw new IllegalStateException("Cannot execute task:"

+ " the task has already been executed "

+ "(a task can be executed only once)");

}

}

mStatus = Status.RUNNING;

onPreExecute();

mWorker.mParams = params;

exec.execute(mFuture);

return this;

}

}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_39671509/article/details/117774043

智能推荐

excel 个人日常记账——统计报表_小码农吗的博客-程序员宝宝_个人记账excel

前言为了日常开销的一个统计,excel本地保存,个人隐私信息绝对安全。禁止商业模式使用,违者后果自付。效果图1 首页2 月份3 导航重点有想用的联系※ 小插曲:本期分享就到这里、欢迎一起学习探讨,※ 有想要一起加入的请关注公众号“小码农吗” 以及有趣的小程序“小韩欢乐屋”...

vue中$set的使用场景_微 光的博客-程序员宝宝

场景1:通过数组的下标去修改数组的值,数据已经被修改了,但是不触发updated函数,视图不更新,export default { data () { return { items: ['a', 'b', 'c'] }; }, updated () { console.log('数据更新', ...

51nod-1686 第K大区间_天夏123的博客-程序员宝宝

原题链接1686 第K大区间基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注定义一个区间的值为其众数出现的次数。现给出n个数,求将所有区间的值排序后,第K大的值为多少。众数(统计学/数学名词)_百度百科 Input

Tomcat中JVM内存溢出及合理配置_weixin_33704234的博客-程序员宝宝

为什么80%的码农都做不了架构师?>>> ...

SWPU-ACM集训队周赛之组队赛(3-11) C题题解_weixin_30451709的博客-程序员宝宝

点这里去看题模拟,注意细节#include<stdio.h>#include<string.h>int main(){ int T,n,i,j,ct,q[1010];  //q[]储存正负信息 scanf("%d",&T); while(T--) { char a[1010...

PAT 甲级 1158 Telefraud Detection_漫浸天空的雨色的博客-程序员宝宝

1158 Telefraud Detection(25 分)Telefraud(电信诈骗) remains a common and persistent problem in our society. In some cases, unsuspecting victims lose their entire life savings. To stop this crime, you are...

随便推点

Android开发-使用ViewPager2控件实现抖音视频上下滑动播放功能__彼岸雨敲窗_的博客-程序员宝宝_viewpager2 抖音

前 言目前抖音 App 比较火,大家在玩 Android 版的抖音的过程中有没有发现,当你在刷抖音视频时手指上滑拉取下一视频,大家有没有觉得拉取视频很顺畅,而且视频能立即播放,当手指下滑拉取上一视频,效果也一样。其实这背后都是 ViewPager2 控件的功劳,当用户启动到抖音视频页面时,ViewPager2 除了加载当前的视频界面外还自动加载下一个视频界面的操作,所以大家有没有感觉首次进入到视频页面加载视频时等待的时间很长,这其实是 ViewPager2 同时加载当前视频和下一个视频的原因。当用户上

关于802.15.4 下RFD和RFD通讯问题求证_zigbeekiller的博客-程序员宝宝

  我们知道在IEEE802.15.4下有说明,FFD可以和FFD对话,也可以和RFD对话,但RFD只能同FFD对话。(An FFD can talk to RFDs or other FFDs, while an RFD cantalk only to an FFD. P22。)     但在实际应用时并非如此,本人通过对JENNIC MAC做简单配置后可以做到RFD同RFD通讯.具

37 使用accumulate或者for_each进行区间统计_扮猪吃饺子的博客-程序员宝宝

1.count告诉你一个区间有多少个元素,count_if统计满足判别式的元素个数。2.区间的最大值和最小值分别为max_element和max_element.算法accumulate 和 inner_product、adjacent_differenthe和partial_sum 头文件是<numeric>区间统计处理:可能计算一个区间的数值的乘积;计算一个区间的平均坐标等。...

19 个 JavaScript 常用的简写技术——爱创课堂_普通网友的博客-程序员宝宝

1.三元操作符当想写if...else语句时,使用三元操作符来代替。const x = 20;let answer;if (x > 10) {    answer = 'is greater';} else {    answer = 'is lesser';}简写:const answer = x > 10 ? 'is greater' : 'is lesser';

Windows Server 2008 终端服务授权激活-离线_炎雨0927的博客-程序员宝宝

Windows Server 2008 终端服务授权激活-离线 版权声明:本文为炎雨0927(heiyan_7)原创文章,非商用自由转载,请保持署名并注明出处,谢谢。需求:公司内网有一台用于安全检测的服务器,操作系统版本是Windows Server 2008 R2 Enterprise SP1,要实现多人远程登录(10个人以上),第一次修改远程连接数,实现了多人登录,没有问题。但是,用过一段

推荐文章

热门文章

相关标签