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


    模板方法模式详解:

    • 概念
      模板方法是通过定义一个算法骨架,而将算法中的步骤延迟到子类,这样子类就可以复写这些步骤的实现来实现特定的算法。
    • 使用场景
      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的完整过程就分析完了。

  • 相关阅读:
    Proxies
    内置的Symbol值
    css兼容问题大全
    Jquery ajax方法详解
    Ajax笔记
    Jquery笔记
    Css3笔记
    JavaScript学习笔记
    10 款优秀的文件管理插件推荐
    初始化和预装载servlet与JSP页面
  • 原文地址:https://www.cnblogs.com/webor2006/p/8992741.html
Copyright © 2020-2023  润新知