在軟件設(shè)計(jì)模式的學(xué)習(xí)中,創(chuàng)建型模式是構(gòu)建靈活、可復(fù)用代碼的基石。本文基于 wsndbbhh 的 CSDN 博客《數(shù)據(jù)庫(kù)及計(jì)算機(jī)網(wǎng)絡(luò)服務(wù)》中的相關(guān)筆記,對(duì)簡(jiǎn)單工廠模式(Simple Factory Pattern)及其變體——靜態(tài)工廠方法模式(Static Factory Method Pattern)進(jìn)行梳理與探討,并分析其在數(shù)據(jù)庫(kù)連接、網(wǎng)絡(luò)服務(wù)等場(chǎng)景中的應(yīng)用價(jià)值。
一、核心概念解析
1. 簡(jiǎn)單工廠模式
簡(jiǎn)單工廠模式,又稱靜態(tài)工廠方法模式(注意:此處的“靜態(tài)”指方法為靜態(tài),但嚴(yán)格來(lái)說(shuō)它與“靜態(tài)工廠方法模式”在概念上存在細(xì)微差別,下文會(huì)詳述),它不屬于 GoF 23 種設(shè)計(jì)模式之一,而是一種編程習(xí)慣或基礎(chǔ)模式。其核心思想是:定義一個(gè)工廠類,根據(jù)傳入的參數(shù),動(dòng)態(tài)決定創(chuàng)建哪一種產(chǎn)品類的實(shí)例。
- 角色:
- 工廠角色:負(fù)責(zé)創(chuàng)建所有實(shí)例的邏輯,包含判斷與實(shí)例化代碼。
- 抽象產(chǎn)品角色:所有具體產(chǎn)品的父類或接口,定義了產(chǎn)品的公共方法。
- 具體產(chǎn)品角色:工廠創(chuàng)建的目標(biāo)對(duì)象,實(shí)現(xiàn)了抽象產(chǎn)品接口。
- 優(yōu)點(diǎn):
- 封裝創(chuàng)建邏輯:將對(duì)象的創(chuàng)建與使用分離,客戶端無(wú)需關(guān)心對(duì)象的具體構(gòu)建細(xì)節(jié)。
- 集中化管理:新增產(chǎn)品類型時(shí),只需修改工廠類,符合“開(kāi)閉原則”的一部分(對(duì)擴(kuò)展開(kāi)放,但對(duì)修改不完全封閉)。
- 缺點(diǎn):
- 工廠職責(zé)過(guò)重:隨著產(chǎn)品種類增加,工廠方法會(huì)變得臃腫(例如,龐大的
switch或if-else語(yǔ)句)。
- 不符合開(kāi)閉原則:增加新產(chǎn)品必須修改工廠類的邏輯。
2. 靜態(tài)工廠方法模式
靜態(tài)工廠方法模式,特指通過(guò)類的靜態(tài)方法來(lái)創(chuàng)建對(duì)象,而不直接暴露構(gòu)造函數(shù)。這是對(duì)簡(jiǎn)單工廠模式的一種常見(jiàn)實(shí)現(xiàn)方式,也常見(jiàn)于 JDK(如 Integer.valueOf(int))及眾多工具類中。
- 與簡(jiǎn)單工廠的關(guān)聯(lián)與區(qū)別:
- 簡(jiǎn)單工廠模式強(qiáng)調(diào)的是“由一個(gè)工廠類負(fù)責(zé)所有產(chǎn)品的創(chuàng)建”,這個(gè)工廠類本身可能通過(guò)實(shí)例方法或靜態(tài)方法實(shí)現(xiàn)。
- 靜態(tài)工廠方法模式強(qiáng)調(diào)的是“創(chuàng)建方法本身是靜態(tài)的”,它可能分散在各個(gè)產(chǎn)品類或工具類中,不一定會(huì)集中在一個(gè)工廠類里。
- 在實(shí)踐中,我們常說(shuō)的“簡(jiǎn)單工廠”經(jīng)常用靜態(tài)工廠方法來(lái)實(shí)現(xiàn),因此兩者常被混用,但側(cè)重點(diǎn)不同。
- 優(yōu)點(diǎn):
- 方法名可讀性強(qiáng):靜態(tài)方法可以有意義的名稱(如
createConnection,getInstance),比直接調(diào)用構(gòu)造函數(shù)更清晰。
- 可以控制實(shí)例:可以實(shí)現(xiàn)緩存、單例、返回子類等靈活控制,隱藏實(shí)現(xiàn)細(xì)節(jié)。
- 減少API復(fù)雜度:對(duì)于構(gòu)造函數(shù)復(fù)雜的類,提供簡(jiǎn)化的創(chuàng)建入口。
二、在數(shù)據(jù)庫(kù)與網(wǎng)絡(luò)服務(wù)中的應(yīng)用示例
以 wsndbbhh 博客中提到的場(chǎng)景為例,數(shù)據(jù)庫(kù)連接和網(wǎng)絡(luò)服務(wù)客戶端都是典型的、需要根據(jù)不同配置或類型創(chuàng)建不同實(shí)現(xiàn)的對(duì)象。
場(chǎng)景一:數(shù)據(jù)庫(kù)連接工廠
假設(shè)系統(tǒng)需要支持 MySQL、PostgreSQL 和 Oracle 三種數(shù)據(jù)庫(kù)。我們可以定義一個(gè) IDatabaseConnection 接口,并為每種數(shù)據(jù)庫(kù)實(shí)現(xiàn)具體的連接類。使用簡(jiǎn)單工廠模式,可以創(chuàng)建一個(gè) DatabaseConnectionFactory:
`java
// 抽象產(chǎn)品
public interface IDatabaseConnection {
void connect();
void executeQuery(String sql);
}
// 具體產(chǎn)品
public class MySQLConnection implements IDatabaseConnection { / 實(shí)現(xiàn)細(xì)節(jié) / }
public class PostgreSQLConnection implements IDatabaseConnection { / 實(shí)現(xiàn)細(xì)節(jié) / }
// 簡(jiǎn)單工廠(使用靜態(tài)方法)
public class DatabaseConnectionFactory {
public static IDatabaseConnection createConnection(String dbType) {
switch (dbType.toLowerCase()) {
case "mysql":
return new MySQLConnection();
case "postgresql":
return new PostgreSQLConnection();
// 可以方便地?cái)U(kuò)展新的數(shù)據(jù)庫(kù)類型,但需要修改此處代碼
default:
throw new IllegalArgumentException("Unsupported database type: " + dbType);
}
}
}
// 客戶端使用
public class Client {
public void operateDatabase() {
IDatabaseConnection conn = DatabaseConnectionFactory.createConnection("mysql");
conn.connect();
// ... 其他操作
}
}`
場(chǎng)景二:網(wǎng)絡(luò)服務(wù)客戶端工廠
對(duì)于不同的網(wǎng)絡(luò)協(xié)議(如 HTTP、WebSocket、gRPC),我們可以創(chuàng)建統(tǒng)一的客戶端接口,并使用靜態(tài)工廠方法提供創(chuàng)建入口。
`java
// 抽象產(chǎn)品
public interface INetworkClient {
void sendRequest(String data);
String receiveResponse();
}
// 具體產(chǎn)品
public class HttpClient implements INetworkClient { / 實(shí)現(xiàn) / }
public class WebSocketClient implements INetworkClient { / 實(shí)現(xiàn) / }
// 使用靜態(tài)工廠方法模式(工廠邏輯可能更分散或集成在配置中)
public class NetworkClientFactory {
// 靜態(tài)工廠方法
public static INetworkClient createClient(Protocol protocol) {
if (protocol == Protocol.HTTP) {
return new HttpClient();
} else if (protocol == Protocol.WEBSOCKET) {
return new WebSocketClient();
}
throw new IllegalArgumentException("Unsupported protocol");
}
}
public enum Protocol {
HTTP, WEBSOCKET, GRPC
}`
三、模式對(duì)比與演進(jìn)
簡(jiǎn)單工廠/靜態(tài)工廠方法模式非常適合在以下情況使用:
- 對(duì)象創(chuàng)建邏輯相對(duì)簡(jiǎn)單,產(chǎn)品類型數(shù)量有限且穩(wěn)定。
- 需要集中管理創(chuàng)建邏輯,例如在數(shù)據(jù)庫(kù)連接池初始化、根據(jù)配置選擇不同實(shí)現(xiàn)時(shí)。
- 希望隱藏具體實(shí)現(xiàn)類,為客戶端提供統(tǒng)一的接口。
正如其缺點(diǎn)所示,當(dāng)系統(tǒng)需要頻繁擴(kuò)展新的產(chǎn)品類型時(shí),持續(xù)修改工廠類會(huì)成為維護(hù)負(fù)擔(dān)。此時(shí),可以考慮演進(jìn)到更靈活的 工廠方法模式(每個(gè)產(chǎn)品對(duì)應(yīng)一個(gè)工廠)或 抽象工廠模式(創(chuàng)建產(chǎn)品族)。
四、
簡(jiǎn)單工廠模式與靜態(tài)工廠方法模式是理解更復(fù)雜工廠模式的基礎(chǔ)。它們?cè)跀?shù)據(jù)庫(kù)驅(qū)動(dòng)加載、網(wǎng)絡(luò)服務(wù)適配、日志記錄器選擇等底層服務(wù)中廣泛應(yīng)用,通過(guò)將“創(chuàng)建”與“使用”解耦,提升了代碼的模塊化和可維護(hù)性。
學(xué)習(xí)時(shí),應(yīng)重點(diǎn)掌握:
- 識(shí)別出需要使用該模式的場(chǎng)景——即存在一組同族或同接口的產(chǎn)品,需要根據(jù)條件動(dòng)態(tài)創(chuàng)建。
- 理解其優(yōu)缺點(diǎn),明確它只是設(shè)計(jì)模式旅程的起點(diǎn),而非終點(diǎn)。
- 結(jié)合具體技術(shù)(如 JDBC 的
DriverManager.getConnection()本質(zhì)上也是一種工廠模式的應(yīng)用)加深理解。
通過(guò)將理論應(yīng)用于像數(shù)據(jù)庫(kù)和網(wǎng)絡(luò)服務(wù)這樣的實(shí)際組件開(kāi)發(fā)中,我們能更深刻地體會(huì)到設(shè)計(jì)模式如何優(yōu)雅地解決常見(jiàn)的軟件設(shè)計(jì)問(wèn)題,構(gòu)建出更健壯、更易擴(kuò)展的系統(tǒng)。