我有以下内容:
class DepartmentsSet(ComplexModel):
__namespace__ = MODELS_NS
service_difference_set = Iterable(Department)
db_difference_set = Iterable(Department)
intersection_difference_set = Iterable(Department)
def __init__(self, service_diff, db_diff, intersection):
self.service_difference_set = _convert_to_departments(service_diff)
self.db_difference_set = _convert_to_departments(db_diff)
self.intersection_set = _convert_to_departments(intersection)
def _convert_to_departments(operation_set):
departments = []
for item in operation_set:
department = dict(item)
departments.append(Department(
name=department.get('name'),
external_id=department.get('external_id')
))
class EmployeesSet(ComplexModel):
__namespace__ = MODELS_NS
service_difference_set = Iterable(Employee)
db_difference_set = Iterable(Employee)
intersection_set = Iterable(Employee)
def __init__(self, service_diff, db_diff, intersection):
self.service_difference_set = _convert_to_employees(service_diff)
self.db_difference_set = _convert_to_employees(db_diff)
self.intersection_set = _convert_to_employees(intersection)
def _convert_to_employees(operation_set):
employees = []
for item in operation_set:
employee = dict(item)
dep = employee.get('department')
employees.append(Employee(
name=employee.get('name'),
post=employee.get('post'),
department=(dep.name if isinstance(dep, CompanyDepartment) else u''),
contact_info=employee.get('contact_info'),
external_id=employee.get('external_id')))
return employees
我有两个问题:
因此,您可以看到我的课程DepartmentsSet
和EmployeesSet
都具有相似的结构。它们之间的唯一区别是它们的集合由_convert_to_departments
或_convert_to_employees
组成。
我意识到我的解决方案并不好。这种情况的最佳做法是什么?
有没有办法将函数_convert_to_departments
和_convert_to_employees
统一为一般函数?
*我不能为DepartmentsSet和EmployeesSet创建单个类,因为这些类将是我的SOAP服务的类型。
答案 0 :(得分:2)
解决直接问题很简单 - 将公共代码和变量移动到超类并从中继承EmployeeSet和DepartmentSet:
class CommonModel(ComplexModel):
def get_items(self, operation_set):
items = [dict(x) for x in operation_set]
return items
# important: put COMMON methods, variables etc. here
class DepartmentsSet(CommonModel):
...
def _convert(self, operation_set):
items = self.get_items(operation_set)
for item in items:
... # convert to departments
class EmployeeSet(CommonModel):
...
def _convert(self, operation_set):
items = self.get_items(operation_set)
for item in items:
... # convert to employees
然而,从策略上来说,我觉得这不是一个好的设计,如果它真的是“它们之间唯一的区别就是它们的集合由”组成,“DepartmentSet
和EmployeeSet
真的不是同一件事情?你能不能把它变成一个有2个转换方法的类?
虽然这仍然不是很好的设计 - 你正在混合集合和类中的特定对象。这实际上违反了单一责任原则。将Employee
或Department
或CommonModel
设为一个类,只需将其实例放入列表中即可。如果你真的,真的需要转换某处提供单个对象转换方法,然后你可以做类似的事情:
[x.convert() for x in list_of_model_instances]
..甚至没有费心去检查x
的类别(那是鸭子打字)。
我仍然认为你没有真正做过,它应该是一些其他的类或函数,可以在输入中使用CommonModel
的实例,并用它做任何想做的事情。如果你真的需要进行精细的转换,为什么不创建一个Converter
类,它可以接受许多输入实例并输出所要求的任何内容? (单一责任原则)
class AbstractItemCheckpoint(object):
__metaclass__ = ABCMeta
'''Abstract item checkpoint, derive concrete item checkpoints that verify if a item (Subsystem, Component,
etc.) is eligible for creating a Task for it.'''
@abstractmethod
def convert(self):
'''
Ensure that model inheriting from AbstractItemCheckpoint has convert method.
'''
pass
这可以确保Employee
或Department
等任何类都必须使用convert
方法,从而使提交到Converter
的实例更安全。