(原創) 我的Design Pattern之旅[3]:使用template改進Strategy Pattern (OO) (Design Pattern) (C/C++) (template)
在strategy pattern中,為了讓各strategy能方便存取原來物件的所有public member function,我們常用*this將整個物件傳給各strategy,這樣的設計並沒有什麼不好,但各strategy和原物件過於tight coupling,導致各strategy難以再和其他各物件搭配,本文使用template解決此問題。
在(原創) 我的Design Pattern之旅:Strategy Pattern (初級) (Design Pattern) (C++) (OO C++) (Template C++)中,我們使用了strategy pattern讓Grapher能畫Triangle、Circle和Square
因為需求再次改變,:D,我們希望Grapher能將文字印在各Shape中,執行結果如下


為了達到此需求,我們可以將IShape interface改成




但若將來需求再改變,希望畫的不是文字,而是一張圖片,那interface又必須再變動,為了一勞永逸,我們會將整個物件傳給各strategy,IShape interface改成如下




Grapher::drawShpae()將*this傳給各strategy



完整的程式碼如下


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

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

執行結果


這樣的設計看似完美,但IShape和Grapher相依程度太高,若將來有個Painter class,和Grapher完全不同,沒有任何繼承或多型的關係,但想重複使用IShape interface的strategy,這樣的設計就無法讓Painter使用了。若我們能讓IShape interface的draw()不再只限定Grapher型別,改用template,就能讓將來所有型別都能使用IShape interface。





我們用泛型T取代了Grapher,任何型別都可傳進IShape::draw()。
完整程式碼如下


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

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

執行結果


Conclusion
泛型的應用相當廣,在此範例僅僅是泛型的小小應用,在OOP世界使用strategy pattern,常將*this傳給strategy,若搭配GP可讓strategy pattern的resuse程度更高。
See Also
(原創) 我的Design Pattern之旅[1]:Strategy Pattern (初級) (Design Pattern) (C++) (OO C++) (Template C++)
(原創) 我的Design Pattern之旅[4]:使用Generic改進Strategy Pattern (高級) (Design Pattern) (C#) (Generic)