前言
定义:
定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤;
使用场景:
- 多个子类有公有的方法,并且逻辑基本相同时;
- 重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现;
- 重构时,模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数约束行为;
UML类图:
AbsTemplate:
抽象类,定义了一套算法框架;ConcreteImpA、ComcreteImpB:
具体实现类;
示例实现
这里以去健身房用跑步机跑步
举例,用跑步机跑步的步骤是一套固定的算法框架,都需要开机
、跑步
、关机
,但每个人的跑步习惯不一样,下面我们就使用模板模式来实现:
- 定义抽象跑步机跑步步骤,
TreadMill
/**
* 抽象跑步机跑步(定义了一系列跑步机跑步步骤)
*/
abstract class TreadMill {
protected open fun powerOn() {
println("启动跑步机....")
}
protected open fun running() {
println("跑步机上进行跑步....")
}
protected open fun powerOff() {
println("跑完结束,关闭跑步机....")
}
/**
* 跑步机跑步
*/
fun treadMillRunning() {
powerOn()
running()
powerOff()
}
}
- PersonA 用跑步机跑步,
PersonARunning
/**
* PersonA 用跑步机跑步
*/
class PersonARunning : TreadMill() {
override fun running() {
super.running()
println("我是 PersonA 我跑累了....")
rest()
}
private fun rest() {
println("PersonA 休息一会....")
}
}
- PersonB用跑步机跑步,
PersonBRunning
/**
* PersonB 用跑步机跑步
*/
class PersonBRunning : TreadMill() {
override fun powerOn() {
super.powerOn()
//personB调整跑步机参数 设置速度 坡度
setUpTreadMillParams()
}
override fun running() {
super.running()
wipeSweat()
}
private fun setUpTreadMillParams() {
println("PersonB 调整跑步机相关参数....")
}
private fun wipeSweat() {
println("PersonB 边跑步边擦汗....")
}
}
- 编写测试类进行验证
object Test {
@JvmStatic
fun main(args: Array<String>) {
//personA 跑步机跑步
val personA = PersonARunning()
personA.treadMillRunning()
println("-------------------------")
println("-------------------------")
//personB 跑步机跑步
val personB = PersonBRunning()
personB.treadMillRunning()
}
}
结果输出:
启动跑步机....
跑步机上进行跑步....
我是 PersonA 我跑累了....
PersonA 休息一会....
跑完结束,关闭跑步机....
-------------------------
-------------------------
启动跑步机....
PersonB 调整跑步机相关参数....
跑步机上进行跑步....
PersonB 边跑步边擦汗....
跑完结束,关闭跑步机....
Android源码中的模板方法模式
-
AsyncTask
,定义了onPreExecute()
、doInBackground()
、onPostExecute()
、onProgressUpdate()
一系列模板方法; -
Activity的声明周期
,onCreate()
、onStart()
、onResume()
、...
-
View的draw方法
,定义了drawBackground()
、onDraw()
、dispatchDraw()
、onDrawForeground()
、drawDefaultFocusHighlight()
一系列模板方法;
总结
优点:
- 封装不变部分,扩展可变部分;
- 提供共用部分代码,便于维护;
缺点:
- 模板方法会带来代码阅读的难度,会让用户觉得难以理解;
结语
如果以上文章对您有一点点帮助,希望您不要吝啬的点个赞加个关注,您每一次小小的举动都是我坚持写作的不懈动力!ღ( ´・ᴗ・` )