The strategy pattern in Python is a behavioral design pattern that allows the selection of algorithms or behaviors at runtime. This pattern is very useful in scenarios such as testing frameworks, rule engines, and business logic processing.The traditional if-else approach for writing an assertion comparison function is very verbose:
def compare(operator, actual, expected): if operator == '==': return actual == expected elif operator == '!=': return actual != expected elif operator == '>': return actual > expected elif operator == '<': return actual < expected elif operator == '>=': return actual >= expected elif operator == '<=': return actual <= expected elif operator == 'in': return actual in expected elif operator == 'not in': return actual not in expected elif operator == 'is': return actual is expected elif operator == 'is not': return actual is not expected elif operator == 'contains': return expected in actual elif operator == 'startswith': return actual.startswith(expected) elif operator == 'endswith': return actual.endswith(expected) elif operator == 'regex': return re.search(expected, actual) is not None elif operator == 'not regex': return re.search(expected, actual) is None else: raise ValueError(f"Unsupported operator: {operator}")
Converting it to use the strategy pattern:
def compare(self, **kwargs): comparators = { '==': lambda a, b: a == b, '!=': lambda a, b: a != b, '>': lambda a, b: a > b, '<': lambda a, b: a < b, '>=': lambda a, b: a >= b, '<=': lambda a, b: a <= b, 'in': lambda a, b: a in b, 'not in': lambda a, b: a not in b, 'is': lambda a, b: a is b, 'is not': lambda a, b: a is not b, 'contains': lambda a, b: b in a, 'not contains': lambda a, b: b not in a, 'startswith': lambda a, b: a.startswith(b), 'endswith': lambda a, b: a.endswith(b), 'regex': lambda a, b: re.search(b, a) is not None, 'not regex': lambda a, b: re.search(b, a) is None }
Calling the strategy pattern:
comparators[operators](kwargs['actual'], kwargs['expected'])# Equality comparisonoperators = '=='actual = 5expected = 5result = comparators[operators](actual, expected)print(result)# Contains comparisonoperators = 'contains'actual = "abcdefg"expected = "ab"result = comparators[operators](actual, expected)print(result)
The execution process is as follows:
# Step 1: Get the function object from the dictionary# For example: operators = '=='function_obj = comparators[operators] # Step 2: Call the retrieved functionresult = function_obj(kwargs['actual'], kwargs['expected'])
This is equivalent to the traditional function call:
# Equivalent to: if operators == '==': result = kwargs['actual'] == kwargs['expected'] elif operators == 'in': result = kwargs['actual'] in kwargs['expected']