如何重构类似的方法?

时间:2017-01-16 08:38:53

标签: python oop design-patterns refactoring

我开发了一个管理外部资源连接的类。它的职责是从给定的源读取凭据并返回经过身份验证的连接,例如:

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_credentialsget_db_credentials等等。它看起来非常多余,所以我想重构这个结构。 我的想法是:

  1. 为每种连接类型创建子类,并为每个连接类型定义方法get_connectionget_credentials。问题是:1)我想要一个班级来统治所有的联系; 2)我将不得不使用多继承(可能在Python中,但在Java中不起作用 - 如果我将来会遇到这个问题)

  2. 创建方法get_connection(type)get_credentials(type),并为字符串返回的每个已知连接类型返回相应的实例。问题是我必须创建一个在OOP中认为不好的开关。

  3. 使用元编程为每种连接类型生成方法。不明显且特定于Python。

    你会如何设计?

3 个答案:

答案 0 :(得分:0)

您可以拥有Credentials类,该类可用于验证另一个函数调用:

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)

答案 1 :(得分:0)

只需添加Jean-Francois Fabre的答案,您可以通过以下方式执行一项功能

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)

我认为你不能简单地做到这一点,而且我不相信它比Jean的方式更好......

答案 2 :(得分: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