Фабрика классов Python ... или? - PullRequest
1 голос
/ 07 октября 2008

У нас есть библиотека базы данных в C #, которую мы можем использовать так:

DatabaseConnection conn = DatabaseConnection.FromConnectionString("...");

Эта библиотека скрывает многие различия между различными механизмами баз данных, такими как имена функций SQL, имена параметров и спецификации и т. Д.

Внутренне класс DatabaseConnection является абстрактным классом, реализующим некоторые базовые методы, но метод FromConnectionString проходит через список зарегистрированных специализированных типов, который обрабатывает фактические различия, и создает объект нужного класса. Другими словами, я не получаю объект DatabaseConnection, я получаю взамен объект MSSQLDatabaseConnection или OracleDatabaseConnection, который, конечно, наследуется от DatabaseConnection.

Строка подключения содержит информацию о том, какой тип ядра базы данных и версия этого подключения.

Я бы хотел создать подобную библиотеку в Python. Правильный ли подход к созданию чего-то, что может быть сконструировано таким образом?

conn = DatabaseConnection("...")

или используя метод класса?

conn = DatabaseConnection.FromConnectionString("...")

это первое возможное, то есть ... создание такого объекта и получение чего-то другого, специализированного объекта, в зависимости от данных в переданной строке?

Хорошо, позвольте мне задать другой вопрос ... Что такое pythonic способ сделать это?

Я в основном хочу иметь базовый класс DatabaseConnection также на Python, реализующий общие методы и специализирующийся на производных классах, и где-нибудь иметь метод или функцию, основанную на строках строки соединения и возвращающую правильный тип объекта.

Ответы [ 3 ]

5 голосов
/ 07 октября 2008

Это возможно в Python, но, вероятно, это не лучший способ сделать это. Шаблон фабрики классов - это обходной путь для языков, в которых нет классов первого класса. Поскольку в Python есть классы первого класса, вы можете хранить класс в переменной и использовать этот класс напрямую для создания экземпляров. Чтобы изменить созданный класс, сохраните другой класс в переменной.

Например:

class class1:
  def greet(self):
    print "hi"

class class2:
  def greet(self):
    print "hello"

maker = class1
obj1 = maker()

maker = class2
obj2 = maker()

obj1.greet() # prints "hi"
obj2.greet() # prints "hello"
3 голосов
/ 08 октября 2008

Python не волнует почему вы возвращаете тип.

def DatabaseConnection( str ):   
    if ( IsOracle( str ) ):   
        return OracleConnection( str )  
    else: 
        return SomeOtherConnection( str )
1 голос
/ 07 октября 2008

Первый вариант абсолютно возможен и предпочтителен, на мой взгляд. В Python конструкторов не так много. По сути, они, как и любая другая функция. Я использовал этот шаблон проектирования несколько раз, чтобы указать, что класс не должен создаваться напрямую, например:

def DatabaseConnectionFromString(connection_string)
    return _DatabaseConnection(connection_string)

def DatabaseConnectionFromSomethingElse(something_else)
    connection_string = convert_something_else_into_string(something_else)
    return _DatabaseConnection(connection_string)

class _DatabaseConnection(object):
    def __init__(self, connection_string):
        self.connection_string = connection_string

Конечно, это надуманный пример, но он должен дать вам общее представление.

РЕДАКТИРОВАТЬ: Это также одна из областей, где наследование не совсем так, как в Python. Вы также можете сделать это:

DatabaseConnection(object):
    def __init__(self, connection_string):
        self.connection_string = connection_string

DatabaseConnectionFromSomethingElse(object)
    def __init__(self, something_else):
        self.connection_string = convert_something_else_into_string(something_else)

Извините, что так многословно, но я хотел прояснить.

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