android开发工厂模式,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;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值