Фабрика Singleton для управления и упаковки нескольких объектов базы данных

Я создаю приложение PHP, которое должно взаимодействовать с несколькими структурно идентичными базами данных. Я хотел бы использовать singleton factory для раздачи подключений к базам данных и минимизировать количество дублирующихся подключений. Я также хотел бы обернуть класс базы данных несколькими функциями.

Было бы крайне удобно, если бы я мог делать все это в одном классе. Я попытался использовать singleton factory (в то время это казалось хорошей идеей), только чтобы понять, что, похоже, он должен возвращать другие классы, чтобы быть полезными. Есть ли простой способ объединить одноэлементную фабрику и функциональность упаковки базы данных, или я должен просто поместить функции упаковки базы данных в другой класс?

static private $instance = array();

private function __construct($name) {
    switch ($name) {
        //select db connection
    }

    $this->db = $this->getDb();
    return;
}

protected function __clone() {

}

public static function singleton($name) {
    if (!isset(self::$instance[$name])) {
        $c = __CLASS__;
        self::$instance[$name] = new $c($name);
    }
    return self::$instance[$name];
}

public function wrapperFunction() {
    //stuff
}

person James    schedule 20.07.2010    source источник
comment
смотрели интерфейсы? :)   -  person nathan    schedule 21.07.2010
comment
Пожалуйста, объясните часть о дублирующих соединениях. Собираетесь ли вы подключаться к одной и той же базе данных для выполнения нескольких задач в рамках одного процесса? Расскажите нам немного подробнее о том, чем вы занимаетесь.   -  person GoalBased    schedule 21.07.2010
comment
Если бы я это сделал, похоже, я бы разделил относительно короткий фрагмент кода на два класса. Кроме того, зачем использовать интерфейс вместо универсального класса-оболочки?   -  person James    schedule 21.07.2010
comment
@GoalBased Это система, в которой пользователи, использующие один и тот же интерфейс, будут подключаться к нескольким разным базам данных с одинаковым макетом таблицы, но разными данными. Если несколько пользователей подключаются к одной и той же базе данных, я хотел бы повторно использовать это соединение.   -  person James    schedule 21.07.2010
comment
Кажется, я понимаю, что вы пытаетесь сделать... скажите, правильно ли это: вы создаете класс-оболочку для чего-то вроде mysqli, который добавит пользовательские функции. Другими словами, вы расширяете существующий класс БД. Кроме того, вам нужен фабричный класс, который будет раздавать экземпляры вашего нового класса. Это правильно?   -  person GoalBased    schedule 21.07.2010
comment
Я спросил, есть ли простой способ сделать и то, и другое в одном классе.   -  person James    schedule 21.07.2010
comment
Я думаю, вам нужно создать два отдельных класса. Первый класс расширяет класс базы данных, второй класс создает, распространяет и поддерживает экземпляры первого класса. Я думаю, вы найдете этот способ столь же удобным, как и попытка сделать все это в одном классе. Сказав это, я не думаю, что вам нужно создавать свой собственный фабричный класс для эффективного повторного использования соединений с базой данных; Я думаю, что постоянные соединения mysqli должны неплохо с этим справиться.   -  person GoalBased    schedule 21.07.2010
comment
[a] Он добавляет еще один очень короткий класс для отслеживания (увеличивает умственную нагрузку), так что это не так удобно; поэтому я и задал вопрос. [b] Я не использую mysqli, читайте теги. [c] Фабрика по-прежнему остается одним из самых простых способов раздавать связи; Я предполагаю, что вы жалуетесь на одноэлементную часть. Синглтон также упрощает закрытие неиспользуемых соединений.   -  person James    schedule 21.07.2010


Ответы (2)


Я делаю что-то подобное довольно часто (например, управление несколькими подключениями к базе данных по имени). Единственное изменение, которое я предлагаю, — сделать конструктор и массив $instance защищенными. Причина в том, что таким образом становится НАМНОГО проще тестировать (поскольку вы можете расширить его с помощью класса-оболочки, чтобы иметь доступ к ним, а также создавать и уничтожать экземпляры по мере необходимости). Конечно, это открывает возможность сделать это в приложении, но зачем отказываться от возможности управления экземплярами из дочернего класса?

Всего лишь мои 0,02 доллара...

person ircmaxell    schedule 20.07.2010

Похоже, что это, вероятно, было бы возможно, используя некоторые переменные состояния класса и делая некоторые умные вещи с func_num_args и func_get_arg в конструкторе.

Однако в интересах сокращения количества WTF в минуту я пойду с предложением GoalBased разделить вещи на два класса.

person James    schedule 21.07.2010