Блог о программировании

Singleton на PHP

 22 ноября 2015 г. 22:24

Синглтон – это, наверное, самый простой из шаблонов проектирования, и в то же время, самый распространенный. Его часто используют для создания подключения к БД, логирования событий, использования конфигурационного файла и по многим-многим другим причинам. Цель этого шаблона - гарантировать существование единственного экземпляра класса (такие экземпляры и называются синглтонами). Причина, по которой обычно он создается: обеспечить доступ к синглтону всему приложению.

Дело в том, что при разработке кода в ООП стиле следует избегать глобальных переменных. И чтобы не использовать их в проекте и был придуман этот шаблон.

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


Для начала объявим класс Singleton с приватным конструктором:

class Singleton {
	private function __construct() {
	}
}

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

class Singleton {
	public static function getInstance() {
		return new self();
	}

	private function __construct() {
	}
}

Так, теперь мы можем создавать множество экземпляров объекта вызовом статической функции. Но ведь нам нужен все один экземпляр. Тогда нужно каким-то образом контролировать создание экземпляров объекта. Это делается просто: объявляется статическая приватная переменная, которая по-умолчанию ничему не равна. При вызове статического метода Singleton::getInstance() проверяется на наличие значения у статической переменной. Если значение не установлено – то создаем объект и возвращаем его, если же значение переменной уже установлено – то возвращаем его. Вот так:

class Singleton {
	private static $_instance;
	public static function getInstance() {
		if (is_null(self::$_instance)) {
			self::$_instance = new self();
		}
		return self::$_instance;
	}

	private function __construct() {
	}
}

Всё! Синглтон готов. Теперь при обращении к статическому методу Singleton::getInstance() всегда будет возвращаться один и тот же объект. Однако, наш объект по прежнему можно склонировать, и тем самым породить такой же стинглтон, что противоречит концепции. Исправим это объявлением метода __clone приватным.

class Singleton {
	private static $_instance;
	public static function getInstance() {
		if (is_null(self::$_instance)) {
			self::$_instance = new self();
		}
		return self::$_instance;
	}

	private function __construct() {
	}

	private function __clone() {
	}
}

Теперь точно все.

Выводы

Шаблон Синглтон очень похож на глобальные переменные: и тем и другим часто злоупотребляют. Также при использовании синглтона могут получиться такие зависимости, которые будут усложнять отладку приложения. А если в таком случае изменится синглтон, то придется проверять все места его использования. Однако главное отличие синглтона от глобальной пемеренной: его значение нельзя никак затереть. И хотя бы наличие этого факта говорит за приоритетность его использования.

В общем, как и всегда, если грамотно его использовать – он принесет одну лишь пользу.

Поделиться статьей

Оставить комментарий