Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Singleton a klasa "statyczna"
menic
post 23.12.2006, 22:55:17
Post #1





Grupa: Zarejestrowani
Postów: 493
Pomógł: 0
Dołączył: 14.06.2003
Skąd: Tomaszów Lubelski/Rzeszów

Ostrzeżenie: (0%)
-----


Mogłby ktoś wytłumaczyć, jaka jest własciwie róznica pomiędzy wzorcem Singleton a tym, ze w klasie mamy wszystkie metody statyczne? Bo jakoś nie moge dojśc co i kiedy stosowac. Wg mnie to nie ma w tym wiekszej różnicy. A co wy sądzicie?


--------------------
Jak masz cos zrobic dobrze...
...To musisz zrobić to sam.

Uchwycić moment...
Go to the top of the page
+Quote Post
2 Stron V   1 2 >  
Start new topic
Odpowiedzi (1 - 19)
Denver
post 24.12.2006, 00:08:40
Post #2





Grupa: Zarejestrowani
Postów: 132
Pomógł: 0
Dołączył: 24.09.2003
Skąd: Giżycko / Wrocław

Ostrzeżenie: (0%)
-----


Różnica jest, i to bardzo wyraźna.

Singleton to wzorzec projektowy gwarantujący Ci, że nigdy nie stworzysz więcej, niż jeden obiekt danej klasy - zawsze będziesz korzystać z tego samego egzemplarza. Zapewnia Ci to prywatny konstruktor danej klasy. Klasa ta nie musi mieć tylko i wyłącznie statycznych metod.

Klasa zawierająca same metody statyczne natomiast to niejako zbiornik funkcji - np. klasa String udostępniająca statyczne metody String::ToUpperCase czy też String::RemoveFirstFiveLetters. Klasa ta operuje tylko i wyłącznie na podanych jej metodom argumentach, i nie posiada własnych (chyba, że statycznych). No i nigdy nie tworzysz żadnego ezgemplarza tej klasy.


--------------------
Go to the top of the page
+Quote Post
hwao
post 24.12.2006, 00:15:31
Post #3


Developer


Grupa: Moderatorzy
Postów: 2 844
Pomógł: 20
Dołączył: 25.11.2003
Skąd: Olkusz




Klasa statyczna posiada statyczne metody, generalnie jest jakby "pojemnikiem" często nie powiązanych ze sobą "funkcji" i przede wszystkim nie posiada instancji ( $obiekt = new Cos() ).

Singleton, posiada zainicjowana klase (obiekt), ba nawet więcej gdyż ten wzorzec jest stosowany wtedy gdy chcemy posiadać tylko jedna instancje danej klasy (tj, wszędzie możemy korzystać tylko z tej klasy, nie istnieje możliwość zainicjowania kolejnej).
Go to the top of the page
+Quote Post
LBO
post 24.12.2006, 00:52:25
Post #4





