Принцип единой ответственности, когда метод может принимать различные типы данных? - PullRequest
1 голос
/ 11 июня 2019

В соответствии с рекомендациями метод или функция должны выполнять одну задачу и делать это хорошо, поэтому как я могу применить 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

Является ли вышеприведенное «питоническим»? Есть ли лучший способ сделать это?

# 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

1 Ответ

1 голос
/ 13 июня 2019

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 также является хорошим принципом для следования

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...