Смешиваем singleton и registry

Основное достоинство Одиночки одновременно является и его недостатком. Допустим у нас есть класс для работы с базой данных реализованный на singleton (о ужОс, нужно было хотя бы фабрику). Всё замечательно работает, пока в один непогожий день мы не придумываем держать данные в разных базах на разных серверах. Ну и этого геморроя нам мало, поэтому от возможностей мускула мы отказываемся. И приплыли… Соединение у нас то ОДНО. Отказываться от singleton и перелопачивать тонны кода тоже не с руки, значим поставим костыль.Можно было бы использовать registry, но опять же куча правок и смена Db::getInstance() на Regisrty::get(‘db0’) Regisrty::get(‘db1’). От этой мысли мы возьмём на заметку способ доступа по ключу Db::getInstance(‘db0’) Db::getInstance(‘db1’).

Для этого сделаем $instance массивом, а чтобы не хранить в памяти ключи и не переписывать код Db::getInstance() будем хранить последнее значение в статической переменной $cursor

class Foo {
 private static $instance = array();
 private static $cursor;
 private function __construct() {
 echo 'Created ' . __CLASS__;
 }
 private function __clone() {
 }
 public static function getInstance($cursor = 0) {
 if ($cursor !== null) {
 self::$cursor = $cursor;
 }
 if (!array_key_exists(self::$cursor, self::$instance)) {
 self::$instance[self::$cursor] = new self();
 }
 return self::$instance[self::$cursor];
 }
}
echo 'Foo::getInstance(): ';
$o[] = Foo::getInstance();
echo '<br>Foo::getInstance(): ';
$o[] = Foo::getInstance();
echo '<br>Foo::getInstance(1): ';
$o[] = Foo::getInstance(1);
echo '<br>Foo::getInstance(0): ';
$o[] = Foo::getInstance(0);
var_dump($o);

В итоге мы получим нечто этакое

Foo::getInstance(): Created Foo
Foo::getInstance():
Foo::getInstance(1): Created Foo
Foo::getInstance(0):
array
0 =>
object(Foo)[1]
1 =>
object(Foo)[1]
2 =>
object(Foo)[2]
3 =>
object(Foo)[1]

Создали одну копию у неё индекс «0», при повторном вызове без параметра получаем всё тот же singleton, а когда передали индекс «1», то создался ещё один экземпляр класс Foo, последующие вызовы уже будут работать с ним, пока не переключимся на версию «0» Foo::getInstance(0).

Как бы всё, можете писать свой хайлод или модифицировать старый код.

Смешиваем singleton и registry: 2 комментария

    1. AmdY Автор записи

      Спасибо, наверное после обновления хайлайтера перестал перебиваться стиль темы div.post div.entry code, убрал пока display: block;

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *