## 32.適配器模式
適配器模式是一種可以適應各種需求的類。 假設我們有一個名為`Animal`的類,并且根據它必須適應的方式,如果它需要像狗一樣表現,則需要說“ woof!”; 如果它需要表現得像只貓,則必須說“喵!” 等等。 然后我們可以編寫如下代碼:
```rb
# without_adapter.rb
class Animal
def speak(kind)
puts case kind
when :dog then "woof!"
when :cat then "meow!"
when :owl then "hoo!"
end
end
end
Animal.new.speak(:dog)
```
輸出量
```rb
woof!
```
但是深思熟慮,這段代碼好嗎? 每次我需要使這種動物表現得像新動物一樣,我需要更改`Animal`類。 如果我編寫了`Animal`類,可以在不更改其原始代碼的情況下更改其行為,該怎么辦? 歡迎使用適配器模式。
現在看下面的代碼 [animal.rb](code/design_patterns/animal.rb) 。 現在讓我不解釋它,而是跳到其實現
```rb
# animal.rb
class Animal
module Adapter
module Dog
def self.speak
puts "woof!"
end
end
module Cat
def self.speak
puts "meow!"
end
end
end
def speak
self.adapter.speak
end
def adapter
return @adapter if @adapter
self.adapter = :dog
@adapter
end
def adapter=(adapter)
@adapter = Animal::Adapter.const_get(adapter.to_s.capitalize)
end
end
```
因此,在下面的程序 [adapter.rb](code/design_patterns/adapter.rb) 中,我們使用了在 [animal.rb](code/design_patterns/animal.rb) 中編寫的類`Anaimal`
```rb
# adapter.rb
require_relative "animal.rb"
animal = Animal.new
animal.speak
animal.adapter = :cat
animal.speak
```
Output
```rb
woof!
meow!
```
在這里,我們首先調用`animal.speak`并在其上打印`woof!`,然后通過命令`animal.adapter = :cat`告訴它像貓一樣適應,然后再次調用`animal.speak`并在其上打印`meow`。 好吧,這是如何工作的。
現在,讓我們分析 [animal.rb](code/design_patterns/animal.rb) 中的代碼。 這里我們有一個名為`Animal`的類,其中有一個函數來設置適配器,如下所示
```rb
def adapter=(adapter)
@adapter = Animal::Adapter.const_get(adapter.to_s.capitalize)
end
```
當我們將適配器的名稱作為`Symbol`傳遞時,請注意代碼`adapter.to_s.capitalize`,如果我們將其作為`:cat`傳遞,則它將轉換為`Cat`,這只是`Animal::Adapter`中模塊的名稱 ]。 當我們在`Animal::Adapter.const_get(…?.)`<sup class="footnote">[[66](#_footnotedef_66 "View footnote.")]</sup> statement. So we have set the `@adapter`中獲得常數時,這將加載到`@adapter`中。
現在讓我們看一下`Animal`類如何根據我們設置的適配器調用相應的`speak`方法。 假設`@adapter`加載了常量`Animal::Adapter::Cat`,現在該函數
```rb
def adapter
return @adapter if @adapter
self.adapter = :dog
@adapter
end
```
在`return @adapter if @adapter`中返回常量。 因此,在`animal.adapter = :cat`之后的`animal.speak`語句中,它將在`Animal::Adapter::Cat`中加載`speak`函數。 因此,當其被調用時,它返回`meow!`。
現在,以這種方式編碼類別`Animal`的優點是我們可以將其擴展到不同的動物,而無需修改原始類別。 換句話說,可以使其適應新情況。 請參見下面的 [adapter_2.rb](code/design_patterns/adapter_2.rb) 中的代碼。 我們在`Animal::Adapter`中放置了一個名為`Owl`的新模塊,當我們使用`animal.adapter = :cat`將適配器設置為 owl 并調用`animal.speak`時,得到的響應為`hoo!`
```rb
# adapter_2.rb
require_relative "animal.rb"
class Animal
module Adapter
module Owl
def self.speak
puts "hoo!"
end
end
end
end
animal = Animal.new
animal.adapter = :owl
animal.speak
```
Output
```rb
hoo!
```
- 前言
- 紅寶石
- 先決條件
- 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.策略模式
- 贊助商
- 捐
- 人們怎么說
- 版權
- 取得這本書