插件 = 策略模式:TEMPLATE_ID/PRIORITY/recognizes/parse 四要素
不写进 if-else,写进文件
加一种新的 PDF 格式,最省事的写法是往解析函数里塞 if 是格式A: … elif 是格式B: …。但格式一多,核心代码就成了一滩浆糊,而且每次改格式都要动核心、都要重新发布。
第一性原理:把同族行为抽象成"策略",每个策略一个文件,核心只负责调度,不负责具体格式。这就是策略模式(Strategy)。
插件四要素
我们每个插件文件,固定实现四个东西:
class Plugin:
TEMPLATE_ID = "1002" # #1 唯一ID,路由用
PRIORITY = 1 # #2 优先级,数字小优先
def recognizes(self, pdf): # #3 自动判据:给个pdf,能认吗?
...
def parse(self, pdf): # #4 真正解析,返回标准记录
...
导入时通过 __init__.py 统一加载,扫描 plugins 目录里的每个文件,收集这四要素。
为什么这是"插件"
因为核心代码不看你字节是什么格式,它只认这四个口。你新加一个格式 = 在 plugins 目录丢一个新 py 文件,定义好这四样,核心零改动。
以 1002 插件为例,recognizes 是这样认的:
def recognizes(self, pdf):
first = pdf.pages[0].extract_text() or ""
return ("Lot No." in first) and ("Item(unit)" in first)
判定谁认知谁
两个职责分开:
- recognizes:自动模式下,逐插件试,谁 True 用谁。
- TEMPLATE_ID:显式模式下(HTTP 带 template),按 ID 直接锁。
一句话
策略模式 = 让"新增变体"变成"加文件"而不是"改核心"。识别逻辑这种高度因格式而异的活,天生适合插件化。 四个口子定死,剩下的自由发挥。


