
# Python 服务层模式 (Service Layer)# 服务层是应用层与领域层之间的薄中间层负责事务控制、# 权限校验、DTO 转换等横切关注点领域层保持纯净。from abc import ABC, abstractmethodfrom dataclasses import dataclassfrom typing import Optional# 领域层dataclassclass Product:id: str; name: str; price: float; stock: intdef reduce_stock(self, qty: int) - None:if self.stock qty:raise ValueError(库存不足)self.stock - qty# DTO (数据传输对象)dataclassclass CreateProductDTO:name: str; price: float; stock: int 0dataclassclass ProductDTO:id: str; name: str; price: float; stock: intclassmethoddef from_entity(cls, p: Product) - ProductDTO:return cls(p.id, p.name, p.price, p.stock)# 工作单元 - 管理事务边界class UnitOfWork:def __enter__(self):return selfdef __exit__(self, *args):self.commit()def commit(self) - None:print([UOW] 提交事务)# 仓储接口class ProductRepository(ABC):abstractmethoddef save(self, p: Product) - None: ...abstractmethoddef get(self, pid: str) - Optional[Product]: ...class MemoryProductRepo(ProductRepository):def __init__(self):self._store: dict[str, Product] {}def save(self, p: Product) - None:self._store[p.id] pdef get(self, pid: str) - Optional[Product]:return self._store.get(pid)# 服务层class ProductService:def __init__(self, repo: ProductRepository, uow: UnitOfWork):self._repo repo; self._uow uowdef create_product(self, dto: CreateProductDTO) - ProductDTO:if dto.price 0:raise ValueError(价格必须为正数)product Product(fP-{dto.name[:3].upper()},dto.name, dto.price, dto.stock)with self._uow:self._repo.save(product)return ProductDTO.from_entity(product)def reduce_stock(self, pid: str, qty: int) - ProductDTO:product self._repo.get(pid)if product is None:raise ValueError(产品不存在)product.reduce_stock(qty)with self._uow:self._repo.save(product)return ProductDTO.from_entity(product)# 表现层控制器class ProductController:def __init__(self, service: ProductService):self._service servicedef create(self, name: str, price: float, stock: int) - dict:result self._service.create_product(CreateProductDTO(name, price, stock))return {id: result.id, name: result.name}if __name__ __main__:svc ProductService(MemoryProductRepo(), UnitOfWork())ctrl ProductController(svc)print(ctrl.create(无线鼠标, 89.0, 50))