以同一個介面來建立一整族相關或相依的物件,不需要點明個物件真正所屬的具象類別。
class AbstractFactory
def create_product_a
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
end
def create_product_b
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
end
end
class ConcreteFactory1 < AbstractFactory
def create_product_a
ConcreteProductA1.new
end
def create_product_b
ConcreteProductB1.new
end
end
class ConcreteFactory2 < AbstractFactory
def create_product_a
ConcreteProductA2.new
end
def create_product_b
ConcreteProductB2.new
end
end
class AbstractProductA
def useful_function_a
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
end
end
class ConcreteProductA1 < AbstractProductA
def useful_function_a
'The result of the product A1.'
end
end
class ConcreteProductA2 < AbstractProductA
def useful_function_a
'The result of the product A2.'
end
end
class AbstractProductB
def useful_function_b
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
end
def another_useful_function_b(_collaborator)
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
end
end
class ConcreteProductB1 < AbstractProductB
def useful_function_b
'The result of the product B1.'
end
def another_useful_function_b(collaborator)
result = collaborator.useful_function_a
"The result of the B1 collaborating with the (#{result})"
end
end
class ConcreteProductB2 < AbstractProductB
def useful_function_b
'The result of the product B2.'
end
def another_useful_function_b(collaborator)
result = collaborator.useful_function_a
"The result of the B2 collaborating with the (#{result})"
end
end
def client_code(factory)
product_a = factory.create_product_a
product_b = factory.create_product_b
puts product_b.useful_function_b.to_s
puts product_b.another_useful_function_b(product_a).to_s
end
puts 'Client: Testing client code with the first factory type:'
client_code(ConcreteFactory1.new)
puts "\n"
puts 'Client: Testing the same client code with the second factory type:'
client_code(ConcreteFactory2.new)
Client: Testing client code with the first factory type:
The result of the product B1.
The result of the B1 collaborating with the (The result of the product A1.)
Client: Testing the same client code with the second factory type:
The result of the product B2.
The result of the B2 collaborating with the (The result of the product A2.)
在討論整個抽象工廠運作流程以前,最重要的是先了解客戶端如何啟動抽象工廠!
上述的程式碼中的client_code
內所投入的factory
參數,是工廠運作的開始,也是確立哪一個工廠應該開始作用
確認工廠後再來就是確認哪種產品是需要的,所以再來使用create_product_a
或者create_product_b
來製作特定產品
而製造產品的方法內部細節,會額外抽離到ConcreteProduct
的類別之中
最後獲得產品物件後,就可以實踐各個方法
此外Abstract
的部分是宣告抽象介面,利用與Concrete
繼承關係,來讓客戶端知道哪些工廠或者產品可以實作
而Concrete
則是負責實作具象成品(所以客戶端在產生物件時,會直接new
出特定工廠來實作特定產品)
client
端所輸入的是特定工廠,所以確保一系列產品的產出
client
與產品耦合明天又要上班囉,大家早點休息吧~ :)
感謝大家 如有問題,再煩請大家指教!