Skip to content

设计模式

设计原则在 Python 的形态、哪些模式退化为语言特性、面试怎么答。

Updated View as Markdown
For humans

设计模式

设计模式是解决重复问题的套路,但套路的形态随语言变化。Python 是动态语言,很多 Java 模式在 Python 里退化为语言特性或几行代码。面试主线的正确姿势:模式的本意是什么,Python 里它长什么样

哪些模式“消失”了

模式 Java 的写法 Python 的写法
单例 私有构造 + getInstance 模块天然单例,import 即复用
工厂 工厂类 + 接口 一个函数返回对象
策略 策略接口 + 实现类 直接传函数
观察者 观察者接口 + 注册 事件回调、信号
迭代器 Iterator 接口 __iter__/__next__ 或直接 for

原因:Java 的类型系统要求“接口”才能多态,Python 的鸭子类型让任何对象都能扮演角色,函数是一等公民让“行为注入”变成传参。

设计原则在 Python 的体现

SOLID 不是 Java 专属,Python 的落地方式不同:

原则 Python 实践
单一职责 模块和函数小而专注,一个函数只做一件事
开闭原则 协议(Protocol)和鸭子类型扩展行为,不改旧代码
里氏替换 继承谨慎,子类不应破坏父类契约;优先组合
接口隔离 Protocol 按需声明,不用继承大接口
依赖倒置 依赖抽象(Protocol/ABC)而不是具体类,靠 DI 注入

ABC 与 Protocol 的选择(高频考点):

  • abc.ABC 抽象基类:名义子类,必须显式继承,适合“定义骨架”(模板方法)
  • typing.Protocol结构化子类,只要方法签名对上就满足,不强制继承,适合“描述能力”
  • 一句话:Protocol 是鸭子类型的类型标注版,ABC 是传统继承的抽象

组合优于继承

Python 里这个原则格外重要:多重继承有 MRO 坑(菱形继承、super 顺序),组合(持有对象)比继承(成为对象)更好改。dataclasses、依赖注入、装饰器都是组合思维。

面试怎么答

  1. 先答模式意图(解决什么问题),再答 Python 形态
  2. 主动说“这个模式在 Python 里通常不这么写”,展示语言意识
  3. 结合 FastAPI 举例(DI、中间件、lru_cache)比背 Gof 例子有说服力
  4. 被问“工厂模式”时说函数工厂,被问“单例”时说模块单例加 lru_cache

面试追问

  1. Python 还需要设计模式吗? 需要,但形态变了。行为型模式多退化为传函数,创建型多退化为模块和函数,结构型(装饰器、代理)仍有独立价值
  2. ABC 和 Protocol 的区别? ABC 要显式继承(名义子类),Protocol 只要结构匹配(结构化子类)。鸭子类型的类型标注用 Protocol
  3. 为什么组合优于继承? 继承耦合父类实现,MRO 和菱形继承有坑;组合只依赖接口,便于替换和测试
  4. 单例在 Python 怎么写? 模块级对象就是单例。需要惰性初始化或参数化时用 lru_cache 或显式工厂
  5. 设计模式和 Python 惯例冲突怎么办? 优先惯例。Python 里“Pythonic”的解法往往就是模式的简化形态
Navigation

Type to search…

↑↓ navigate↵ selectEsc close