验证多种复杂条件的好模式是什么?

时间:2015-11-06 18:23:30

标签: python design-patterns

我正在编写一段代码,需要验证两个用户是否在几个不同的标准下“匹配”。如果它有帮助,可以将其视为一个约会应用程序,我们会根据年龄,性别偏好,种族偏好等来匹配人们。这是一个有3个条件的例子,每个条件都是一个函数。

def is_match(row):
    return True \
        and ethnicity(user_a, user_b) \
        and sexual_orientation(user_a, user_b) \
        and age(user_a, user_b) \

现在,假设我想为邻近度添加另一个条件,我只想将它添加到函数中:

def is_match(row):
    return True \
        and ethnicity(user_a, user_b) \
        and sexual_orientation(user_a, user_b) \
        and age(user_a, user_b) \
        and proximity(user_a, user_b)

当然,这对于小型应用程序来说是可行的,但我可以想象其他同事可能想要检查代码并将自己的条件传递给它,这看起来不够抽象。我知道这里必须有一个模式。我应该将每个函数作为数组传递吗?你会怎么推荐这样做?我正在使用Python,但您可以使用任何您想要演示模式的语言。

3 个答案:

答案 0 :(得分:2)

我认为集合对于这样的任务是有益的,因为它比验证更具有比较性。我会举例给你:

user_a = {
    'ethnicity': 1,
    'sexual_orientation': 'straight',
    'age': 37,
}

user_b = {
    'ethnicity': 2,
    'sexual_orientation': 'straight',
    'age': 34,
}

differences = set(user_a.items()) ^ set(user_b.items()) # s.symmetric_difference(t)
commons = set(user_a.items()) & set(user_b.items()) # s.intersection(t)

print({'differences': differences, 'commons': commons})

输出:

{'differences': {('ethnicity', 2), ('ethnicity', 1), ('age', 37), ('age', 34)}, 'commons': {('sexual_orientation', 'straight')}}

所以你可以将两个用户的数据加载到dicts并进行比较。

答案 1 :(得分:1)

def is_match(list_of_functions, user_a, user_b):
   return all([cur_fun(user_a, user_b) for cur_fun in list_of_functions])

编辑:

以下变体更有效,因为它会在遇到非True值时缩短,而不是必须评估所有函数:

def is_match(list_of_functions, user_a, user_b):
   for cur_fun in list_of_functions
       if not cur_fun(user_a, user_b):
            return False
   return True

答案 2 :(得分:1)

结帐Specification Pattern。这正是您所需要的。它用C#编写,但可以很容易地转换