工廠模式族群是創建型模式的基石,解決**「對象創建邏輯與使用邏輯耦合」**的核心問題。本文將三大工廠模式置於同一坐標系,通過**雷鋒案例**、**數據庫訪問案例**雙實戰,揭示其層層遞進的抽象演化邏輯,並給出實戰選型決策表。
簡單工廠 (Simple Factory)
│ 靜態工廠方法、上帝類、違反開閉原則
▼
工廠方法 (Factory Method) ── GOF 正統、多態工廠、符合開閉原則
│ 抽象工廠接口 + 多個具體工廠子類,每個工廠只創建一種產品
▼
抽象工廠 (Abstract Factory) ── 工具箱、產品族、多等級結構
一個工廠接口創建多個相關/依賴產品 (如:椅子+沙發、MySQL User+MySQL Student)
public class LeiFengFactory {
public static LeiFeng createLeiFeng(String type) {
if ("student".equals(type)) return new Student();
if ("volunteer".equals(type)) return new Volunteer();
throw new IllegalArgumentException("未知類型");
}
}
// 客戶端
LeiFeng lf = LeiFengFactory.createLeiFeng("student");
lf.sweep();
// 抽象產品
public abstract class LeiFeng {
public void sweep() { System.out.println("掃地"); }
public void wash() { System.out.println("洗衣服"); }
}
// 具體產品
public class Student extends LeiFeng {}
public class Volunteer extends LeiFeng {}
// 抽象工廠
public interface IFactory {
LeiFeng getLeiFeng();
}
// 具體工廠
public class StudentFactory implements IFactory {
public LeiFeng getLeiFeng() { return new Student(); }
}
public class VolunteerFactory implements IFactory {
public LeiFeng getLeiFeng() { return new Volunteer(); }
}
// 客戶端
IFactory factory = new StudentFactory(); // 或從配置/IOC 獲取
LeiFeng lf = factory.getLeiFeng();
lf.sweep();
系統有**多個產品等級結構** (如:User、Student),且**不同數據庫實現構成產品族** (SqlUser+SqlStudent、AccessUser+AccessStudent)。客戶端需**一次性獲得一族相關產品**。
// 兩個產品等級結構
public interface IUser { void insert(User u); User getUser(int id); }
public interface IStudent { void insert(Student s); Student getStudent(int id); }
// SQL Server 族
public class SqlUser implements IUser { ... }
public class SqlStudent implements IStudent { ... }
// Access 族
public class AccessUser implements IUser { ... }
public class AccessStudent implements IStudent { ... }
// 抽象工廠:定義創建全族產品的契約
public interface IFactory {
IUser createUser();
IStudent createStudent();
}
// 具體工廠:實現族內創建
public class SqlFactory implements IFactory {
public IUser createUser() { return new SqlUser(); }
public IStudent createStudent() { return new SqlStudent(); }
}
public class AccessFactory implements IFactory {
public IUser createUser() { return new AccessUser(); }
public IStudent createStudent() { return new AccessStudent(); }
}
// 客戶端
IFactory factory = new SqlFactory(); // 切換數據庫只需換工廠
IUser userDao = factory.createUser();
IStudent stuDao = factory.createStudent();
userDao.insert(new User());
stuDao.insert(new Student());
位於**不同等級結構中、功能相關聯**的產品組成的家族。如 `SqlUser` + `SqlStudent` 屬於「SQL Server 產品族」。抽象工廠在**類內部約束了族內關聯**,確保客戶端獲得的始終是兼容的一族對象。
| 維度 | 簡單工廠 | 工廠方法 | 抽象工廠 |
|---|---|---|---|
| 產品等級結構數 | 1 | 1 | 多 (≥2) |
| 每個工廠創建產品數 | 多 | 1 | 多 (一族) |
| 開閉原則 | 違反 (修改工廠類) | 符合 (擴展子類) | 符合 (擴展子類) |
| 客戶端耦合度 | 耦合具體工廠類 | 耦合抽象工廠接口 | 耦合抽象工廠接口 |
| 增加新產品等級 | 修改工廠類 | 新增工廠接口方法+所有子類實現 (較麻煩) | 同工廠方法 |
| 典型應用 | JDK Calendar.getInstance()、數據庫連接池獲取連接 | JDBC DriverManager、集合迭代器、文檔構建器 | UI 皮膚庫、跨平台 GUI、數據庫多廠商適配 |
「工廠方法加個方法變抽象工廠,抽象工廠減個方法變工廠方法。」
實戰中**不必糾結名稱**,核心目標只有一個:**降低創建與使用的耦合度**。靈活組合:工廠方法創建單品、抽象工廠組裝族、簡單工廠封裝邏輯、依賴注入容器管理工廠實例生命週期。
三大工廠模式是**抽象層級遞增**的演化鏈:
掌握其**核心結構差異 (產品等級數、工廠創建數)、擴展痛點 (新增產品 vs 新增等級)、實戰適用邊界**,即可在架構設計中精準落子,避免過度設計與不足設計。