Singleton - filozofia
Wyobraźmy sobie sytuację, w której piszemy klasę obsługi bazy danych. W jej konstruktorze wywoływana jest metoda odczytująca z pliku konfiguracyjnego dane, potrzebne do nawiązania połączenia z bazą. Dla lepszego zobrazowania problemu, załóżmy że plik konfiguracyjny ma strukturę dokumentu XML, którego odczytanie wymaga odwołania się do odpowiednich klas (np. DOMDocument). Dodatkowo niech nasz konstruktor nawiązuje połączenie z bazą, od razu po odczytaniu potrzebnych danych. Jak widzimy, operacji do wykonania jest całkiem sporo.W sytuacji, gdy będziemy musieli odwoływać się do obiektu tej klasy w wielu miejscach, dodatkowo w różnych od siebie plikach naszej aplikacji, każdorazowe tworzenie tego obiektu będzie bardzo nieefektywne. Z logicznego punktu widzenia, najlepszym rozwiązaniem byłoby utworzyć raz instancję tej klasy i używać jej później w miarę potrzeb. Takie rozwiązanie umożliwia właśnie Singleton.
Singleton - implementacja
class Singleton
{
private static $_oInstance = NULL;
private function __construct() { }
private function __clone() { }
public static function getInstance()
{
$className = get_class();
if (is_null(self::$_oInstance)) return self::$_oInstance = new $className;
return self::$_oInstance;
}
}
Implementację Singletonu można opisać w kilku punktach:
- zablokowanie modyfikatorem private konstruktora i metody kopiującej obiekt,
- przygotowanie prywatnego statycznego pola, które będzie przechowywać instancję klasy,
- przygotowanie publicznej statycznej metody getInstance(), która zwracać będzie obiekt - jeżeli jest to pierwsze wywołanie, tworzy obiekt i zwraca go, zapisując do pola statycznego; jeżeli pole statyczne przechowuje już obiekt, metoda zwraca ten właśnie obiekt,
$singleton = Singleton::getInstance();
Dzięki temu mamy zagwarantowane, że zawsze będziemy mieć jedną jedyną instancję określonej klasy (poprzez modyfikator private przy konstruktorze, niemożliwe będzie utworzenie obiektu przy pomocy operatora new).
Plusy i minusy
Główną zaletę Singletonu opisałem w powyższym przykładzie - nasz kod zyskuje na wydajności, dzięki ograniczonej liczbie wywołań konstruktora klasy. Przeciwnicy tego rozwiązania, przedstawiają zawsze jeden główny kontrargument - Singleton ukrywa pod obiektową otoczką zmienną globalną (a jak wiadomo, stosowanie zmiennych globalnych w programowaniu obiektowym jest bardzo nieeleganckie). Dobrze, załóżmy że zgodzimy się z tym argumentem. W tym miejscu zawsze na myśl przychodzi mi bardzo prosta riposta - Ci sami przeciwnicy Singletonu, używają w swoim kodzie zmiennych sesyjnych, które z logicznego punktu widzenia są zmiennymi super globalnymi (!). Nie mam nic przeciwko zmiennym sesyjny (gwoli wyjaśnienia), ich stosowanie jest bardzo powszechne (m.in. w mechanizmach uwierzytelniania). Z tego właśnie punktu widzenia, argumenty przeciwników Singletonu moim zdaniem tracą na znaczeniu.Wzorcem zbliżonym swoją filozofią do Singletonu, jest wzorzec Fabryka, o którym tutaj jeszcze napiszę.












0 komentarze:
Prześlij komentarz