Вопрос:

Принцип единой ответственности, когда метод может принимать различные типы данных?

python design-patterns single-responsibility-principle

21 просмотра

1 ответ

136 Репутация автора

В соответствии с передовой практикой метод или функция должны выполнять одну задачу и делать это хорошо, поэтому как я могу применить 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
Автор: Jackofspace Источник Размещён: 11.06.2019 06:45

Ответы (1)


0 плюса

15144 Репутация автора

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либо в виде отдельной функции снаружи. Это даст вам более чистые модульные тесты, но в вашем конкретном случае , вы можете решить , чтобы сохранить его как вместо того , чтобы более-инженерии.

Автор: Dan Dinu Размещён: 12.06.2019 09:07
Вопросы из категории :
32x32