Python类成员变更捕获设计:公司员工薪资联动计算需求
嘿,这个需求用**观察者模式(Observer Pattern)结合懒加载(Lazy Loading)**简直是量身定制!既完美捕获员工薪资的变更事件,又能避免不必要的高成本计算。我给你捋清楚实现思路,再附上可运行的代码示例:
1. 先搭好观察者模式的基础框架
我们需要定义被观察者(Subject)和观察者(Observer)的基类,用来规范事件通知和响应的逻辑:
class Subject: def __init__(self): self._observers = [] def attach(self, observer): if observer not in self._observers: self._observers.append(observer) def detach(self, observer): try: self._observers.remove(observer) except ValueError: pass def notify(self, *args, **kwargs): for observer in self._observers: observer.update(self, *args, **kwargs) class Observer: def update(self, subject, *args, **kwargs): # 子类需要实现具体的更新逻辑 pass
2. 实现Employee类(被观察者)
让Employee继承Subject,封装salary属性——只有当薪资真正变化时,才触发通知给它所属的Company:
class Employee(Subject): def __init__(self, name, salary, company): super().__init__() self._name = name self._salary = salary self._company = company # 初始化时就把公司添加为自己的观察者 self.attach(company) @property def name(self): return self._name @property def salary(self): return self._salary @salary.setter def salary(self, new_salary): if new_salary != self._salary: self._salary = new_salary # 通知所有观察者(这里就是所属公司)薪资变更了 self.notify() @property def company(self): return self._company
3. 实现Company类(观察者+懒加载计算)
Company继承Observer,同时维护总薪资的缓存和“是否需要重新计算”的标记。只有当实际需要获取总薪资且缓存无效时,才执行高成本的计算:
class Company(Observer): def __init__(self, name): self._name = name self._employees = [] # 缓存总薪资,初始为None表示从未计算过 self._total_salary = None # 标记:是否需要重新计算总薪资 self._is_dirty = False @property def name(self): return self._name @property def employees(self): return self._employees.copy() # 返回副本,避免外部直接修改列表 def add_employee(self, employee): if employee not in self._employees: self._employees.append(employee) self._is_dirty = True # 添加员工后,总薪资需要重新计算 def remove_employee(self, employee): try: self._employees.remove(employee) employee.detach(self) # 解除和员工的观察者关联 self._is_dirty = True # 移除员工后,总薪资需要重新计算 except ValueError: pass @property def total_salary(self): # 懒加载核心逻辑:只有当缓存无效时才重新计算 if self._is_dirty or self._total_salary is None: print("正在执行高成本的总薪资计算...") # 模拟高成本操作 self._total_salary = sum(emp.salary for emp in self._employees) self._is_dirty = False # 计算完成后标记为干净 return self._total_salary def update(self, subject, *args, **kwargs): # 收到员工薪资变更的通知,标记总薪资需要重新计算 if isinstance(subject, Employee): self._is_dirty = True
4. 测试一下效果
运行下面的代码,你就能看到懒加载和事件通知的效果:
# 创建公司 acme = Company("ACME Corp") # 创建员工并关联公司 alice = Employee("Alice", 5000, acme) bob = Employee("Bob", 6000, acme) # 添加员工到公司 acme.add_employee(alice) acme.add_employee(bob) # 第一次获取总薪资,会触发高成本计算 print(f"初始总薪资: {acme.total_salary}") # 输出:正在执行高成本的总薪资计算... # 初始总薪资: 11000 # 修改Alice的薪资 alice.salary = 5500 # 再次获取总薪资,因为标记为脏,会重新计算 print(f"修改Alice薪资后总薪资: {acme.total_salary}") # 输出:正在执行高成本的总薪资计算... # 修改Alice薪资后总薪资: 11500 # 连续两次获取,第二次不会触发计算 print(f"再次获取总薪资: {acme.total_salary}") # 输出:再次获取总薪资: 11500
关键点说明
- 观察者模式:员工薪资变更时自动通知公司,完全不需要手动同步状态,代码解耦性很强。
- 懒加载:只有当实际需要使用
total_salary时才计算,而且只在缓存无效(有员工薪资变更/增删)时才重新计算,完美节省了高成本计算的资源。 - 封装性:通过
@property封装了敏感属性,避免外部直接修改导致状态不一致。
内容的提问来源于stack exchange,提问作者Larry
相关产品推荐
相关产品推荐

