如何优化类耦合并处理家庭食品消费追踪程序的动态属性历史问题
方案合理性评估
你当前的设计思路可以跑通,但存在两个明显的局限性:
- 职责边界不清晰:
Member类本身是用来存储成员基础属性、饮食相关规则的载体,直接存储和ReceiptLine的绑定关系会让Member的职责过重,后续如果要查询单张收据的全部分拆结果,需要遍历所有成员的对应属性才能聚合得到,查询效率很低 - 扩展性差:如果后续出现一个成员属于多个家庭的场景(比如未成年子女同时归属父母家和祖父母家),成员身上存储的分拆数据会出现跨家庭混淆的问题
更合理的设计是新增一个第三方中间类来存储分拆结果,示例结构如下:
@attr.s class ConsumptionAllocation: house: 'House' = attr.ib(validator=instance_of(House)) receipt_line: 'ReceiptLine' = attr.ib(validator=instance_of(ReceiptLine)) member: 'Member' = attr.ib(validator=instance_of(Member)) allocated_ratio: float = attr.ib() # 分拆占比,取值范围0-1 allocated_qty: float = attr.ib() # 对应分配的商品数量 allocated_amount: float = attr.ib() # 对应分配的商品金额
然后在House类新增一个allocations: Set[ConsumptionAllocation]的属性存储全部分拆结果,同时可以给Member类加一个只读的计算属性,过滤返回和当前成员关联的所有分拆记录,兼顾两边的查询便捷性。
成员属性变更的处理方案
你的需求是weekly_meals等属性变更仅影响新录入的收据分拆,处理逻辑非常简单:
- 所有分拆计算仅在**
Receipt录入House的瞬间**执行,计算时取当前时刻所有成员的weekly_meals、nutrition_plan等属性值计算占比 - 计算得到的分拆结果作为静态值存入
ConsumptionAllocation,和后续的成员属性变更完全解耦 - 成员属性修改后不需要回溯修改历史分拆数据,自然只会影响之后新录入的收据分拆结果
另外注意你贴的代码里有个笔误:你提到的Member类的代码,类名写成了Patient,记得修正。
内容的提问来源于stack exchange,提问作者Joaquim
相关产品推荐
相关产品推荐

