Python依赖倒置原则的价值:为何使用?未发现其实际优势
依赖倒置原则在Python中的实际价值:从代码对比看优势
你觉得抽象类只是用来防止修改方法名,是因为还没碰到需求扩展的场景。依赖倒置的核心不是语法层面的约束,而是解耦高层模块与低层模块,让两者都依赖抽象契约而非具体实现——这个价值在功能迭代时会立刻凸显。
无依赖倒置的实现(直接绑定具体类)
假设我们写一个餐厅类,直接依赖汉堡、披萨这些具体食物:
class Burger: def cook(self): print("煎制汉堡") class Pizza: def cook(self): print("烘烤披萨") class Restaurant: def __init__(self): self.burger = Burger() self.pizza = Pizza() def serve_burger(self): self.burger.cook() def serve_pizza(self): self.pizza.cook() # 使用 restaurant = Restaurant() restaurant.serve_burger() restaurant.serve_pizza()
现在如果要新增沙拉品类,你必须修改Restaurant的代码:添加self.salad = Salad()属性,还要新增serve_salad()方法。高层模块(餐厅)直接绑定低层具体类,每次扩展功能都要改动核心逻辑,完全违反开闭原则。
依赖倒置的实现(依赖抽象契约)
先定义抽象的IFood接口,所有食物类都实现这个抽象,餐厅只依赖IFood而非具体食物:
from abc import ABC, abstractmethod class IFood(ABC): @abstractmethod def cook(self): pass class Burger(IFood): def cook(self): print("煎制汉堡") class Pizza(IFood): def cook(self): print("烘烤披萨") class Salad(IFood): def cook(self): print("制作沙拉") class Restaurant: def __init__(self, foods: list[IFood]): self.foods = foods def serve_all(self): for food in self.foods: food.cook() # 使用 restaurant = Restaurant([Burger(), Pizza()]) restaurant.serve_all() # 新增沙拉时,完全不用修改Restaurant类 restaurant = Restaurant([Burger(), Pizza(), Salad()]) restaurant.serve_all()
这里的核心优势一目了然:
- 新增任何食物品类,只需要写一个实现
IFood的类,直接传入餐厅即可,不需要改动餐厅的一行代码。 - 高层模块(餐厅)完全不关心具体是哪种食物,只知道所有食物都遵循“有cook方法”的契约,彻底解耦了“服务逻辑”和“具体产品”的绑定关系。
你之前没发现优势的原因
你写的两段代码是在需求稳定、无扩展场景下的实现,此时依赖倒置的价值确实不明显。但当系统需要迭代扩展时,它能让你避免“牵一发而动全身”的修改,让架构更灵活、更易维护。
另外,Python里也可以用鸭子类型替代抽象类(不需要显式继承ABC),但抽象类的作用是明确契约,避免出现“某个食物类忘了实现cook方法”的低级错误——这是附加保障,而非依赖倒置的核心价值。
内容的提问来源于stack exchange,提问作者matt
相关产品推荐
相关产品推荐

