设计模式相关面试问题-模板方法

模板方法模式详解:

  • 概念
    模板方法是通过定义一个算法骨架,而将算法中的步骤延迟到子类,这样子类就可以复写这些步骤的实现来实现特定的算法。
  • 使用场景
    1、多个子类有公有的方法,并且逻辑基本相同时。
    2、重复,复杂的算法,可以把核心算法设计为模板方法。
    3、重构时,模板方法模式是一个经常使用的模式。
  • UML结构图分析
  • 实际代码分析
    首先建议抽象类:
    public abstract class AbstractWork {
    
        //其中声明为final是不允许子类重写
        public final void newDay() {
            getUp();
            goToWork();
            work();
            getOffWork();
        }
    
        //这是每个人都共有的特性
        protected void getUp() {
            System.out.println("起床啦:");
        }
    
        protected abstract void getOffWork();
    
        protected abstract void work();
    
        protected abstract void goToWork();
    }

    然后具体类来继承它,如下:

    /**
     * 老板工作
     */
    public class BossWork extends AbstractWork {
        @Override
        protected void getOffWork() {
            System.out.println("老板开车去下班");
        }
    
        @Override
        protected void work() {
            System.out.println("老板分配工作给员工");
        }
    
        @Override
        protected void goToWork() {
            System.out.println("老板开车去上班");
        }
    }
    /**
     * 普通员工工作
     */
    public class StaffWork extends AbstractWork {
        @Override
        protected void getOffWork() {
            System.out.println("员工坐公交去下班");
        }
    
        @Override
        protected void work() {
            System.out.println("员工处理具体工作");
        }
    
        @Override
        protected void goToWork() {
            System.out.println("员工坐公交去上班");
        }
    }

    下面来运用一下:


    另外扩展一下:还有一个具体模板,它跟抽象模板定义是不一样的,具体区别如下:
    抽象模板 / 具体模板:定义的数量和类型 / 模板方法的数量

模板方法模式在android中的实际运用:

  • activity && fragment
    像咱们的生命周期回调方法就是其父类定义好的,咱们只能去重写,这就是典型的模板方法啦。
  • AsyncTask
    对于它,我们常用的几个方法:onPreExecute()、doInBackground()、onProgressUpdate()、onPostExecute(),其实都是以模板方法定义在AsyncTask当中的,如下:

     
    而对于AsyncTask的启动通常是要调用它的execute()方法,所以源码定位到它:

     接着来分析一下是怎么在线程池中运行的:

    所以这也是为啥AsyncTask只能执行一次的原因啦,好接着继续往下分析:

    接着往下执行:

    其实这两个变量是在AsyncTask的构造函数中进行初始化的,如下:

    而mWorker是WorkerRunnable类型,那WorkerRunnable又是啥类型呢?

    而它里面就会执行doInBackground()执行异步任务了,如下:

     而mFuture是FutureTask类型,那什么是FutureTask呢?这里需要介绍一下:
    1、Future<V>接口:用来获取异步计算结果的,说白了就是对具体的Runnable或者Callable对象任务执行的结果进行获取(get()),取消(cancel()),判断是否完成等操作。
    2、FutureTask:FutureTask除了实现了Future接口外还实现了Runnable接口,因此FutureTask也可以直接提交给Executor执行。
    明白了FutureTask的作用之后,还是回到mWorker,在执行完doInBackground()之后,还会有如下执行:

    继续跟踪:

    而AsyncTask的finish()方法的具体代码如下:

    所以我们在处理结果就会在onPostExecute()方法里面,至此整个AsyncTask的完整过程就分析完了。

posted on 2018-05-04 22:04  cexo  阅读(243)  评论(0编辑  收藏  举报

导航