Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Automatyczny singleton.
Koleś
post
Post #1





Grupa: Zarejestrowani
Postów: 48
Pomógł: 0
Dołączył: 3.03.2007

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


Cześć. Kiedyś programując w C++ nauczyłem się pisać ciekawy wzorzec, który nazywał się automatycznym singletonem. Swoją "automatyczność" zawdzięcza temu, że można po nim odziedziczyć podając jako parametr szablonu nazwę klasy pochodnej (dziedziczącej). IMHO takie rozwiązanie jest o wiele wygodniejsze. Pomyślałem, że można coś takiego napisać w PHP:

  1. <?php
  2. class Singleton
  3. {
  4. protected static $type = false;
  5.  
  6. protected function __construct() {}
  7. public function SetType( $type_ )
  8. {
  9. self::$type = $type_;
  10. }
  11.  public static function Instance()
  12.  {
  13. static $instance;
  14. if( ! self::$type )
  15. {
  16. throw new Exception( 'Po Singletonie należy odziedziczyć' );
  17. }
  18. if( ! isset( $instance ) ) $instance = new self::$type;
  19. return $instance;
  20.  }
  21. }
  22. ?>


  1. <?php
  2. class Test extends Singleton
  3. {
  4. public function Show() { echo 'abcd <br />'; }
  5. }
  6. ?>


  1. <?php
  2. Test::SetType( 'Test' );
  3. Test::Instance()->Show();
  4. ?>


Co o tym sądzicie?
Go to the top of the page
+Quote Post
Turgon
post
Post #2





Grupa: Zarejestrowani
Postów: 800
Pomógł: 0
Dołączył: 26.11.2005
Skąd: Nowy Sącz

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


Po co dawać setType przecie zasadniczo, to działa bez naszej pomocy. Wystarczy dać self.
Według mnie to powinno być tak:
  1. <?php
  2. class Singleton
  3. {
  4. protected static $instance;
  5.  
  6. protected function __construct() {}
  7. public static function Instance(){
  8. if( !isset(self::$instance)) self::$instance = new self();
  9. return self::$instance;
  10.  }
  11. }
  12. ?>


