定義
在一個方法中定義一個算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以在不改變算法結構的情況下,重新定義算法中的某些
步驟。
鉤子
鉤子是一種被聲明在抽象類中的方法,但只有空的或者默認的實現(xiàn)。鉤子的存在,可以讓子類有能力對算法的不同點進行掛鉤。要不要掛鉤有子類自己決定。
目的:
鉤子可以讓子類實現(xiàn)算法中的可選部分,或者在鉤子對子類的實現(xiàn)并不重要的時候,子類可以對此鉤子置之不理。
要點
1、“模板方法”定義了算法的步驟,把這些步驟的實現(xiàn)延遲到子類;
2、模板方法模式為我們提供了一種代碼復用的可重要技巧;
3、模板方法的抽象類可以定義具體方法、抽象方法和鉤子;
4、抽象方法由子類實現(xiàn);
5、鉤子是一種方法,它在抽象類中不做事,或者只做默認的事情,子類可以選擇要不要覆蓋它;
6、為了防止子類改變模板算法中的方法,可以用將模板方法聲明為final;
7、好萊塢原則告訴我們,將決策權放在高層模塊中,以便決定如何以及何時調用底層模塊。
實例
CaffeineBeverage.java
1
2
package com.sailor.templateMethod;
3
4
/**
5
* @author sailor
6
* Jul 26, 2008 8:26:42 AM
7
*/
8
public abstract class CaffeineBeverage {
9
10
final void prepareRecipe(){
11
boilWater();
12
brew();
13
pourInCup();
14
if(customerWantsCondiments()){
15
addCondiments();
16
}
17
}
18
19
//由子類實現(xiàn)方法
20
abstract void brew();
21
22
//由子類實現(xiàn)方法
23
abstract void addCondiments();
24
25
final void boilWater(){
26
System.out.println("Boilding water");
27
}
28
29
final void pourInCup(){
30
System.out.println("Pouring into cup");
31
}
32
33
//這是一個鉤子,子類可以覆蓋也可以不覆蓋
34
public boolean customerWantsCondiments(){
35
return true;
36
}
37
}
38

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

31

32

33

34

35

36

37

38

1
package com.sailor.templateMethod;
2
3
import java.io.BufferedReader;
4
import java.io.IOException;
5
import java.io.InputStreamReader;
6
7
/**
8
* @author sailor
9
* Jul 26, 2008 8:38:54 AM
10
*/
11
public class Coffee extends CaffeineBeverage{
12
13
14
@Override
15
void addCondiments() {
16
System.out.println("Dripping Coffee throug filter");
17
}
18
19
@Override
20
void brew() {
21
System.out.println("Adding Sugar and Milk");
22
}
23
24
@Override
25
public boolean customerWantsCondiments() {
26
27
String answer = getUserInput();
28
29
if(answer.toLowerCase().startsWith("y"))
30
return true;
31
else
32
return false;
33
}
34
35
private String getUserInput(){
36
String answer = null;
37
38
System.out.println("Would you liak milk and sugar with your coffee(y/n)?");
39
40
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
41
42
try {
43
answer = br.readLine();
44
} catch (IOException e) {
45
e.printStackTrace();
46
}
47
48
if(answer == null){
49
return "no";
50
}
51
52
return answer;
53
}
54
}
55

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

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

1
2
package com.sailor.templateMethod;
3
4
/**
5
* @author sailor
6
* Jul 26, 2008 8:32:03 AM
7
*/
8
public class Tea extends CaffeineBeverage{
9
10
@Override
11
public void addCondiments() {
12
System.out.println("Steeping the tea");
13
}
14
15
@Override
16
public void brew() {
17
System.out.println("Adding lemon");
18
}
19
20
21
}
22

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

1
package com.sailor.templateMethod;
2
3
/**
4
* @author sailor
5
* Jul 26, 2008 8:34:30 AM
6
*/
7
public class Client {
8
9
public static void main(String args[]){
10
// Tea myTea = new Tea();
11
// myTea.prepareRecipe();
12
13
Coffee myCoffee = new Coffee();
14
myCoffee.prepareRecipe();
15
System.out.println("end");
16
}
17
18
}
19

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19
