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