Grupa: Zarejestrowani
Postów: 1 415
Pomógł: 117
Dołączył: 7.09.2005
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Dodam do wypowiedzi @hwao, że wzorzec singletona jest bardzo pomocny w dużych projektach. Znika wtedy problem przekazywania obiektów (kiedyś to był problem (kopie, referencje itp) np. Klasa odpowiedzialna za połączenie z bazą - zazwyczaj potrzebna tylko jedna, bo aplikacja operuje na jednej bazie danych.
Go to the top of the page
+Quote Post
menic
post 25.12.2006, 14:02:51
Post #5





Grupa: Zarejestrowani
Postów: 493
Pomógł: 0
Dołączył: 14.06.2003
Skąd: Tomaszów Lubelski/Rzeszów

Ostrzeżenie: (0%)
-----


Z teoretycznego punktu widzenia rozumiem. Gorzej z praktycznego


--------------------
Jak masz cos zrobic dobrze...
...To musisz zrobić to sam.

Uchwycić moment...
Go to the top of the page
+Quote Post
hwao
post 25.12.2006, 14:40:00
Post #6


Developer


Grupa: Moderatorzy
Postów: 2 844
Pomógł: 20
Dołączył: 25.11.2003
Skąd: Olkusz




Hm patrz smile.gif

  1. <?php
  2.  
  3. function NewSpace() {
  4. // Jakas nowa przestrzen, tu nie ma zmiennej $Object, z tamtąd
  5. // łapiemy dziada
  6. $Object = Counter::get();
  7.  
  8. echo 'Włączony: '.$Object->getStatus().' razy.'.PHP_EOL;
  9.  
  10. $Object->run();
  11. echo 'Włączony: '.$Object->getStatus().' razy.'.PHP_EOL;
  12.  
  13. }
  14.  
  15. class Counter {
  16. private $i = -1;
  17. private function __construct() {
  18. $this->i = 0;
  19. }
  20.  
  21. private function __clone() {}
  22.  
  23. private static $Instance = null;
  24. public static function get() {
  25. return is_null( self::$Instance ) ? self::$Instance = new Counter() : self::$Instance;
  26. }
  27.  
  28. public function run() {
  29. $this->i++;
  30. }
  31.  
  32. public function getStatus() {
  33. return $this->i;
  34. }
  35. }
  36.  
  37. // Nie darady
  38. //$Object = new Counter();
  39.  
  40. // O, tak lepiej :)
  41. $Object = Counter::get();
  42.  
  43. echo 'Włączony: '.$Object->getStatus().' razy.'.PHP_EOL;
  44.  
  45. $Object->run();
  46. echo 'Włączony: '.$Object->getStatus().' razy.'.PHP_EOL;
  47.  
  48. NewSpace();
  49.  
  50. echo 'Włączony: '.$Object->getStatus().' razy.'.PHP_EOL;
  51.  
  52. ?>

Ciagle operujesz na tym samym obiekcie, nie możesz "powielić".

  1. <?php
  2.  
  3. // Nie darady, prywatny konstrukor
  4. $Object = new Counter();
  5.  
  6. $Object = Counter::get();
  7.  
  8. // Sklonowac dziada tez sie nie da :)
  9. $CloneObject = clone $Object;
  10. ?>


A i rezultat działania (poprawnego).
Kod
Włączony: 0 razy.
Włączony: 1 razy.
Włączony: 1 razy.
Włączony: 2 razy.
Włączony: 2 razy.
Go to the top of the page
+Quote Post
menic
post 25.12.2006, 14:53:58
Post #7





Grupa: Zarejestrowani
Postów: 493
Pomógł: 0
Dołączył: 14.06.2003
Skąd: Tomaszów Lubelski/Rzeszów

Ostrzeżenie: (0%)
-----


Rozumiem smile.gif Ale chodzi mi o róznice w zastosowaniu singletona a statycznych metod. Mam klase która działa na wzorcu singleton oraz działa rownie dobrze z metodami statycznymi. Od czego wiec zalezy jaką technike obrać?


--------------------
Jak masz cos zrobic dobrze...
...To musisz zrobić to sam.

Uchwycić moment...
Go to the top of the page
+Quote Post
Cysiaczek
post 25.12.2006, 16:00:54
Post #8





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




Odpowiedź jest niezwykle prosta - od potrzeb : )

Pozdrawiam.


--------------------
To think for yourself you must question authority and
learn how to put yourself in a state of vulnerable, open-mindedness;
chaotic, confused, vulnerability, to inform yourself.
Think for yourself. Question authority.
Go to the top of the page
+Quote Post
cadavre
post 25.12.2006, 17:57:15
Post #9





Grupa: Zarejestrowani
Postów: 472
Pomógł: 7
Dołączył: 7.12.2005
Skąd: Gliwice

Ostrzeżenie: (0%)
-----


Jednak gdy np. połączenia z bazą, w klasie która obsługuje DB nie ma w konstruktorze, a jest ona wywoływana osobną metodą? Wtedy korzystając ze statyków nie nawiązujemy ciągle nowych połączeń.


--------------------
Silesian PHP User Group - www.spug.pl
Symfony2, OAuth2, budowanie API - masz pytania? Pisz!
Go to the top of the page
+Quote Post
Cysiaczek
post 25.12.2006, 18:04:19
Post #10





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




@cadavre - a singletonem niby tak? Połączenie jest ustawiane raz i potem tylko się do niego odwołujemy, nie ma żadnego kolejnego połączenia. Chyba, że czegoś nie zrozumiałem...

Pozdrawiam.


--------------------
To think for yourself you must question authority and
learn how to put yourself in a state of vulnerable, open-mindedness;
chaotic, confused, vulnerability, to inform yourself.
Think for yourself. Question authority.
Go to the top of the page
+Quote Post
cadavre
post 25.12.2006, 18:38:32
Post #11





Grupa: Zarejestrowani
Postów: 472
Pomógł: 7
Dołączył: 7.12.2005
Skąd: Gliwice

Ostrzeżenie: (0%)
-----


Tak - jak najbardziej jest jak mówisz. Ale porównuję stosowanie statyków i tworzenie nowych instancji bez singletona.


--------------------
Silesian PHP User Group - www.spug.pl
Symfony2, OAuth2, budowanie API - masz pytania? Pisz!
Go to the top of the page
+Quote Post
menic
post 25.12.2006, 20:08:54
Post #12





