定義
工廠模式可分爲三類:
- 簡單工廠模式
- 工廠方法模式
- 抽象工廠模式
簡單工廠模式
屬於創建型模式,不屬於 23 種 GOF 設計模式之一,由一個工廠對象決定創建出哪一種產品類實例,邏輯爲定義一個工廠類,根據傳入的參數不同返回不同的產品實例,被創建的實例具有共同的父類或接口。
工廠方法模式
跟簡單工廠模式的區別就是,定義了一些工廠子類,每個工廠子類都可以創建相對應的產品類實例,而不用工廠父類去根據參數創建,一般在產品類比較多的情況下,不想太多複雜的邏輯封裝在工廠父類裏面,可以用這種模式。
抽象工廠模式
顧名思義,把工廠抽象出來,根據具體的業務需求組合工廠創建產品實例的邏輯,通常爲創建多個產品實例類。抽象工廠一旦要增加創建產品實例的邏輯,就需要修改抽象工廠接口的具體產品組合邏輯,所以並不符合開閉原則,如果是需要頻繁增加(修改)產品實例的話,要衡量是否採用這種模式
基本結構
工廠模式從源碼上總的來說可以分爲 4 部分:
抽象產品: 通過聲明接口(特性),定義了產品的業務方法。
具體產品: 通過 implement 接口(特性),定義了業務方法的具體邏輯。
抽象工廠: 按照相應的業務邏輯,聲明瞭創建產品對象的業務方法(多數爲組合方式)。
具體工廠: 通過 implement 接口(特性),定義了創建產品對象的具體邏輯。
結構設計的關鍵點:
- 產品只負責產品對象的創建,其他什麼都不關心, 也與其他的產品不會產生任何業務邏輯上的關聯
- 工廠要根據具體的業務需求去決定是否需要抽象,不要爲抽象而抽象,抽象出工廠是爲了更優雅的源碼結構
適用場景
- 需要統一的邏輯來創建產品實例
- 各種產品實例創建邏輯很接近
- 不用關心產品實例的創建過程
- 需要有統一的入口去聯動產品的創建
- 抽象工廠模式不符合開閉原則,故不適應於需要頻繁增加(修改)產品的場景
如以上內容有不對之處請指導修正,謝謝。
範例代碼
源碼地址: https://github.com/halokid/rust-cookbook/tree/master/design_patterns/factory
trait Product {
fn convert(&self, _: String) -> String;
}
trait Factory {
fn create_product(&self) -> Box<dyn Product>;
fn convert(&self, s: String) -> String {
self.create_product().convert(s)
}
}
struct ProductX;
impl Product for ProductX {
fn convert(&self, s: String) -> String {
println!("ProductX convert: {}", s.to_uppercase());
return s.to_uppercase()
}
}
struct ProductY;
impl Product for ProductY {
fn convert(&self, s: String) -> String {
println!("ProductY convert: {}", s.to_lowercase());
return s.to_lowercase()
}
}
struct FactoryAll;
impl Factory for FactoryAll{
fn create_product(&self) -> Box<dyn Product> {
Box::new(ProductY) as Box<dyn Product>
}
}
fn main() {
let f = FactoryAll;
println!("{}", f.convert("HaloKid".to_string()))
}