1.模板模式的定义及使用场景
定义一个操作中的算法框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
使用场景:
多个子类有公有的方法,并且逻辑基本相同
重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现
重构时,模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数约束其行为
2.模板模式的优缺点
2.1优点
封装不变的部分,扩展可变部分
提取公共部分代码,便于维护
行为由父类控制,子类实现
2.2缺点
抽象类定义了部分抽象方法,由子类实现,子类执行的结果影响父类的结果,也就是子类对父类产生了影响,在负责的项目中,会带来代码阅读的复杂性
2.3注意事项
在开发中经常遇到一个问题,父类怎么调用子类的方法?应善用模板模式,避免如下的使用:
把子类传递到父类的有参构造中,然后调用
使用反射的反射调用
父类调用子类的静态方法
3.模板模式的实现方式
AbstactTemple
public abstract class AbstactTemple {
protected abstract void doOne();
protected abstract boolean doTwo();
public final void templeMethod() {
doOne();
if (doTwo()) {
System.out.println("the world is bueatiful");
}
}
}```
ConcreteTempleOne
public class ConcreteTempleOne extends AbstactTemple {
@Override
protected void doOne() {
System.out.println("ConcreteTempleOne:" + "doOne");
}
@Override
protected boolean doTwo() {
return true;
}
}```
ConcreteTempleTwo
public class ConcreteTempleTwo extends AbstactTemple {
@Override
protected void doOne() {
System.out.println("ConcreteTempleTwo:" + "doOne");
}
@Override
protected boolean doTwo() {
return false;
}
}```
Test
public class Test {
public static void main(String args[]) {
AbstactTemple templeOne = new ConcreteTempleOne();
AbstactTemple templeTwo = new ConcreteTempleTwo();
templeOne.templeMethod();
templeTwo.templeMethod();
}
}```
4.模板模式在Android中的实际应用
在Android中,AsyncTask是比较常见的一个类型,这个类就是使用了模板模式。在使用AsyncTask时,我们都知道把耗时的方法放在doInBackground(Params… params)中,在doInBackground之前,如果还想做一些类似初始化的操作,可以把实现卸载onPreExecutre方法中,当doInBackground方法执行完成后,会执行onPostExecutre方法,而我们只需要构建AsyncTask对象,然后执行exexute方法即可。
AsyncTask主要使用了线程池及任务队列,handle消息机制。
启动执行:将任务交由线程池处理
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
ublic final AsyncTask<Params, Progress, Result> 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;
}```
处理消息队列:
public AsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
Result result = doInBackground(mParams); //处理后台的方法
Binder.flushPendingCommands();
return postResult(result); //消息分发
}
};
mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void done() {
try {
postResultIfNotInvoked(get());
} catch (InterruptedException e) {
android.util.Log.w(LOG_TAG, e);
} catch (ExecutionException e) {
throw new RuntimeException("An error occurred while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
postResultIfNotInvoked(null);
}
}
};
}
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}```
处理Mesage消息:
private static class InternalHandler extends Handler {
public InternalHandler() {
super(Looper.getMainLooper());
}
@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
@Override
public void handleMessage(Message msg) {
AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
switch (msg.what) {
case MESSAGE_POST_RESULT:
// There is only one result
result.mTask.finish(result.mData[0]);
break;
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;
}
}
}
private void finish(Result result) {
if (isCancelled()) {
onCancelled(result);
} else {
onPostExecute(result);//处理完成的回调
}
mStatus = Status.FINISHED;
}