Grupa: Zarejestrowani
Postów: 493
Pomógł: 0
Dołączył: 14.06.2003
Skąd: Tomaszów Lubelski/Rzeszów

Ostrzeżenie: (0%)
-----


Czyli tak jak sie domyślałem. Ten singleton to taki lekki pic na wode winksmiley.jpg


--------------------
Jak masz cos zrobic dobrze...
...To musisz zrobić to sam.

Uchwycić moment...
Go to the top of the page
+Quote Post
cadavre
post 25.12.2006, 20:35:45
Post #13





Grupa: Zarejestrowani
Postów: 472
Pomógł: 7
Dołączył: 7.12.2005
Skąd: Gliwice

Ostrzeżenie: (0%)
-----


Ja też nie widzę sensu w singletonie. Jeśli zdefiniuję sobie:
  1. <?php
  2. $db = new db();
  3. ?>
to dalej w kodzie będę cały czas używał $db a nie tworzył nowe jej instancje, bo po co? A gdy chcę uzyskać dostęp do klasy db w innych klasach to używam już tylko extends'a i komunikuję się z klasą db poprzez Scope Resolution Operator. Naturalnie połączenie z bazą danych uzyskuję na początku głównego pliku, który ładuje wszystkie moduły etc.

EDIT: Gdy potrzebuję przetestować jakąś klasę, która używa np. połączenia z bazą to używam do tego platformy testowej napisanej przeze mnie samego.

Ten post edytował cadavre 25.12.2006, 20:52:21


--------------------
Silesian PHP User Group - www.spug.pl
Symfony2, OAuth2, budowanie API - masz pytania? Pisz!
Go to the top of the page
+Quote Post
y3ti
post 25.12.2006, 20:52:44
Post #14





Grupa: Zarejestrowani
Postów: 40
Pomógł: 0
Dołączył: 19.08.2004
Skąd: Pruszków

Ostrzeżenie: (0%)
-----


Zgadza się, ale Twój obiekt $db jest zmienną globalną - a przed tym ma właśnie chronić singleton. Powiedzmy, że masz taką sytuację:

  1. <?php
  2. (...)
  3. $db = new DB();
  4.  
  5. class Foo {
  6.  function bar() {
  7.  // $db nie istnieje, musimy korzystać z global
  8.  }
  9. }
  10. ?>


W bar() $db nie istnieje. Musisz wywołać jeszcze raz $db = new DB() - co wiąże się z tym, że będziesz miał dwa takie same obiekty. Możesz również korzystać ze zmiennej globalnej - a fuj nie ładne.

Możesz skorzystać z singletona, który gwarantuje jedną instancje i tylko jedną. Dla przykładu masz klasę Preferences, która przechowuje ustawienia dla całego serwisu. Jeśli klasa X zmieni coś w Preferences to klasa Z musi odczytać tą zmianę (nie mogą być dwa różne obiekty Preferences - może być tylko jeden).

Jednak nadal nie rozumiem, czym się różni funkcjonalnością klasa statyczna od singletona.

Klasa statyczna również:
- nie zezwala na dwie różne wersje objektów
- można przechowywać składowe (np. identyfikator połączenia z bazą danych) - private static
- zachowana jest hermetyzacja

Poza tym korzystanie ze statycznej klasy jest szybsze (nie trzeba pobierać instancji) tj.

  1. <?php
  2. // zamiast 
  3. $db = DB:getInstance();
  4. $db->query(...);
  5.  
  6. // Możemy napisać po prostu
  7. DB:query(...);
  8. ?>
Go to the top of the page
+Quote Post
cadavre
post 25.12.2006, 20:56:44
Post #15





Grupa: Zarejestrowani
Postów: 472
Pomógł: 7
Dołączył: 7.12.2005
Skąd: Gliwice

Ostrzeżenie: (0%)
-----


