You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:43:42