2017-01-16 2 views
0

Я разрабатываю класс, который управляет подключениями к внешним ресурсам. Его ответственность читает полномочия от данного источника и возвращения авторизованных соединений, как:Как реорганизовать подобные методы?

def get_svn_connection(self): 
    username, pwd=self.get_credentials("SVN") 
    client=self.get_svn_client(username, pwd) 
    return client 

def get_db_connection(self): 
    username, pwd, url, schema=self.get_credentials("DB") 
    client=self.get_db_client(username, pwd, url, schema) 
    return client 

Сегодня я встретил новый случай использования: иногда пользователь должен получить только учетные данные без подключения. Итак, после текущего решения, мне нужно создать методы get_svn_credentials, get_db_credentials и так далее. Он выглядит очень избыточным, поэтому я хочу реорганизовать эту структуру. Мои идеи:

  1. Создание подклассов для каждого типа соединения и для каждого из них определяют методы get_connection и get_credentials. Проблемы: 1) Я хочу, чтобы один класс правил всеми соединениями; 2) Я бы использовать мульти-наследование (возможно в Python, но не будет работать, например, Java - если я встречусь с этой проблемой в будущем)

  2. Создать методы get_connection(type) и get_credentials(type) и для всех известных тип соединения, указанный строкой, возвращает соответствующий экземпляр. Проблема в том, что я должен создать переключатель, который считается неудачным в ООП.

  3. Использование метапрограммирования для генерации методов для каждого типа подключения. Не очевидна и специфична для Python.

    Как бы вы это разработали?

+0

У вас уже есть 'get_credentials (тип)', почему ты подумайте, что использование 'get_connection (type)' ухудшит ситуацию? – Goyo

+0

@Goyo, это упрощенный код. Фактически, это 'get_credentials (префикс, list_of_variables)', вызываемый как 'get_credentials (« SVN », [« USERNAME »,« PASSWORD »]), поэтому он ищет SVN_USER и SVN_PASSWORD. Это частная функция, не предназначенная для внешнего использования. – fresheed

+0

Тогда ваш вопрос, как написано, вводит в заблуждение. В любом случае, я думаю, вы должны просто выбрать API, который наилучшим образом соответствует потребностям ваших пользователей, а затем реализовать его. – Goyo

ответ

0

Вы могли бы иметь класс учетных данных, которые могут быть использованы для аутентификации другой вызов функции:

class SvnCredentials: 
    def __init__(username, password): 
     self._username = username 
     self._password = password 

    def authenticate(function): 
     return function(self._username, self._password) 

Использование:

>>> credentials = SvnCredentials('AzureDiamond ', 'hunter2') 
>>> client = credentials.authenticate(get_svn_client) 
0

Просто добавить на Жан-Франсуа Фабр ответ, вы можете сделать одну функцию следующим образом:

def get_svn_connection(self, decision_str): 
    if decision_str = "DB": 
    return self.get_connection("DB",self.get_db_client) 
    if decision_str = "SVN": 
    return self.get_connection(decision_str, self.get_svn_client) 

Я не думаю, что вы можете сделать это любой более сжато, чем это, и я не уверен, что это лучше, чем, как Жан ...

0
def get_svn_connection(self, credentials=False): 
    username, pwd=self.get_credentials("SVN") 
    if credentials: 
     return (username, pwd)   
    client=self.get_svn_client(username, pwd) 
    return client 

def get_db_connection(self, credentials=False): 
    username, pwd, url, schema=self.get_credentials("DB") 
    if credentials: 
     return (username, pwd, url, schema) 
    client=self.get_db_client(username, pwd, url, schema) 
    return client 
Смежные вопросы