1.意图
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
热门词汇:骨架 步骤 结构 延迟到子类
2.结构
定义了几个步骤1,2,3等,在模板方法中按照一定的结构顺序执行这些步骤。父类的方法可以有缺省实现,也可以是一个空实现,即所谓的钩子操作。
结合实际情况,我们画出View中draw方法涉及到的几个步骤方法如下:
学习模板方法对于我们了解框架的基类实现,生命周期和流程控制非常有帮助,我觉得是务必要掌握的一个模式。
3.代码
1 public class View{ 2 /** 3 * 钩子操作,空实现 4 */ 5 protected void onDraw(Canvas canvas) { 6 } 7 8 /** 9 *钩子操作,空实现 10 */ 11 protected void dispatchDraw(Canvas canvas) { 12 } 13 14 //算法骨架 15 public void draw(Canvas canvas) { 16 if (!verticalEdges && !horizontalEdges) { 17 // 步骤1 18 if (!dirtyOpaque) onDraw(canvas); 19 20 // 步骤2 21 dispatchDraw(canvas); 22 23 // 步骤3 24 onDrawScrollBars(canvas); 25 26 return; 27 } 28 } 29 //... ... 30 }
我们看看系统组件TextView的实现:
1 public class TextView{ 2 @Override 3 protected void onDraw(Canvas canvas) { 4 //大量自定义实现代码 5 } 6 }
如果我们自定义View的话,我们一般也是重写onDraw方法即可:
1 public class MyView extends View { 2 3 public MyView(Context context) { 4 super(context); 5 } 6 7 @Override 8 protected void onDraw(Canvas canvas) { 9 super.onDraw(canvas); 10 } 11 12 @Override 13 protected void dispatchDraw(Canvas canvas) { 14 super.dispatchDraw(canvas); 15 } 16 17 }
4.效果
(1).模板方法是一种代码复用的基本技术。它们在类库中尤为重要,它们提取了类库中的公共行为。
(2).模板方法导致一种方向控制结构,"好莱坞法则":"Don\'t call me,i will call you.",即一个父类调用子类的操作,而不是相反。
(3).模板调用操作的类型有具体的操作,具体的AbstracClass操作,原语操作,工厂方法,钩子操作。少定义原语操作。
(4).android中对这些重定义操作的命名喜欢在方法前加一个前缀on。
(5).模板方法使用继承来改变算法的一部分。策略模式使用委托来改变整个算法。