PHP, преимущества синглтона

12
M
На сайте с 03.02.2017
Offline
0
3153

Изучаю некоторые коды и вижу использования синглтонов там, где, как мне кажется, они не нужны (или не понимаю из за недостатка опыта). Это стало как правилом хорошего тона. Например, в том же классе БД. Причем зачем то используется такая конструкция $class::getInstance()->method1() вместо $class::method1(). Зачем делать метод публичным и обращаться к нему через инстанс если его можно сделать статичным? Может это снижение нагрузки? Или с целью наследования? Как понимаю, для бд синглтон нужен лишь тогда, когда необходима работа с несколькими базами данных (создавать экземляры класса). Или зачем использовать синглтон для User, если пользователь он только один. Из очевидных преимуществ я пока вижу возможность реализовать несколько методов одной строкой, например, так $class::getInstance()->method1()->method2()->method2().

Поделитесь опытом, кто использует синглтоны и для каких задач.

bay_ebook
На сайте с 28.05.2010
Offline
111
#1
mdevelop:
Изучаю некоторые коды и вижу использования синглтонов там, где, как мне кажется, они не нужны (или не понимаю из за недостатка опыта). Это стало как правилом хорошего тона. Например, в том же классе БД. Причем зачем то используется такая конструкция $class::getInstance()->method1() вместо $class::method1(). Зачем делать метод публичным и обращаться к нему через инстанс если его можно сделать статичным? Может это снижение нагрузки? Или с целью наследования? Как понимаю, для бд синглтон нужен лишь тогда, когда необходима работа с несколькими базами данных (создавать экземляры класса). Или зачем использовать синглтон для User, если пользователь он только один. Из очевидных преимуществ я пока вижу возможность реализовать несколько методов одной строкой, например, так $class::getInstance()->method1()->method2()->method2().

Поделитесь опытом, кто использует синглтоны и для каких задач.

Ух. расписывать не буду. Скажу только - что синглтон для БД нужен всего для ОДНОЙ вещи - что бы подключаться к БД один раз, а не делать 100 подключений из каждого файла. На этом работа синглитона с БД заканчивается)

Нужен прогер на php+mysql+понимание чужего кода? (/ru/forum/540660) Вам сюда PHP-шаман (http://php-shaman.pw/)
danforth
На сайте с 18.12.2015
Offline
153
#2

Несколько методов одной строкой реализуется через возврат $this в методе.

Паттерн синглтон это признак дурно-пахнущего кода. Зачем User-у синглтон, вообще не понимаю. Видимо, кто-то начитался паттернов и налепил их куда не надо, как я писал тут.

Junior Web Developer
Aisamiery
На сайте с 12.04.2015
Offline
314
#3
danforth:

Паттерн синглтон это признак дурно-пахнущего кода.

По вашей ссылочке есть не только определение термина, но и его описание. Ткните пальцем, где там про синглтон?

Рукожопые программисты всегда пишут дурнопахнущий код и паттерны тут как бы не при чем от слова совсем. Прикратите нести эту ересь в массы, микроскопом гвозди тоже не заколачивают, но об этом никто не кричит. Проблема синглтона только в одном, он самый просто в реализации паттерн и его начали пихать туда, где для него небыло места, от туда и пошло понятие антипаттерна в реализации, потому что в умы рукожопых программистов проще вложить это, чем объяснить где его стоит использовать, а где нет.

Разработка проектов на Symfony, Laravel, 1C-Bitrix, UMI.CMS, OctoberCMS
Solmyr
На сайте с 10.09.2007
Offline
501
#4

Ну и с БД и с юзерами все не так однозначно.

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

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

M
На сайте с 03.02.2017
Offline
0
#5
danforth:
Несколько методов одной строкой реализуется через возврат $this в методе.

А если нужно передать параметры, например, так: singlton::getInstance()->setvars($_GET, $_POST);

danforth
На сайте с 18.12.2015
Offline
153
#6
Aisamiery:
По вашей ссылочке есть не только определение термина, но и его описание. Ткните пальцем, где там про синглтон?

Анкор ссылки видите? Там определение дурно-пахнущего кода.

Понятие антипаттерна заркепилось из-за:

1) Проблемы с тестированием.

2) Непрозрачная структура зависимостей: синглтон не передается параметром в метод, он вызывается изнутри через getInstance();

3) Нарушением S акронима SOLID, управляет своим жизненным циклом сам, невозможно уничтожить (а даже если и сделать метод-деструктор, то появляется зависимость от состояния системы - кто вызвал, когда инстанс был создан, кем, для чего, а может он уже вообще не нужен?).

