## 36.策略模式
無論你是否意識到自己是一名出色的戰略家。 早上醒來時,你會去喝咖啡,如果沒有咖啡粉,你可能會喝杯茶或熱巧克力或牛奶。 你開車去上班或上學,如果某條路受阻,則采取另一種方式。 在工作中,你需要考慮向老板呈現的方式,是否使老板心情愉快的方式,以便你可以談論事實或掩蓋事實。 策略無處不在,你只是沒有注意到它。 你每次都會根據環境 <sup class="footnote">[ [68](#_footnotedef_68 "View footnote.") ]</sup> 不斷采用新策略。
在計算世界中,如果我們能夠根據傳遞的標志/參數告訴一段代碼動態運行不同的算法,則這種編碼稱為策略模式。 讓我們看下面的示例 [strategy_pattern.rb](code/design_patterns/strategy_pattern.rb) :
```rb
```
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
```rb
|
```
# strategy_pattern.rb
module NewsFormatter
class Text
def self.format(data)
seperator = "\n* "
seperator + data.join(seperator)
end
end
class HTML
def self.format(data)
html = []
html << "<ul>"
data.each { |datum| html << "<li>#{datum}</li>" }
html << "</ul>"
html.join "\n"
end
end
end
class NewsGenerator
def self.generate(data, formatter)
formatter.format(data)
end
end
news = [
"You are reading I Love Ruby.",
"There is water down below in the oceans.",
"There is air up above our heads.",
"Even people in space report their is air up above their heads.",
"Even bald people have air up above their heads."
]
puts "News As HTML:"
puts "\n"
puts NewsGenerator.generate(news, NewsFormatter::HTML)
puts "\n\n"
puts "News As Text:"
puts "\n"
puts NewsGenerator.generate(news, NewsFormatter::Text)
puts "\n\n"
```rb
|
```
輸入并執行
輸出量
```rb
News As HTML:
<ul>
<li>You are reading I Love Ruby.</li>
<li>There is water down below in the oceans.</li>
<li>There is air up above our heads.</li>
<li>Even people in space report their is air up above their heads.</li>
<li>Even bald people have air up above their heads.</li>
</ul>
News As Text:
* You are reading I Love Ruby.
* There is water down below in the oceans.
* There is air up above our heads.
* Even people in space report their is air up above their heads.
* Even bald people have air up above their heads.
```
現在讓我們分析代碼。 查看以下幾行(29-35):
```rb
news = [
"You are reading I Love Ruby.",
"There is water down below in the oceans.",
"There is air up above our heads.",
"Even people in space report their is air up above their heads.",
"Even bald people have air up above their heads."
]
```
在這里,我們聲明一個名為`news`的數組,并在其中填充新聞項。
然后在第 39 行中,有以下語句`puts NewsGenerator.generate(news, NewsFormatter::HTML)`,其輸出如下:
```rb
<ul>
<li>You are reading I Love Ruby.</li>
<li>There is water down below in the oceans.</li>
<li>There is air up above our heads.</li>
<li>Even people in space report their is air up above their heads.</li>
<li>Even bald people have air up above their heads.</li>
</ul>
```
注意,對于`NewsGenerator`類中的`generate`方法,我們提供了兩個參數作為輸入,第一個是數據,在這種情況下,數據是`news`數組,其中包含新聞列表。 下一個參數是`NewsFormatter::HTML`,這是打印時要遵循的策略。
現在看第 24 行的 generate 方法,它看起來像這樣:
```rb
def self.generate(data, formatter)
formatter.format(data)
end
```
在這里,我們將`formatter`作為第二個參數,即本例中的`NewsFormatter::HTML`,并將其傳遞給`data`作為參數,從而對其調用`format`方法。 因此,程序控制轉到第 12 行,該行位于模塊`NewsFormatter`內,并進入類`HTML`中的方法`self.format`中,你可以在此處看到代碼段
```rb
module NewsFormatter
....
class HTML
def self.format(data)
html = []
html << "<ul>"
data.each { |datum| html << "<li>#{datum}</li>" }
html << "</ul>"
html.join "\n"
end
end
end
```
在該函數中,我們神奇地將其轉換為 HTML 無序列表 <sup class="footnote">[ [69](#_footnotedef_69 "View footnote.") ]</sup> ,然后將其返回。
當我們調用`puts NewsGenerator.generate(news, NewsFormatter::Text)`時,會發生相同的事情,但是由于我們通過了不同的策略`NewsFormatter::Text`,因此這段代碼得以執行:
```rb
module NewsFormatter
class Text
def self.format(data)
seperator = "\n* "
seperator + data.join(seperator)
end
end
....
end
```
那就是調用了模塊`NewsFormatter`中類`Text`中的函數`self.format`,該函數會產生純文本輸出,如項目符號,因此你將看到以下輸出:
```rb
* You are reading I Love Ruby.
* There is water down below in the oceans.
* There is air up above our heads.
* Even people in space report their is air up above their heads.
* Even bald people have air up above their heads.
```
- 前言
- 紅寶石
- 先決條件
- 1.安裝 Ruby
- 2.在線資源
- 3.入門
- 4.比較與邏輯
- 5.循環
- 6.數組
- 7.哈希和符號
- 8.范圍
- 9.功能
- 10.可變范圍
- 11.類&對象
- 12.安全導航
- 13.打破大型程序
- 14.結構和 OpenStruct
- 15. Rdoc
- 16. Ruby 樣式指南
- 17.模塊和混入
- 18.日期和時間
- 19.文件
- 20. Proc,Lambda 和塊
- 21.多線程
- 22.異常處理
- 23.正則表達式
- 24.寶石
- 25.元編程
- 26.基準
- 27.測試驅動開發
- 28.觀察者模式
- 29.模板模式
- 30.工廠模式
- 31.裝飾圖案
- 32.適配器模式
- 33.單例模式
- 34.復合模式
- 35.建造者模式
- 36.策略模式
- 贊助商
- 捐
- 人們怎么說
- 版權
- 取得這本書