Python规范模式

Python规范模式 # Python 规范模式 (Specification Pattern)# 封装业务规则and/or/not 组合规则链查询构建# 规范模式将业务规则封装为独立对象通过逻辑运算符组合。from abc import ABC, abstractmethodfrom dataclasses import dataclassfrom typing import Any# 规范基类支持逻辑运算class Specification(ABC):abstractmethoddef is_satisfied_by(self, candidate: Any) - bool: ...def __and__(self, other: Specification) - AndSpec:return AndSpec(self, other)def __or__(self, other: Specification) - OrSpec:return OrSpec(self, other)def __invert__(self) - NotSpec:return NotSpec(self)# 组合规范class AndSpec(Specification):def __init__(self, *specs: Specification):self._specs specsdef is_satisfied_by(self, c: Any) - bool:return all(s.is_satisfied_by(c) for s in self._specs)class OrSpec(Specification):def __init__(self, *specs: Specification):self._specs specsdef is_satisfied_by(self, c: Any) - bool:return any(s.is_satisfied_by(c) for s in self._specs)class NotSpec(Specification):def __init__(self, spec: Specification):self._spec specdef is_satisfied_by(self, c: Any) - bool:return not self._spec.is_satisfied_by(c)# 领域对象dataclassclass Order:id: str; total: float; customer_name: str; is_vip: bool False# 具体规范class TotalAbove(Specification):def __init__(self, threshold: float):self._threshold thresholddef is_satisfied_by(self, c: Order) - bool:return c.total self._thresholdclass VIPCustomer(Specification):def is_satisfied_by(self, c: Order) - bool:return c.is_vip# 规范查询class OrderQuery:def __init__(self):self._orders: list[Order] []def add(self, o: Order) - None:self._orders.append(o)def find(self, spec: Specification) - list[Order]:return [o for o in self._orders if spec.is_satisfied_by(o)]# 规范转 SQLclass SpecToSQL:staticmethoddef convert(spec: Specification) - str:if isinstance(spec, TotalAbove):return ftotal {spec._threshold}if isinstance(spec, VIPCustomer):return is_vip 1if isinstance(spec, AndSpec):return ( AND .join(SpecToSQL.convert(s) for s in spec._specs) )return 11if __name__ __main__:vip_high VIPCustomer() TotalAbove(1000)q OrderQuery()q.add(Order(O1, 2000, 张三, True))q.add(Order(O2, 500, 李四, False))for o in q.find(vip_high):print(fVIP高额订单: {o.id})print(fSQL: {SpecToSQL.convert(vip_high)})