You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为需实例化的类实现依赖倒置与接口隔离原则?

解决Clean Architecture中依赖倒置的Python实现方案

核心思路是通过依赖注入+工厂模式,把具体类的实例化逻辑从业务代码(main)中彻底剥离,让main只依赖抽象接口,完全不感知具体实现类的存在,完美契合Clean Architecture和依赖倒置原则的要求。

1. 分层拆分模块

先按Clean Architecture的分层逻辑拆分代码结构:

  • 抽象层:定义业务逻辑依赖的接口
  • 基础设施层:实现具体功能(比如API调用)
  • 工厂层:负责实例化具体类,作为抽象层和实现层的中间桥梁
  • 业务逻辑层(main):只依赖抽象接口和工厂

2. 代码实现细节

2.1 抽象接口定义(业务规则层)

创建abstractions/stock_readers.py,用Python的抽象基类(ABC)定义标准接口:

from abc import ABC, abstractmethod
from typing import Optional

class StockPriceReader(ABC):
    @abstractmethod
    def get_price(self, stock_symbol: str) -> Optional[float]:
        """获取指定股票价格,返回None表示获取失败"""
        pass

2.2 具体实现类(基础设施层)

创建infrastructure/tick_reader.py,实现抽象接口,包含API凭证等内部细节:

from abstractions.stock_readers import StockPriceReader
import requests

class TickReaderConcrete(StockPriceReader):
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://api.example-stock-data.com/v1/price"

    def get_price(self, stock_symbol: str) -> Optional[float]:
        try:
            response = requests.get(
                self.base_url,
                params={"symbol": stock_symbol, "apikey": self.api_key}
            )
            response.raise_for_status()
            return response.json().get("price")
        except requests.exceptions.RequestException:
            return None

2.3 工厂函数(依赖注入桥梁)

创建factories/stock_reader_factory.py,负责读取配置并实例化具体类,把实例化逻辑从main中抽离:

from abstractions.stock_readers import StockPriceReader
from infrastructure.tick_reader import TickReaderConcrete
import os

def create_stock_price_reader() -> StockPriceReader:
    # 从环境变量读取API凭证,避免硬编码
    api_key = os.getenv("STOCK_API_KEY")
    if not api_key:
        raise ValueError("请配置STOCK_API_KEY环境变量")
    return TickReaderConcrete(api_key=api_key)

2.4 业务逻辑(main模块)

main.py里只依赖抽象接口和工厂函数,完全不知道TickReaderConcrete的存在:

from abstractions.stock_readers import StockPriceReader
from factories.stock_reader_factory import create_stock_price_reader

def main():
    # 通过工厂获取接口实例,无需关心具体实现
    reader: StockPriceReader = create_stock_price_reader()
    
    stock_symbol = input("请输入股票代码:")
    price = reader.get_price(stock_symbol)
    
    if price:
        print(f"{stock_symbol} 当前价格:{price:.2f}")
    else:
        print(f"无法获取{stock_symbol}的价格数据")

if __name__ == "__main__":
    main()

3. 为什么符合要求?

  • 依赖倒置原则:main(高层模块)依赖抽象接口,具体实现类(低层模块)也依赖同一个抽象,彻底打破了高层依赖低层的传统关系。
  • Clean Architecture分层:抽象接口属于内层业务规则,具体实现属于外层基础设施,工厂作为中间层连接内外,符合内层不依赖外层的核心规则。
  • 可扩展性:如果后续要替换数据源(比如换API、读本地文件),只需要新增一个StockPriceReader的实现类,修改工厂函数的返回逻辑即可,main模块完全不用动。

内容的提问来源于stack exchange,提问作者Della

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 18:57:53