4) Порождает высокую связанность системы, которая полностью опирается на этот синглтон. Можете поискать в проекте с хотя бы синглтоном количество вызовов getInstance();

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

M
На сайте с 03.02.2017
Offline
0
#7

синглтон для БД нужен всего для ОДНОЙ вещи - что бы подключаться к БД один раз, а не делать 100 подключений из каждого файла.

я не понимаю как можно подключаться 100 раз. Мы же подключаемся в __construct, ссылку на подключение сохраняем в переменной класса (это нужно для mysqli), а дальше уже из методов вызываем, например mysqli_query(self::$dblink, self::parse($query) ).

может имеется ввиду создание экземпляра класса БД в других классах? так мы же используем статику и вызов и из других классов уже происходит без подключения, например, так db::query($q); Статические методы и так доступны из всех классов.


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

Я думаю дело в том, что большинство мануалов по синглтонам бестолковые. Там пишут что то вроде "подключаться к БД один раз, а не делать 100 подключений из каждого файла" и программист думает "ну тогда я и статическим классом обойдусь". Про реальные преимущества синглотнов мало инфы.

Пока для себя нашел два. Это такая конструкция, например, data::get()->settings($param)->tree($param).

Второе преимущество: возможность наследовать классы. Например, если у нас есть расширенная версия класса Login с подключением через социальные сети, допустим, LoginSoc, тогда мы его объединяем с общим классом Login. Наличие статически методов в этом случае создает дополнительные сложности.

Aisamiery, а вы используете синглтоны, если да, то как и где?

danforth
На сайте с 18.12.2015
Offline
153
#8
mdevelop:
А если нужно передать параметры, например, так: singlton::getInstance()->setvars($_GET, $_POST);

Невижу никаких сложностей

<?php

class Calculator
{
private $value;

public function sum(int $a, int $b) : Calculator
{
$this->value = $a + $b;
return $this;
}

public function sqrt() : Calculator
{
$this->value = sqrt($this->value);
return $this;
}

public function show() : float
{
return $this->value;
}
}

class Singleton
{
private static $instance = null;

public static function getInstance()
{
if (self::$instance === null) {
self::$instance = new Calculator();
}
return self::$instance;
}

private function __construct(){}
private function __destruct(){}
private function __clone(){}

}

// Pipe example
echo (Singleton::getInstance())->sum(3, 6)->sqrt()->show(); // sqrt(9) = 3
echo '<br>';
echo (Singleton::getInstance())->show(); // 3
M
На сайте с 03.02.2017
Offline
0
#9
danforth:
Невижу никаких сложностей

Или я вас не понял или вы меня.

Я имел ввиду, например, что вместо

$class = new Class();

$class->vars($get); (или class::vars($get))

Можно написать

$class::getInstance()->vars($get);

Но у меня три паттерна, а не один общий. В моем случае это выглядит так:

Data::get()->page($_SERVER['REQUEST_URI']);

Т.е. это как довод в пользу использования Синглтона.

-----

Наличие статических методов создает проблемы при наследовании классов или создании экземпляров класса. Как раз и для такой ситуации может пригодиться синглтон.

С юзерами - один экземпляр класса юзер - это конкретно сейчас залогиненный юзер, а второй экземпляр класса юзер - это экземпляр класса над которым производится действие. Например залогиненный админ банит некоторого юзера.
AP
На сайте с 12.06.2015
Offline
74
#10
danforth:
Невижу никаких сложностей
<?php


class Calculator
{
private $value;

public function sum(int $a, int $b) : Calculator
{
$this->value = $a + $b;
return $this;
}

public function sqrt() : Calculator
{
$this->value = sqrt($this->value);
return $this;
}

public function show() : float
{
return $this->value;
}
}

class Singleton
{
private static $instance = null;

public static function getInstance()
{
if (self::$instance === null) {
self::$instance = new Calculator();
}
return self::$instance;
}

private function __construct(){}
private function __destruct(){}
private function __clone(){}

}

// Pipe example
echo (Singleton::getInstance())->sum(3, 6)->sqrt()->show(); // sqrt(9) = 3
echo '<br>';
echo (Singleton::getInstance())->show(); // 3

Круто. В одной функции передаем параметры в виде аргументов


public function sum(int $a, int $b)
$this->value = $a + $b;

во втором случае используем свойство


public function sqrt()
$this->value = sqrt($this->value);

Потом это вырастет в большую путаницу и необходимость лезть в сам класс разбираться, как надо передавать параметры в функцию.

12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий