Wzorzec singleton należy do wzorców konstrukcyjnych. Służy on do ograniczania możliwości tworzenia obiektów danej klasy do jednej instancji oraz zapewniania globalnego punktu dostępu do niej. Wzorzec ten jest krytykowany ze względu na zbyt częste traktowanie go jako zamiennika dla zmiennych globalnych powszechnie uznawanych za niekorzystne.

Implementacja wzorca singleton:

PHP:
  1. class Singleton
  2. {
  3.     /**
  4.      * Obiekt instancji
  5.      *
  6.      * @var object
  7.      * @access private
  8.      * @static
  9.      */
  10.     static private $_instance;
  11.    
  12.     /**
  13.      * Konstruktor klasy
  14.      *
  15.      * @access private
  16.      */
  17.     private function __construct()  { }
  18.  
  19.     /**
  20.      * Metoda klonujaca
  21.      *
  22.      * @access private
  23.      */
  24.     private function __clone() { }
  25.    
  26.     /**
  27.      * Metoda zwraca instance obiektu
  28.      *
  29.      * @static
  30.      * @return object
  31.      */
  32.     static function getInstance()
  33.     {
  34.         if(!self::$_instance) {
  35.             self::$_instance = new self();
  36.         }
  37.         return self::$_instance;
  38.     }
  39.  
  40.     function foo()
  41.     {
  42.         // [...]
  43.     }
  44. }

Kluczowym elementem jest statyczna metoda getInstance(), która sprawdza istnienie prywatnej zmiennej statycznej $_instance. Jeśli zmienna ta nie istnieje wywoływany jest konstruktor klasy i do zmiennej jest przypisywany jej obiekt co zapobiega wielokrotnemu tworzeniu jej instancji. Jeśli obiekt klasy istnieje jest po prostu zwracany przez referencję. Dzięki temu, iż zarówno konstruktor jak i metoda __clone są prywatne nie ma możliwości ich wywołania spoza klasy co jest dodatkowym zabezpieczeniem przed próbą utworzenia obiektu bądź jego sklonowaniem.
Przykład wykorzystania:

PHP:
  1. Singleton::getInstance()->foo();

Najpierw pobieram instancję klasy Singleton a następnie wywołuję metodę foo().

Jak wspomniałem na początku wzorzec ten często uznawany jest za antywzorzec ponieważ bywa wykorzystywany jako zamienni dla zmiennych globalnych. Dlatego powinien być stosowanych tylko w określonych przypadkach głównie związanych z wydajnością np. pobieranie jednej instancji obiektu bazy danych ze względów na czas połączenia z bazą, oszczędność zasobów pamięci itp.

Więcej o wzorcu singleton:
http://pl.wikipedia.org/wiki/Wzorzec_singletonu
http://4programmers.net/PHP/Wzorce_Projektowe#id-Singleton
http://www.phppatterns.com/docs/design/singleton_pattern
http://www.fluffycat.com/PHP-Design-Patterns/Singleton
http://www.vincehuston.org/dp/singleton.html

Leave a Reply

You must be logged in to post a comment.