最佳实践建议一种方法或函数应该做一件事情,并且要做好,所以在以下情况下如何应用SRP:
摘要:我有一个API包装器,可以发送HTTP Post请求,但是为了提供json,我想允许用户使用多个选项,可以说我的函数可以接受以下任何一项:
def function_for_srp(jsonable_data: Union[Entity, Domain, str]):
# Pseudo code (Violation of SRP?)
if jsonable_data is instance of entity or domain:
jsonable_data = json.dumps(jsonable_data)
else do nothing, as its a json encoded string of data already
some_api_wrapper.post_data(jsonable_data)
此函数根据传递给它的数据类型执行多项操作,因此它违反了SRP吗?我如何以一种干净的方式克服这个设计问题,理想情况下,我在想这样的事情:
def function_for_srp_using_entity(entity: Entity): pass
def function_for_srp_using_domain(domain: Domain): pass
def function_for_srp(json_encoded_data: str): pass
以上是“ pythonic”吗? 有更好的方法吗?
# possible alternative?
def function_for_srp(jsonable_data: Union[Entity, Domain, str]):
json = some_other_function(jsonable_data)
some_api_wrapper.post_something(json)
# Is this still a violation?
def some_other_function(jsonable_data: Union[Entity, Domain, str]):
# Figure out the type and return a json encoded string that is suitable
if isinstance of entity/domain, json dump and return
else check if is valid json encoded string, if not make it valid and return it
答案 0 :(得分:1)
SRP绝对是一个很好的遵循原则,但是在实践中,您需要知道何时画线,否则会给代码增加太多的复杂性。
在您的特定情况下,我将从对您的用户更有利的方面开始,然后决定您是否保留此
def function_for_srp(jsonable_data: Union[Entity, Domain, str]):
或
def function_for_srp_using_entity(entity: Entity): pass
def function_for_srp_using_domain(domain: Domain): pass
第二个选项很明确,您没有违反任何原则:)
如果您想保留第一个选项,可以这样做(也是伪代码):
def function_for_srp(jsonable_data: Union[Entity, Domain, str]):
jsonableData = jsonable_data.getjson();
some_api_wrapper.post_data(jsonable_data)
您可以按自己的意愿实现getJson
(既可以作为Entity
上的函数,也可以作为Domain
上的单独函数来实现。
这将使您的单元测试更加简洁,但是在您的特定情况下,您可以决定保持原样,而不是过度设计。 KISS也是一个很好的遵循原则