工廠模式:像點(diǎn)外賣一樣創(chuàng)建對(duì)象
一、生活比喻:你每天都在用“工廠模式”
想象一下點(diǎn)外賣的場(chǎng)景:
graph TD
A[顧客] -->|“我要一份披薩”| B(外賣平臺(tái))
B --> C{判斷需求}
C -->|海鮮披薩| D[海鮮披薩店]
C -->|水果披薩| E[水果披薩店]
D --> F[制作海鮮披薩]
E --> G[制作水果披薩]
F --> H[送達(dá)顧客]
G --> H
關(guān)鍵點(diǎn):
- 你不需要知道披薩具體怎么做
- 你只需要告訴平臺(tái)“要什么類型”
- 平臺(tái)自動(dòng)分配對(duì)應(yīng)的店鋪制作
這恰恰就是工廠模式的核心思想:
將對(duì)象的創(chuàng)建和使用分離,使用者無(wú)需關(guān)心對(duì)象的具體創(chuàng)建細(xì)節(jié)
二、工廠模式三大類型(圖文對(duì)比)
類型1:簡(jiǎn)單工廠模式(外賣平臺(tái)基礎(chǔ)版)
結(jié)構(gòu)圖:`
客戶
↓
[披薩工廠]
/ \
海鮮披薩 水果披薩`
代碼示例:`java
// 1. 定義披薩接口
interface Pizza {
void prepare();
void bake();
}
// 2. 具體披薩實(shí)現(xiàn)
class SeafoodPizza implements Pizza {
public void prepare() {
System.out.println("準(zhǔn)備海鮮材料");
}
public void bake() {
System.out.println("烤制海鮮披薩");
}
}
class FruitPizza implements Pizza {
public void prepare() {
System.out.println("準(zhǔn)備水果材料");
}
public void bake() {
System.out.println("烤制水果披薩");
}
}
// 3. 簡(jiǎn)單工廠
class PizzaFactory {
public static Pizza createPizza(String type) {
if ("seafood".equals(type)) {
return new SeafoodPizza();
} else if ("fruit".equals(type)) {
return new FruitPizza();
}
return null;
}
}
// 4. 客戶使用
public class Customer {
public static void main(String[] args) {
// 就像點(diǎn)外賣,只需要說(shuō)“要海鮮披薩”
Pizza pizza = PizzaFactory.createPizza("seafood");
pizza.prepare();
pizza.bake();
}
}`
優(yōu)點(diǎn):簡(jiǎn)單直接,適合類型不多的情況
缺點(diǎn):新增披薩類型需要修改工廠類,違反開(kāi)閉原則
類型2:工廠方法模式(品牌專賣店)
結(jié)構(gòu)圖:`
[披薩店接口]
↑
_
| |
海鮮披薩店 水果披薩店
| |
海鮮披薩 水果披薩`
代碼示例:`java
// 1. 抽象工廠接口
interface PizzaStore {
Pizza createPizza(); // 工廠方法
}
// 2. 具體工廠
class SeafoodPizzaStore implements PizzaStore {
public Pizza createPizza() {
return new SeafoodPizza(); // 專做海鮮披薩
}
}
class FruitPizzaStore implements PizzaStore {
public Pizza createPizza() {
return new FruitPizza(); // 專做水果披薩
}
}
// 3. 客戶使用
public class Customer {
public static void main(String[] args) {
// 選擇海鮮披薩店
PizzaStore store = new SeafoodPizzaStore();
Pizza pizza = store.createPizza(); // 自動(dòng)得到海鮮披薩
pizza.prepare();
pizza.bake();
}
}`
優(yōu)點(diǎn):
- 符合開(kāi)閉原則,新增產(chǎn)品只需新增工廠
- 每個(gè)工廠職責(zé)單一
適用場(chǎng)景:
- 不同品牌有自己專屬的產(chǎn)品線
- 需要?jiǎng)?chuàng)建的對(duì)象類型會(huì)不斷擴(kuò)展
類型3:抽象工廠模式(連鎖餐飲集團(tuán))
現(xiàn)實(shí)比喻:
- 麥當(dāng)勞:生產(chǎn)漢堡 + 薯?xiàng)l + 可樂(lè)(一套美式快餐)
- 肯德基:生產(chǎn)漢堡 + 蛋撻 + 奶茶(一套中式快餐)
結(jié)構(gòu)圖:`
[快餐工廠接口]
/ \
漢堡接口 飲品接口
↑ ↑
麥當(dāng)勞工廠 肯德基工廠
| |
麥當(dāng)勞漢堡 肯德基漢堡
麥當(dāng)勞可樂(lè) 肯德基奶茶`
代碼示例:`java
// 1. 抽象產(chǎn)品族
interface Hamburger {
void eat();
}
interface Drink {
void drink();
}
// 2. 具體產(chǎn)品
class McDonaldHamburger implements Hamburger {
public void eat() {
System.out.println("吃麥當(dāng)勞漢堡");
}
}
class KFCHamburger implements Hamburger {
public void eat() {
System.out.println("吃肯德基漢堡");
}
}
class CocaCola implements Drink {
public void drink() {
System.out.println("喝可口可樂(lè)");
}
}
class MilkTea implements Drink {
public void drink() {
System.out.println("喝奶茶");
}
}
// 3. 抽象工廠(生產(chǎn)一套產(chǎn)品)
interface FastFoodFactory {
Hamburger createHamburger();
Drink createDrink();
}
// 4. 具體工廠
class McDonaldFactory implements FastFoodFactory {
public Hamburger createHamburger() {
return new McDonaldHamburger();
}
public Drink createDrink() {
return new CocaCola(); // 固定搭配可樂(lè)
}
}
class KCFactory implements FastFoodFactory {
public Hamburger createHamburger() {
return new KFCHamburger();
}
public Drink createDrink() {
return new MilkTea(); // 固定搭配奶茶
}
}
// 5. 客戶使用
public class Customer {
public static void main(String[] args) {
// 選擇麥當(dāng)勞套餐
FastFoodFactory factory = new McDonaldFactory();
Hamburger burger = factory.createHamburger();
Drink drink = factory.createDrink();
burger.eat(); // 輸出:吃麥當(dāng)勞漢堡
drink.drink(); // 輸出:喝可口可樂(lè)
}
}`
核心特點(diǎn):
- 創(chuàng)建的是產(chǎn)品族(一組相關(guān)產(chǎn)品)
- 保證產(chǎn)品之間的兼容性(麥當(dāng)勞不會(huì)配奶茶)
適用場(chǎng)景:
- 系統(tǒng)需要一系列相關(guān)的產(chǎn)品
- 需要確保產(chǎn)品之間的兼容性
- 產(chǎn)品族需要整體替換
三、快速選擇指南(決策樹(shù))
開(kāi)始選擇工廠模式
↓
需要?jiǎng)?chuàng)建單個(gè)對(duì)象嗎?
├── 是 → 對(duì)象類型固定且少嗎?
│ ├── 是 → 使用簡(jiǎn)單工廠
│ └── 否 → 使用工廠方法
│
└── 否 → 需要?jiǎng)?chuàng)建一組相關(guān)對(duì)象嗎?
├── 是 → 使用抽象工廠
└── 否 → 重新分析需求
四、真實(shí)應(yīng)用場(chǎng)景
Spring框架中的工廠模式
// Spring的BeanFactory就是工廠模式的典型應(yīng)用
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService) context.getBean("userService");
// 你不用new UserService(),由Spring工廠創(chuàng)建和管理
JDK中的工廠模式
Calendar.getInstance():根據(jù)時(shí)區(qū)創(chuàng)建日歷對(duì)象NumberFormat.getInstance():創(chuàng)建數(shù)字格式化對(duì)象
五、核心思想
- 封裝變化:將對(duì)象創(chuàng)建的變化封裝在工廠中
- 解耦:使用者與具體產(chǎn)品類解耦
- 單一職責(zé):工廠只負(fù)責(zé)創(chuàng)建,產(chǎn)品只負(fù)責(zé)功能
- 開(kāi)閉原則:對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉
記住這個(gè)口訣:
“不要自己new,找工廠要;
要什么產(chǎn)品,給什么參數(shù);
工廠怎么造,你不用管。”
工廠模式就像現(xiàn)實(shí)生活中的“制造商-消費(fèi)者”關(guān)系,讓代碼更靈活、更易維護(hù)!