我正在寻找适合Python的设计模式来解决以下问题:
假设某个成员Company
有一个成员employees
,这是一个包含任意数量Employee
的列表。
我想要捕获的是当Employee
的一个成员变量(假设salary
)发生变化时,该变化会反映在“拥有”Company
中(让我们看看)说total_salary
)。我们还假设total_salary
的计算成本非常高,我们只想在任何员工的薪水发生变化时进行计算,而不是每当我们将其作为财产进行访问时。
> c = Company()
> print(c.total_salary)
0
> c.employees.append(Employee())
> print(c.total_salary)
0
c.employees[0].salary = 100 # update total_salary for c now
> print(c.total_salary)
100
显而易见的方法是确保每个Employee
都有一个引用回到它拥有的Company
。我很好奇的是,是否有一种很好的方法可以在Company
中使用getter,setter或其他内容,以确保我可以对salary
中的任何元素进行employees
更改,这样我就可以立即更新total_salary
。至关重要的是,我们应该在更新其他成员时避免重新计算(例如name
)。
答案 0 :(得分:1)
class Company:
def __init__(self, ....):
self.employees = []
self.total_salary = 0
def add_employe(self, employe):
self.employees.append(employe)
self.total_salary += employe.salary
def remove_employe(self, employe):
self.employees.remove(employe)
self.total_salary -= employe.salary
def update_employe(self, employe):
for e in self.employees:
if not employe.id == e.id:
continue
e.name = employe.name
# ... update more data here
if employe.salary != e.salary: # salary suffered changes, update it
self.total_salary -= e.salary # subtract the older
self.total_salary += employe.salary # sum up the new
e.salary = employe.salary # update it
class Employee:
_id = itertools.count(start=1)
def __init__(self, ...):
self.id = next(Employee._id)
# ...
仅当total_salary
遭受任何更改时才需要更新employe.salary
。对此负责的是update_employe
方法。
此外,某种id
到Employee
的实现也很有用。
答案 1 :(得分:0)
如果您正在寻找getter / setter控件,请查看Python property
。您可以使用此模式来捕获何时设置变量,以实现自动更新功能。
答案 2 :(得分:0)
我认为有几种合理的方法可以做你所要求的。一种是让公司在每次请求时动态计算其总数。另一种方法是让Employee
知道它所属的公司,并在公司自己的信息发生变化时更新公司的总数。
我认为第一种方法更容易,因为Employee
实例不需要了解Company
的任何内容,并且在更新Employee时不做任何特殊操作。缺点是,如果您的公司拥有许多员工并经常请求其总数,则可能会很慢,因为每次都需要遍历所有员工。以下是我使用property
:
class Company:
def __init__(self):
self.employees = []
@property
def total_salary(self):
return sum(e.salary for e in self.employees)
如果你采用第二种方法,你也可以使用property
,但是你将它放在Employee
类中,这样就可以检测到对{{1}的更改属性:
salary
要在更复杂的系统中完成这项工作,您可能需要一堆其他方法,例如添加class Company:
def __init__(self):
self.employees = []
self.total_salary = 0
class Employee:
def __init__(self, employer):
self.employer = employer
self._salary = 0
@property
def salary(self):
return self._salary
@salary.setter
def salary(self, value):
self.employer.total_salary += value - self._salary
self._salary = value
并且工资已设置为Employee
的方法(目前您必须首先将Company
添加到公司,然后更新它的工资,否则总计将是错误的。