Python 面向对象实战案例:校园后勤管理系统的优化
·
下面通过一个校园后勤管理系统的优化案例,展示 Python 面向对象设计的核心思想与实践技巧。该系统主要管理校园资产(设备、家具等)、维修记录、仓库库存等核心业务,优化重点在于职责拆分、扩展性提升和数据一致性保障。
一、系统痛点分析(优化前)
- 单一大类封装所有功能(违反单一职责原则),如
LogisticsSystem类同时处理资产管理、维修记录、库存统计 - 资产类型硬编码(如
if-else判断设备 / 家具),新增类型需修改核心代码 - 缺乏数据验证与状态管理,资产状态(在用 / 维修 / 报废)变更混乱
- 未实现数据持久化,程序重启后数据丢失
二、优化方案设计(面向对象核心思想)
1. 类结构设计(基于职责拆分)
plaintext
├── 核心实体类(数据与基础行为)
│ ├── Asset(资产抽象基类)
│ │ ├── Device(设备资产,如投影仪)
│ │ └── Furniture(家具资产,如课桌)
│ ├── Person(人员抽象基类)
│ │ ├── Staff(后勤人员)
│ │ └── Student(学生,用于报修)
│ ├── MaintenanceRecord(维修记录)
│ └── Warehouse(仓库,管理库存)
├── 服务类(业务逻辑)
│ ├── AssetManager(资产管理:新增/报废/状态变更)
│ ├── MaintenanceManager(维修管理:报修/派工/结案)
│ └── DataPersistence(数据持久化:序列化/反序列化)
└── 工具类(辅助功能)
├── AssetFactory(资产工厂:创建不同类型资产)
└── Validator(数据验证:确保资产信息完整)
![]()
2. 核心代码实现(优化后)
(1)实体类设计(封装数据与基础行为)
python
运行
from abc import ABC, abstractmethod
from dataclasses import dataclass
from datetime import datetime
from typing import List, Optional, Dict
# 抽象基类:资产
class Asset(ABC):
def __init__(self, asset_id: str, name: str, location: str):
self.asset_id = asset_id # 资产唯一标识
self.name = name # 资产名称
self.location = location # 存放位置
self._status = "in_use" # 状态:in_use/repairing/scrapped
self.created_at = datetime.now()
@property
def status(self) -> str:
return self._status
@status.setter
def status(self, new_status: str) -> None:
"""状态变更验证"""
valid_status = {"in_use", "repairing", "scrapped"}
if new_status not in valid_status:
raise ValueError(f"无效状态:{new_status},必须是{valid_status}")
self._status = new_status
@abstractmethod
def get_type(self) -> str:
"""获取资产类型(多态)"""
pass
# 设备资产(继承自Asset)
class Device(Asset):
def __init__(self, asset_id: str, name: str, location: str, brand: str):
super().__init__(asset_id, name, location)
self.brand = brand # 设备品牌(特有属性)
def get_type(self) -> str:
return "device"
# 家具资产(继承自Asset)
class Furniture(Asset):
def __init__(self, asset_id: str, name: str, location: str, material: str):
super().__init__(asset_id, name, location)
self.material = material # 材质(特有属性)
def get_type(self) -> str:
return "furniture"
# 维修记录(关联资产与人员)
@dataclass
class MaintenanceRecord:
record_id: str
asset: Asset # 关联资产对象
reporter: "Person" # 报修人
handler: Optional["Staff"] = None # 处理人(可选)
description: str = "" # 故障描述
status: str = "pending" # pending/processing/completed
created_at: datetime = datetime.now()
completed_at: Optional[datetime] = None
(2)服务类设计(业务逻辑与职责分离)
python
运行
# 资产工厂(工厂模式:创建不同类型资产,避免硬编码)
class AssetFactory:
@staticmethod
def create_asset(asset_type: str, **kwargs) -> Asset:
if asset_type == "device":
return Device(** kwargs)
elif asset_type == "furniture":
return Furniture(**kwargs)
else:
raise ValueError(f"不支持的资产类型:{asset_type}")
# 资产管理类(单一职责:只处理资产生命周期)
class AssetManager:
def __init__(self):
self.assets: Dict[str, Asset] = {} # asset_id -> Asset
def add_asset(self, asset: Asset) -> None:
if asset.asset_id in self.assets:
raise ValueError(f"资产ID已存在:{asset.asset_id}")
self.assets[asset.asset_id] = asset
def scrap_asset(self, asset_id: str) -> None:
"""报废资产(状态变更+业务逻辑)"""
asset = self.assets.get(asset_id)
if not asset:
raise ValueError(f"资产不存在:{asset_id}")
if asset.status == "repairing":
raise RuntimeError(f"资产{asset_id}正在维修,无法报废")
asset.status = "scrapped"
def get_assets_by_status(self, status: str) -> List[Asset]:
return [a for a in self.assets.values() if a.status == status]
# 维修管理类(单一职责:处理维修流程)
class MaintenanceManager:
def __init__(self, asset_manager: AssetManager):
self.records: Dict[str, MaintenanceRecord] = {}
self.asset_manager = asset_manager # 依赖注入:复用资产管理
def create_repair_request(self, record: MaintenanceRecord) -> None:
"""创建报修单(自动更新资产状态)"""
asset = record.asset
if asset.status == "scrapped":
raise RuntimeError(f"报废资产{asset.asset_id}无法报修")
self.records[record.record_id] = record
asset.status = "repairing" # 报修后自动改为维修中
def complete_repair(self, record_id: str, handler: "Staff") -> None:
"""完成维修(更新记录+资产状态)"""
record = self.records.get(record_id)
if not record:
raise ValueError(f"维修记录不存在:{record_id}")
record.status = "completed"
record.handler = handler
record.completed_at = datetime.now()
record.asset.status = "in_use" # 维修完成后改回在用
(3)数据持久化(基于动态属性序列化)
复用之前的动态属性序列化方案,支持资产动态属性(如临时添加的warranty_period保修期限):
python
运行
import json
from typing import Any
class DataPersistence:
@staticmethod
def serialize(obj: Any) -> str:
"""序列化对象(支持Asset、MaintenanceRecord等)"""
def _convert(obj):
if isinstance(obj, datetime):
return obj.isoformat()
if isinstance(obj, Asset):
data = {
"type": obj.get_type(),
"attrs": obj.__dict__,
"class": obj.__class__.__name__
}
return data
if isinstance(obj, MaintenanceRecord):
return {
"record_id": obj.record_id,
"asset_id": obj.asset.asset_id, # 存储关联ID而非对象
"reporter_id": obj.reporter.person_id,
"handler_id": obj.handler.person_id if obj.handler else None,
"description": obj.description,
"status": obj.status,
"created_at": _convert(obj.created_at),
"completed_at": _convert(obj.completed_at) if obj.completed_at else None
}
return obj.__dict__ if hasattr(obj, '__dict__') else obj
return json.dumps(obj, default=_convert, indent=2)
@staticmethod
def deserialize(json_str: str, asset_manager: AssetManager) -> Any:
"""反序列化(需关联资产管理器恢复对象引用)"""
data = json.loads(json_str)
# 简化实现:根据实际需求恢复对象
return data
(4)系统集成与使用示例
python
运行
# 人员类(简化实现)
class Person(ABC):
def __init__(self, person_id: str, name: str):
self.person_id = person_id
self.name = name
class Staff(Person):
pass
class Student(Person):
pass
# 系统初始化
if __name__ == "__main__":
# 1. 创建核心组件
asset_manager = AssetManager()
maintenance_manager = MaintenanceManager(asset_manager)
factory = AssetFactory()
# 2. 添加资产(通过工厂模式)
projector = factory.create_asset(
"device",
asset_id="D001",
name="投影仪",
location="教学楼301",
brand="明基"
)
# 动态添加属性(如保修期限)
projector.warranty_period = "2年"
asset_manager.add_asset(projector)
desk = factory.create_asset(
"furniture",
asset_id="F001",
name="课桌",
location="教学楼301",
material="实木"
)
asset_manager.add_asset(desk)
# 3. 创建人员
student = Student("S1001", "张三")
staff = Staff("ST001", "李四(维修工)")
# 4. 提交报修
repair_record = MaintenanceRecord(
record_id="R001",
asset=projector,
reporter=student,
description="无法开机"
)
maintenance_manager.create_repair_request(repair_record)
print(f"报修后投影仪状态:{projector.status}") # 输出:repairing
# 5. 完成维修
maintenance_manager.complete_repair("R001", staff)
print(f"维修后投影仪状态:{projector.status}") # 输出:in_use
# 6. 数据持久化
serialized_data = DataPersistence.serialize({
"assets": asset_manager.assets,
"repairs": maintenance_manager.records
})
with open("logistics_data.json", "w") as f:
f.write(serialized_data)
三、优化亮点总结
-
单一职责原则:每个类只负责一项功能(如
AssetManager仅管理资产,MaintenanceManager仅处理维修),降低耦合度。 -
多态与工厂模式:通过
Asset抽象基类定义接口,Device/Furniture实现多态;AssetFactory统一创建资产,新增资产类型(如ElectricalAppliance电器)时无需修改核心逻辑。 -
状态管理与数据验证:资产状态通过
@property封装,确保变更合法性;维修流程中自动同步资产状态(如报修后自动改为 "维修中")。 -
动态属性与序列化:支持资产动态添加属性(如保修期限),通过自定义序列化方案实现完整数据持久化。
-
依赖注入:
MaintenanceManager通过参数接收AssetManager,而非内部创建,提高代码可测试性与灵活性。
四、进一步优化方向
- 引入观察者模式:当资产状态变更时,自动通知仓库管理员或相关师生。
- 添加缓存层:对高频访问的资产信息(如教学设备位置)进行缓存,提升查询性能。
- 实现数据库持久化:替换 JSON 文件存储,使用 SQLAlchemy 等 ORM 工具对接 MySQL,支持事务与并发控制。
- 增加权限控制:通过装饰器或代理模式限制不同角色(学生 / 管理员)的操作权限。
通过面向对象设计的优化,系统从 "一锅粥" 的代码结构转变为职责清晰、可扩展、易维护的模块化架构,为后续功能迭代奠定了良好基础。
更多推荐

所有评论(0)