我有两个公共 API 函数添加和删除,第一个函数将元素添加到数据库,第二个函数删除相同的元素。
为了减少重复代码,我可以实现一个泛型函数,让两个函数都调用泛型函数。
第一个解决方案是使用枚举:
private fun UpdateDatabase(list, enum operation_type):
for element in list:
for properties in element.all_properties():
if properties.valid():
switch (operation_type):
case ADD: AddToDatabase(properties)
case DELETE: DeleteFromDatabase(properties)
public fun Add(list): UpdateDatabase(list, OperationType::ADD)
public fun Delete(list): UpdateDatabase(list, OperationType::DELETE)
第二种解决方案是使用lambda:
private fun UpdateDatabase(list, lambda L):
for element in list:
for properties in element.all_properties():
if properties.valid():
L(properties)
public fun Add(list): UpdateDatabase(list, p -> AddToDatabase(p))
public fun Delete(list): UpdateDatabase(list, p -> DeleteFromDatabase(p))
从代码清洁度/可维护性的角度来看,哪种解决方案更好?有替代的第三种解决方案吗?
你不应该使用枚举,因为它违反了开闭原则和单一职责。
问问自己“如果我想实现一种新的操作类型,我必须编辑哪些代码?”
如果您使用枚举,则必须向枚举添加一个新值,在调用者(客户端)中使用该新值并在实现(UpdateDatabase)中编辑 switch 语句。
如果你使用 lambda,你只需要编辑调用者并实现 lambda。
当然,可以说不会有很多数据库操作类型要添加,但我想给出一个更通用的答案,也可以应用于其他情况。
我通常将枚举方法称为“类型开关”,并在几年前写了一篇 blog 关于它。
似乎以下替代解决方案更好:
private fun GetValidProperties(list):
valid_list = empty()
for element in list:
for properties in element.all_properties():
if properties.valid():
valid_list.add(properties)
return valid_list;
public fun Add(list):
for properties in GetValidProperties(list):
AddToDatabase(properties)
public fun Delete(list):
for properties in GetValidProperties(list):
DeleteFromDatabase(properties)