设计模式之模版方法模式

用大白话说就是某事具有一个固定的流程,比如电脑开机,它固定流程为:

开启电源 -> 检查硬件 -> 载入操作系统 -> 用户登陆

不同的电脑可以有不同的操作系统,所以,载入操作系统这一步骤我们可以给子类实现不同的操作,其他步骤可以在父类中有相同的操作。另外一个例子就是请客吃饭:

点菜 -> 等厨师做菜 -> 买单

这个流程基本也是固定的,但是第二步骤每次不一样,根据第一步的点菜不同,就会有不同的实现,同样我们可以将第一步和第三步交给父类统一处理,而第二步延迟给子类来自定义。这样就起到了很好的封装作用。

Template method pattern

定义

定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

In software engineering, the template method pattern is a behavioral design pattern that defines the program skeleton of an algorithm in an operation, deferring some steps to subclasses. It lets one redefine certain steps of an algorithm without changing the algorithm’s structure.

UML class diagram

Android中应用

Android中的AsyncTask的使用就是典型的模版方法模式,该类为异步操作提供了4个顺序步骤(流程):

  1. onPreExecute(), invoked on the UI thread before the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.
  2. doInBackground(Params…), invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. The parameters of the asynchronous task are passed to this step. The result of the computation must be returned by this step and will be passed back to the last step. This step can also use publishProgress(Progress…) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress…) step.
  3. onProgressUpdate(Progress…), invoked on the UI thread after a call to publishProgress(Progress…). The timing of the execution is undefined. This method is used to display any form of progress in the user interface while the background computation is still executing. For instance, it can be used to animate a progress bar or show logs in a text field.
  4. onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.

AsyncTask必须继承子类使用,并且至少重写doInBackground()方法。其实我们使用的时候,也是按照上面的顺序来写,onPreExecute里面显示对话框,告诉用户正在异步操作请求,doInBackground里面做真正的异步操作,请求网络或者加载图片等等,根据不同需求就不同的写法,onProgressUpdate主要是自己处理进度,onPostExecute是异步请求结束的结果,比如网络请求列表或者图片地址等。

除此之外,Activity的生命周期函数也是一个典型用法:onCreate - onStart - onResume - onPause - onStop - onDestroy.

使用场景

  1. 多个子类有公有的方法,并且逻辑基本相同时。
  2. 重要、复杂的算法,可以把核心算法设计为模版方法,周边的相关细节功能则由各个子类实现。
  3. 重构时,模版方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数约束其行为。

总结

该模式主要核心就是:流程封装

优点

  • 封装不变部分,扩展可变部分。
  • 提取公共部分代码,便于维护。

缺点

  • 需要为每一个基本方法的不同实现提供一个子类,如果父类中可变的基本方法太多,将会导致类的个数增加,系统更加庞大,设计也更加抽象。

参考

评论留言请点这里