Nie testowałem (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Ale potem robisz tylko:

  1. <?php
  2. class Tester extends Singleton{
  3.  public function showTest(){
  4. echo 'My name is '.get_class().' and I am using singleton! ';
  5.  }
  6. }
  7. ?>


  1. <?php
  2. Tester::Instance()->showTest();
  3. ?>
Go to the top of the page
+Quote Post
SongoQ
post
Post #3





Grupa: Przyjaciele php.pl
Postów: 2 923
Pomógł: 9
Dołączył: 25.10.2004
Skąd: Rzeszów - studia / Warszawa - praca

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


@Koleś Tutaj czegos takiego nie masz. Singleton to singleton, przyklad masz w manualu bo co na sile kombinowac.
Go to the top of the page
+Quote Post
Koleś
post
Post #4





Grupa: Zarejestrowani
Postów: 48
Pomógł: 0
Dołączył: 3.03.2007

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


Cytat(Turgon @ 4.03.2007, 11:27:14 ) *
Wystarczy dać self.

Aha, dzięki, nie wiedział, że to jest możliwe (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif)
Cytat(SongoQ @ 4.03.2007, 11:45:32 ) *
@Koleś Tutaj czegos takiego nie masz. Singleton to singleton, przyklad masz w manualu bo co na sile kombinowac.

Po to, żeby nie trzeba było pisać tego samego kodu w kilku klasach.
Go to the top of the page
+Quote Post
Athlan
post
Post #5





Grupa: Developerzy
Postów: 823
Pomógł: 12
Dołączył: 18.12.2005

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


@Turgon, mala przyczepka (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif) Linia 8 Twojego kodu mogłaby wyglądać tak:

  1. <?php
  2. if(!(self::$instance instanceof self)) self::$instance = new self();
  3. ?>


Kiedyś byłem bliski przypadkowi, że zamieniam statyczną $instance i się dziwiłem dlaczego mam errora, a instancja jest w środku... po prostu to nie była instancja (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
Turgon
post
Post #6





Grupa: Zarejestrowani
Postów: 800
Pomógł: 0
Dołączył: 26.11.2005
Skąd: Nowy Sącz

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


Wolnoć Tomku w swoim domku !

Dla mnie nie ma większej różnicy powiem szczerze (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
splatch
post
Post #7





Grupa: Zarejestrowani
Postów: 487
Pomógł: 7
Dołączył: 7.01.2004
Skąd: Warszawa

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


Co do singletonu jako wzorca mam kilka zastrzeżeń.

Dziedziczenie singletonów w PHP nie działa, ponieważ odwołanie do self w metodzie zawsze tyczy się klasy, w której ta metoda została zaimplementowana. Przykład:
  1. <?php
  2.  
  3. class HelloWorld {
  4.  
  5. protected static $_oInstance = null;
  6. protected $_sUniqueIdentyficator = null;
  7.  
  8. protected function __construct() {
  9. $this->_sUniqueIdentyficator = md5( sha1( time() * rand(1, 999) ) );
  10. }
  11.  
  12. public static function Instance() {
  13. if(!self::$_oInstance instanceof self)
  14. self::$_oInstance = new self;
  15. return self::$_oInstance;
  16. }
  17.  
  18. public function SayHello() {
  19. echo 'Hello World! ID: ' . $this->_sUniqueIdentyficator ."n";
  20. }
  21. }
  22. class HelloWorldChildren extends HelloWorld {
  23.  
  24. public function SayHello() {
  25. echo 'Childern says hello World! ID: ' . $this->_sUniqueIdentyficator ."n";
  26. }
  27. }
  28. $oHello1 = HelloWorld::Instance();
  29. $oHello1->SayHello();
  30.  
  31. $oHello2 = HelloWorld::Instance();
  32. $oHello2->SayHello();
  33.  
  34. $oHello3 = HelloWorldChildren::Instance();
  35. $oHello3->SayHello();
  36.  
  37. $oHello4 = HelloWorldChildren::Instance();
  38. $oHello4->SayHello();
  39.  
  40. echo get_class($oHello1) ."n";
  41. echo get_class($oHello3);
  42.  
  43. ?>


W ogóle ten temat to pomyłka, i to dość spora, ktoś pisze o implementacji singletonu w PHP...
Go to the top of the page
+Quote Post
hwao
post
Post #8


Developer


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




Brak uniemożliwienia klonowania obiektu.

Czemu klasa nie jest abstrakcyjna? Nie był by potrzebny ten Exception().

Swoją drogą lepiej już napisać obiekt rejestru/fabryki w którym była by przechowywana i tworzona jedna instancja danej klasy.
Go to the top of the page
+Quote Post
Athlan
post
Post #9





Grupa: Developerzy
Postów: 823
Pomógł: 12
Dołączył: 18.12.2005

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


@splatch, o widzę przykład z mojego bloga (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif)

http://athlan.vgroup.pl/singleton-registry-map/

Cytat
Dziedziczenie singletonów w PHP nie działa, ponieważ odwołanie do self w metodzie zawsze tyczy się klasy, w której ta metoda została zaimplementowana.


Mój przykład wyświetla coś innego, sprzecznego z Twoją wypowiedzią:

Kod
Hello World! ID: 90593c18e926b6f8cc33b261b02201a7
Hello World! ID: 90593c18e926b6f8cc33b261b02201a7
Hello World! ID: 90593c18e926b6f8cc33b261b02201a7
Hello World! ID: 90593c18e926b6f8cc33b261b02201a7
HelloWorld
HelloWorld


Ten post edytował Athlan 9.03.2007, 23:39:27
Go to the top of the page
+Quote Post
Turgon
post
Post #10





Grupa: Zarejestrowani
Postów: 800
Pomógł: 0
Dołączył: 26.11.2005
Skąd: Nowy Sącz

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


Athlan: Tak bez obrazy, ale twój przykład potwierdza kolega o nie dziedziczeniu. Ja tylko klasę przerobiłem na PHP i nie testowałem w ogóle...
Go to the top of the page
+Quote Post
Athlan
post
Post #11





Grupa: Developerzy
Postów: 823
Pomógł: 12
Dołączył: 18.12.2005

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


Cytat
Athlan: Tak bez obrazy, ale twój przykład potwierdza kolega o nie dziedziczeniu. Ja tylko klasę przerobiłem na PHP i nie testowałem w ogóle...

Jak to o NIE dziedziczeniu?

Skoro rodzic "wykonuje" instację samego siebie, a dziecko które próbuje wykonać instancję i posiada instancję taką, jaką postada rodzic to singleton jest dziedziczony (przekazywany dziecku). (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

Ten post edytował Athlan 10.03.2007, 19:16:09
Go to the top of the page
+Quote Post
splatch
post
Post #12





Grupa: Zarejestrowani
Postów: 487
Pomógł: 7
Dołączył: 7.01.2004
Skąd: Warszawa

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


Cytat(Athlan @ 10.03.2007, 19:15:30 ) *
Jak to o NIE dziedziczeniu?

Skoro rodzic "wykonuje" instację samego siebie, a dziecko które próbuje wykonać instancję i posiada instancję taką, jaką postada rodzic to singleton jest dziedziczony (przekazywany dziecku). (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

Nie. self jest zależny od kontekstu metody. Jeśli metoda Instance() jest zadeklarowana w klasie HelloWorld to odnosi się do HelloWorld. Jeżeli zatem odwołujesz się do HelloWorldChildren::Instance nie nadpisując tej metody to kontekst się nie zmienia i jest to wciąż HelloWorld. W Javie odwołania statyczne np są zawsze zależne od klasy z której wywołanie następuje, czyli w HelloWorld.Instance() zwróci instancję HelloWorld i logicznie HelloWorldChildren.Instance() zwróci instancję HelloWorldChildren.

Zwróć uwagę, że $this zachowuje się inaczej i nie jest zależne od metody a od klasy. To jest po prostu bug w PHP. W metodzie statycznej nie jesteś w stanie pobrać nazwy klasy, z której została ona wywołana.
Go to the top of the page
+Quote Post
UDAT
post
Post #13





Grupa: Zarejestrowani
Postów: 442
Pomógł: 0
Dołączył: 27.12.2005

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


Cytat(keo @ 27.06.2007, 21:57:24 ) *
zgadzam sie w 100%

Po co przytakujesz wypowiedzi sprzed 4 miesięcy?


A co do automatycznego singletona -> można to zrobić w prosty sposób za pomocą programowania aspektowego. Przykład takiego użycia umieściłem na blogu, gdyż zajęłoby to zbyt dużo miejsca na forum.
Go to the top of the page
+Quote Post
NuLL
post
Post #14





Grupa: Zarejestrowani
Postów: 2 262
Pomógł: 21
Dołączył: 3.05.2004
Skąd: Sopot, Krakow, W-wa

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


Cytat
Po co przytakujesz wypowiedzi sprzed 4 miesięcy?

Mowisz sam do siebie ? (IMG:http://forum.php.pl/style_emoticons/default/snitch.gif)

Mowiac prawde UDAT ten twoj pomysl jest niewiele wart bo malo ktory admin poinstaluje ci rozszerzenia PECL ktore chcesz.
Go to the top of the page
+Quote Post
UDAT
post
Post #15





Grupa: Zarejestrowani
Postów: 442
Pomógł: 0
Dołączył: 27.12.2005

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


To rozszerzenie wymagane jest tylko podczas łączenia aspektów z kodem klas. Do uruchomienia samych klas nie jest potrzebne - tak więc możesz używać powstałego kodu na dowolnym hostingu.


Cytat(NuLL @ 29.06.2007, 11:27:22 ) *
Mowisz sam do siebie ? snitch.gif

Kto usunął tego posta? (IMG:http://forum.php.pl/style_emoticons/default/blinksmiley.gif)

Ten post edytował UDAT 29.06.2007, 12:14:10
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 24.08.2025 - 00:21