接口隔离原则(ISP)
非常好,**接口隔离原则(ISP: Interface Segregation Principle)是 SOLID 五大原则中的第四个,它专门解决“一个接口太臃肿”**导致的麻烦。
我来从以下几个维度详细拆解:
🧠 什么是接口隔离原则?
客户端不应该被强迫依赖它不使用的方法。
也就是说:
- 接口(或抽象类)应该小而精;
- 不要让一个类必须实现一堆它根本用不到的方法。
❌ 举个日常反例(更容易懂)
你去 ATM 机,只是想取钱。
但 ATM 接口强迫你必须实现:
def transfer_money()
def pay_credit_card()
def change_pin()
def open_account() # ❌
—— 你并不需要这些,但你被迫要实现它们,这就违反了接口隔离原则。
✅ 为什么需要接口隔离原则?
问题 | 接口隔离带来的好处 |
---|---|
接口太大,导致子类实现麻烦 | ✅ 子类只依赖自己需要的方法 |
改动一个接口方法,很多子类都受影响 | ✅ 修改影响范围变小(高内聚) |
测试复杂、维护困难 | ✅ 测试更聚焦、职责更清晰 |
✅ 优点 vs ❌ 缺点
优点 | 缺点 |
---|---|
高内聚、低耦合 | 接口数量变多 |
职责清晰 | 抽象类设计更复杂 |
子类不再实现无关方法 | 初学者觉得“麻烦” |
🐍 Python 示例
❌ 违反接口隔离原则
from abc import ABC, abstractmethod# 一个臃肿的“多功能接口”
class Machine(ABC):@abstractmethoddef print(self): pass@abstractmethoddef fax(self): pass@abstractmethoddef scan(self): pass# 简单打印机,只能 print,却被迫实现 fax、scan
class SimplePrinter(Machine):def print(self):print("Printing...")def fax(self):raise NotImplementedError("I can't fax")def scan(self):raise NotImplementedError("I can't scan")
😰 这个子类为了继承,只能抛出异常,尴尬。
✅ 遵守接口隔离原则
from abc import ABC, abstractmethod# 将大接口拆分为多个小接口
class Printer(ABC):@abstractmethoddef print(self): passclass Scanner(ABC):@abstractmethoddef scan(self): passclass Fax(ABC):@abstractmethoddef fax(self): pass# 只需要打印功能的类,只实现 Printer 接口
class SimplePrinter(Printer):def print(self):print("Printing...")# 多功能机实现多个接口
class MultiFunctionPrinter(Printer, Scanner, Fax):def print(self): print("Printing...")def scan(self): print("Scanning...")def fax(self): print("Faxing...")
✅ 各司其职,接口清晰。
🧭 清晰结构图(Mermaid)
🏁 总结口诀:
❌ 一个接口塞太多方法 → 所有人都被迫实现 → 违反 ISP
✅ 把大接口拆小、按需组合 → 谁用啥就实现啥 → 遵守 ISP
📌 应用场景
- 微服务接口暴露:每个服务只暴露自己的职责方法
- 多能力设备:按能力接口组合(打印/扫描/发邮件)
- 用户权限系统:不同角色使用不同接口,不强制统一
如果你想,我还可以用实际项目比如“支付接口”、“用户角色接口”等真实场景帮你模拟设计一套 ISP 系统,要试试看吗?👨💻