4. 工厂模式实现数据库连接

任务说明

本案例要求使用工厂模式设计一个数据库连接创建模块,支持MySQL和PostgreSQL两种类型。调用方只需传入数据库类型标识,即可获得对应的连接对象,无需感知具体连接类的实例化过程。核心目标是:将连接对象的创建逻辑集中管理,隐藏具体实现细节,为后续扩展其他数据库类型提供统一入口。

代码实现

# db_factory.py
from abc import ABC, abstractmethod

class DatabaseConnection(ABC):
    """数据库连接抽象基类"""
    @abstractmethod
    def connect(self) -> str:
        pass

    @abstractmethod
    def close(self) -> str:
        pass

class MySQLConnection(DatabaseConnection):
    """MySQL连接实现"""
    def __init__(self, host: str, port: int, user: str, password: str, dbname: str):
        self.host = host
        self.port = port
        self.user = user
        self.password = password
        self.dbname = dbname
        self._connected = False

    def connect(self) -> str:
        self._connected = True
        return f"MySQL连接已建立: {self.user}@{self.host}:{self.port}/{self.dbname}"

    def close(self) -> str:
        self._connected = False
        return "MySQL连接已关闭"

class PostgreSQLConnection(DatabaseConnection):
    """PostgreSQL连接实现"""
    def __init__(self, host: str, port: int, user: str, password: str, dbname: str):
        self.host = host
        self.port = port
        self.user = user
        self.password = password
        self.dbname = dbname
        self._connected = False

    def connect(self) -> str:
        self._connected = True
        return f"PostgreSQL连接已建立: {self.user}@{self.host}:{self.port}/{self.dbname}"

    def close(self) -> str:
        self._connected = False
        return "PostgreSQL连接已关闭"

class DatabaseFactory:
    """数据库连接工厂"""
    @staticmethod
    def create(db_type: str, **kwargs) -> DatabaseConnection:
        """
        根据类型创建数据库连接
        :param db_type: 'mysql' 或 'postgresql'
        :param kwargs: host, port, user, password, dbname
        :return: DatabaseConnection 实例
        :raises ValueError: 不支持的数据库类型
        """
        db_type = db_type.lower().strip()
        if db_type == 'mysql':
            return MySQLConnection(**kwargs)
        elif db_type == 'postgresql':
            return PostgreSQLConnection(**kwargs)
        else:
            raise ValueError(f"不支持的数据库类型: {db_type},仅支持 'mysql' 和 'postgresql'")

调用示例

# usage.py
from db_factory import DatabaseFactory

# 创建MySQL连接
mysql_conn = DatabaseFactory.create(
    'mysql',
    host='192.168.1.10',
    port=3306,
    user='app_user',
    password='secret',
    dbname='orders'
)
print(mysql_conn.connect())
print(mysql_conn.close())

# 创建PostgreSQL连接
pg_conn = DatabaseFactory.create(
    'postgresql',
    host='192.168.1.20',
    port=5432,
    user='admin',
    password='admin123',
    dbname='analytics'
)
print(pg_conn.connect())
print(pg_conn.close())

# 测试非法类型
try:
    DatabaseFactory.create('oracle', host='x', port=1, user='u', password='p', dbname='d')
except ValueError as e:
    print(f"错误: {e}")

工厂模式结构

客户端 调用方 DatabaseFactory create(db_type, **kwargs) DatabaseConnection «interface» MySQLConnection connect() / close() PostgreSQLConnection connect() / close() 调用 依赖 实现 实现 工厂模式:创建逻辑集中,客户端不直接实例化具体连接类

运行与验证

运行方式:将上述两个代码块分别保存为 db_factory.py 和 usage.py,在相同目录下执行:

python usage.py

预期输出:

MySQL连接已建立: app_user@192.168.1.10:3306/orders
MySQL连接已关闭
PostgreSQL连接已建立: admin@192.168.1.20:5432/analytics
PostgreSQL连接已关闭
错误: 不支持的数据库类型: oracle,仅支持 'mysql' 和 'postgresql'

判定标准:

  1. 程序无异常退出,三行输出与上述预期完全一致;
  2. 调用方代码中未出现 MySQLConnection 或 PostgreSQLConnection 的直接实例化,仅通过 DatabaseFactory.create() 获取对象;
  3. 传入 'oracle' 时抛出 ValueError,说明工厂对非法类型有明确拦截;
  4. 新增数据库类型时,只需在工厂中增加一个分支并新建对应连接类,调用方代码无需修改——这是工厂模式的核心收益。