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

Шаблон проектирования "Одиночка"(Pattern Singleton).

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

Шаблон проектирования "Одиночка" или Pattern Singleton нужен для того, чтобы у нас не было много однотипных объектов, а всегда использовался только один. В качестве примера можно привести класс для работы с базой данных.

class DB {
  protected $db;

  public function __construct() {
   $this->db = new Mysqli($host, $user, $pass, $database);
  }

  public function get() {}
  public function set() {}
  public function del() {}
}

$db1 = new DB();
$db2 = new DB();

У нас уже 2 объекта $db1 и $db2, а потом кто-нибудь, не зная, что уже есть такой объект, создаст третий и т.д. Это очень плохо сказывается на производительности и читаемости кода, а в нашем случае может произойти сбой, т.к. на хостинге ограниченное количество подключений к базе данных.

Чтобы решить эту проблему, и был придуман паттерн singleton.

class DB {
  protected $db;
  static private $instance = null;

  private function __construct() {
   $this->db = new Mysqli($host, $user, $pass, $database);
  }

  private function __clone() {}

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

$db = new DB(); // ошибка

$db = DB::getInstance();
$db2 = DB::getInstance();
$db3 = DB::getInstance();

Чтобы создать объект обычным способом было нельзя, мы делаем наш конструктор приватным, но также не забываем и про то, что объекты могут клонироваться и закрываем также метод __clone. Дальше мы создаём статическое свойство $instance, которое по умолчанию равно null. Теперь создаём статический метод getInstance(), который проверяет, равно ли наше статическое свойство null? Если да, то мы создаём экземпляр нашего объекта и возвращаем его, а если же нет, то просто возвращаем его. Таким образом, у нас всегда будет один и тот же экземпляр, сколько бы мы их не создавали. Использовать его очень просто: присваиваем переменной значение, которое возвращает статический метод getInstance(), класса DB, а дальше работаем, как и с обычным объектом.

Итак, сегодня вы узнали, что такое паттерн singleton, а, главное, зачем он нужен и где его применять.