# 第 3-5 课参考示例:小型仓库领域模型 # # 本示例使用与综合项目不同的“仓库”场景,演示如何让对象各自负责自己的数据和行为。 # 综合项目仍需独立完成,不能直接复制本示例得到答案。 from dataclasses import dataclass, field class InventoryError(Exception): """表示仓库业务规则错误。""" @dataclass class Product: """保存商品数据,并负责与商品自身有关的显示。""" code: str name: str quantity: int = 0 def __post_init__(self) -> None: """确保创建商品时库存数量合法。""" if self.quantity < 0: raise InventoryError("库存数量不能小于 0。") @property def in_stock(self) -> bool: """根据当前数量计算是否有库存。""" return self.quantity > 0 def __str__(self) -> str: """返回面向使用者的商品信息。""" return f"{self.name}|库存:{self.quantity}" @dataclass class Warehouse: """通过组合管理多个 Product 对象。""" name: str products: dict[str, Product] = field(default_factory=dict) def add_product(self, product: Product) -> None: """添加商品,商品编码重复时阻止操作。""" if product.code in self.products: raise InventoryError("商品编码已存在。") self.products[product.code] = product def remove_stock(self, code: str, quantity: int) -> None: """扣减指定商品库存。""" if code not in self.products: raise InventoryError("商品不存在。") product = self.products[code] if quantity <= 0: raise InventoryError("出库数量必须大于 0。") if product.quantity < quantity: raise InventoryError("库存不足。") product.quantity -= quantity def main() -> None: """运行仓库领域模型示例。""" warehouse = Warehouse("教学仓库") keyboard = Product("P001", "机械键盘", 3) warehouse.add_product(keyboard) print(keyboard) print(f"是否有库存:{keyboard.in_stock}") warehouse.remove_stock("P001", 2) print(f"出库后:{keyboard}") try: warehouse.remove_stock("P001", 2) except InventoryError as error: print(f"业务操作失败:{error}") if __name__ == "__main__": main()