Android设计模式学习日记05--模板模式

Android设计模式系列(4)--SDK源码之模板方法模式

模板方法,和单例模式是我认为GOF的23中最简单的两种模式。
但是我个人对模板方法的经典思想特别推崇,虽然模板方法在大对数情况下并不被推荐使用,但是这种通过父类调用子类的方法,使用继承来改变算法的一部分,是面向对象的一种基本认识。
打比方说父亲有很多理想,就行医救人吧,但是父亲医术不行,只能靠儿子,儿子长大后遵从父亲大志,春风拂面,妙手回春,实现了父亲的理想,儿子做的事情早在出生前就定下来了,是父亲之前久定好的模板。  --我很赞同 
认识到模板方法的这种思想,父类可以让未知的子类去做它本身可能完成的不好或者根本完成不了的事情,对框架学习大有帮助。
本文以View中的draw方法为例,展开分析。
模板方法,TemplateMethod,光是学习这个模式,就会对你产生长远影响的一个模式。

1.意图
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 
热门词汇:骨架 步骤 结构 延迟到子类 

2.结构 

定义了几个步骤1,2,3等,在模板方法中按照一定的结构顺序执行这些步骤。父类的方法可以有缺省实现,也可以是一个空实现,即所谓的钩子操作。
结合实际情况,我们画出View中draw方法涉及到的几个步骤方法如下:


学习模板方法对于我们了解框架的基类实现,生命周期和流程控制非常有帮助,我觉得是务必要掌握的一个模式。

3.代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public  class  View{
     /**
      * 钩子操作,空实现
      */
     protected  void  onDraw(Canvas canvas) {
     }
 
     /**
      *钩子操作,空实现
      */
     protected  void  dispatchDraw(Canvas canvas) {
     }
 
     //算法骨架
     public  void  draw(Canvas canvas) {
        if  (!verticalEdges && !horizontalEdges) {
             // 步骤1
             if  (!dirtyOpaque) onDraw(canvas);
 
             // 步骤2
             dispatchDraw(canvas);
 
             // 步骤3
             onDrawScrollBars(canvas);
 
             return ;
         }
     }
     //... ...
}

  我们看看系统组件TextView的实现:

1
2
3
4
5
6
public  class  TextView{
     @Override
     protected  void  onDraw(Canvas canvas) {
         //大量自定义实现代码
     }
}

  如果我们自定义View的话,我们一般也是重写onDraw方法即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public  class  MyView extends  View {
 
     public  MyView(Context context) {
         super (context);
     }
 
     @Override
     protected  void  onDraw(Canvas canvas) {
         super .onDraw(canvas);
     }
 
     @Override
     protected  void  dispatchDraw(Canvas canvas) {
         super .dispatchDraw(canvas);
     }
     
}

4.效果
(1).模板方法是一种代码复用的基本技术。它们在类库中尤为重要,它们提取了类库中的公共行为。
(2).模板方法导致一种方向控制结构,"好莱坞法则":"Don't call me,i will call you.",即一个父类调用子类的操作,而不是相反
(3).模板调用操作的类型有具体的操作,具体的AbstracClass操作,原语操作,工厂方法钩子操作。少定义原语操作(按我的理解应该就是具体操作了)。
(4).android中对这些重定义操作的命名喜欢在方法前加一个前缀on。
(5).模板方法使用继承来改变算法的一部分。策略模式使用委托来改变整个算法。

下面的资料参考来自 http://www.cnblogs.com/god_bless_you/archive/2010/06/06/1752514.html

要点:

1. 模板方法中的非final方法(默认实现或不做事的方法)称为“钩子”。

2. 钩子可以简化子类的实现。

3. 钩子可以让子类能够有机会对模板方法中某些即将发生的(或刚刚发生的)步骤做出反应。

4. primitiveMethod(原始方法)的命名最好加上do前缀。

5. 工厂模式为模板方法模式的特例

6. 除了可以灵活应对子步骤的变化外,“不用调用我,让我来调用你”的反向控制结构是Template Method的典型应用。

7. 模板方法是代码复用的一项基本的技术,在类库中尤其重要。,它遵循“抽象类应当拥有尽可能多的行为,应当拥有尽可能少的数据”的重构原则。




AbstractClass:

1. 定义并实现了一个模板方法,定义了一个算法的骨架。

2. 定义抽象的primitiveMethod,具体的子类将实现它们以实现模板骨架的各个算法步骤。

abstract public class AbstractClass
{
	public void TemplateMethod()
	{
		
		primitiveMethod1();
		
		primitiveMethod2();
		
		doOperation3();
		
	}
	
	protected abstract void primitiveMethod1();
	
	protected abstract void primitiveMethod2();
	
	private final void doOperation3()
	{
		
		// do something
		
	}	
}

 

ConcreteClass:

1. 实现primitiveMethod以完成算法中与特定子类相关的步骤。

public class ConcreteClass extends AbstractClass
{
	public void primitiveMethod1()
	{
		
		// write your code here
		
		System.out.println("primitiveMethod1();");
		
	}
	
	public void primitiveMethod2()
	{
		
		// write your code here
		
		System.out.println("primitiveMethod2();");
		
	}
}

 

模板方法模式中的方法:

模板方法:定义在AbstractClass中,形成算法的骨架

基本方法:

1. Abstract Method:由子类具体实现,完成具体的算法步骤。

2. Concrete Method:抽象类实现的final方法,子类不能override。

3. Hook Method:提供缺省的实现,子类可以在必要时进行扩展,钩子简化了子类的实现,它可以让子类能够有机会对模板方法中某些即将发生的(或刚刚发生的)步骤做出反应

 

适用性:

1. 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。

2. 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。这是Opdyke和Johnson所描述过的“重分解以一般化”的一个很好的例子。首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。

3. 控制子类扩展。模板方法只在特定点调用Hook操作,这样就只允许在这些点进行扩展。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值