O właśnie y3ti zauważyłem błąd w swoim poście. Klasy, które używają db tą właśnie klasę extendują i wszystkie procedury wykonywane są poprzez Scope Resolution Operator (:smile.gif. Moje frameworki działają na zasadzie identycznej (o ile się nie mylę) z Zendową - istnieje główna klasa, która jest extendowana przez wszystkie inne - dzięki temu mam dostęp do wszystkich klas.

EDIT:
  1. <?php
  2. (...)
  3. $db = new DB();
  4.  
  5. class Foo {
  6.  function bar() {
  7.  // $db nie istnieje, musimy korzystać z global
  8.  }
  9. }
  10. ?>
Tak samo jeśli pierwszą linijkę zastąpisz przez:
  1. <?php
  2. $db = DB::getInstance();
  3. ?>
bo jak w kolejnej ładowanej klasie uzyskasz dostęp do $db? Również musisz globalować.

Ten post edytował cadavre 25.12.2006, 20:58:47


--------------------
Silesian PHP User Group - www.spug.pl
Symfony2, OAuth2, budowanie API - masz pytania? Pisz!
Go to the top of the page
+Quote Post
y3ti
post 25.12.2006, 21:16:42
Post #16





Grupa: Zarejestrowani
Postów: 40
Pomógł: 0
Dołączył: 19.08.2004
Skąd: Pruszków

Ostrzeżenie: (0%)
-----


Masz rację, ale dzięki singleton możesz stworzyć tylko i wyłącznie jedną instancję obiektu.

Co do różnic pomiędzy singleton a statyczną klasą tak mi coś jeszcze w głowie zaświtało. Gdy taka klasa DB jest finalna to w sumie nie robi różnicy (dla mnie) czy korzystam ze statycznej wersji DB, czy z singletonu.
Jednak co się stanie jeśli będziemy dziedziczyć z DB?
Go to the top of the page
+Quote Post
cadavre
post 25.12.2006, 23:00:28
Post #17





Grupa: Zarejestrowani
Postów: 472
Pomógł: 7
Dołączył: 7.12.2005
Skąd: Gliwice

Ostrzeżenie: (0%)
-----


Cytat
php 5 introduces the final keyword, which prevents child classes from overriding a method by prefixing the definition with final. If the class itself is being defined final then it cannot be extended.


Finalnej klasy nie można extendować - wiadomo. A gdy dziedziczysz z db to po prostu nie możesz zastąpić metod z klasy finalnej metodami, utworzonymi w klasie dziedziczącej. Różnicy pomiędzy singletonem a statykiem w tym momencie nie widzę.

EDIT: U mnie db nie jest finalną, a finalnymi są te, które extendują db i nie są przez nic extendowane. Final nie służy do wersjonowania, a raczej do tego by zabezpieczyć klasę przez jej extendowaniem, a tym samym możliwą podmianą metod. Tzn. ja tak stosuję final. tongue.gif

Ten post edytował cadavre 25.12.2006, 23:02:21


--------------------
Silesian PHP User Group - www.spug.pl
Symfony2, OAuth2, budowanie API - masz pytania? Pisz!
Go to the top of the page
+Quote Post
y3ti
post 25.12.2006, 23:20:34
Post #18





Grupa: Zarejestrowani
Postów: 40
Pomógł: 0
Dołączył: 19.08.2004
Skąd: Pruszków

Ostrzeżenie: (0%)
-----


brrr zagalopowałem się z tymi klasami finalnymi winksmiley.jpg

Chodziło mi, że różnica jest chyba jest jak będziemy dziedziczyć z klasy statycznej albo singleton - obie klasy oczywiście niefinalne smile.gif Chodzi o sposób odwoływania się np. do składowych odziedziczonych po rodzicu.

W sumie różnicy nie widzę w funkcjonalności klasy statycznej a singleton. Mimo to wzorzec singleton wymyśliła mądrzejsza od nas osoba, która na 100% była świadoma istnienia klas statycznych i dla tego singleton musi być lepszym rozwiązaniem - tylko dlaczego? winksmiley.jpg
Go to the top of the page
+Quote Post
cadavre
post 26.12.2006, 00:25:38
Post #19





Grupa: Zarejestrowani
Postów: 472
Pomógł: 7
Dołączył: 7.12.2005
Skąd: Gliwice

Ostrzeżenie: (0%)
-----


Swoją drogą final'e stosuje się raczej w końcowych fazach projektów, rzadko kiedy w dev-time. Oczywiście jeśli dany moduł (np. klasa właśnie) jest gotowy przed innymi to jak najbardziej można zastanowić się nad finalem. Z praktyki jednak wiem, że nawet gotowe moduły często ulegają zmianie.

Big thx 4 PHP5ZP. biggrin.gif


--------------------
Silesian PHP User Group - www.spug.pl
Symfony2, OAuth2, budowanie API - masz pytania? Pisz!
Go to the top of the page
+Quote Post
Denver
post 26.12.2006, 10:28:10
Post #20





Grupa: Zarejestrowani
Postów: 132
Pomógł: 0
Dołączył: 24.09.2003
Skąd: Giżycko / Wrocław

Ostrzeżenie: (0%)
-----


Wydaje mi się, że siłą rzeczy klasa zawierająca same właściwości i metody statyczne będzie po prostu wolniejsza od jej odpowiednika opartego na wzorcu singleton. Radzę porobić testy wydajnościowe, ale intuicja mi mówi, że Singleton po prostu będzie szybszy.


--------------------
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 14.08.2025 - 08:44