Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Rozszerzalny singleton
Forum PHP.pl > Forum > PHP > Object-oriented programming
Orzeszekk
  1. <?php
  2. /**
  3.  * Rozszerzalny singleton.
  4.  *
  5.  * <b>Użycie</b>
  6.  * <ul><li>W każdej klasie pochodnej utwórz protected static $instance</li>
  7.  * <li>Konstruktor kazdej klasy pochodnej musi byc chroniony lub prywatny</li></ul>
  8.  */
  9. class Singleton
  10. {
  11. /** To jest do celow testowych */
  12. protected $nazwa;
  13. protected static $instance;
  14. protected function __construct()
  15. {
  16. }
  17. public static function get()
  18. {
  19. if (!(static::$instance))
  20. {
  21. $className = get_called_class();
  22. $className::$instance = new $className;
  23. }
  24. return static::$instance;
  25. }
  26. public function identify()
  27. {
  28. echo $this->nazwa;
  29. }
  30. }
  31. class Pierwsza extends Singleton
  32. {
  33. public static $instance;
  34. protected function __construct()
  35. {
  36. $this->nazwa = "pierwsza";
  37. }
  38. }
  39. class Druga extends Singleton
  40. {
  41. public static $instance;
  42. protected function __construct()
  43. {
  44. $this->nazwa = "druga";
  45. }
  46. }
  47. class Trzecia extends Druga
  48. {
  49. public static $instance;
  50. protected function __construct()
  51. {
  52. $this->nazwa = "trzecia";
  53. }
  54. }
  55. $pierwsza = Pierwsza::get();
  56. $druga = Druga::get();
  57. $trzecia = Trzecia::get();
  58. $trzecia->identify();
  59. $pierwsza->identify();
  60. $druga->identify();
  61. ?>


Jak go ulepszyc bym nie musial deklarowac w kazdej klasie public static $instance?

jesli usune deklaracje tych zmiennych statycznych z klas to wtedy tworzy mi singleton zamiast klasy tej co trzeba biggrin.gif (ew w przypadku klasy trzecia utworzy mi klase druga).
Sephirus
Hmm no nie dziwne - jeśli nie dasz w każdej klasie $instance to będziesz się z każdej odwoływał zawsze do tego samego smile.gif oto w sumie chodzi w staticach haha.gif

Moim zdaniem powinno się dawać statyczne $intance dla każdej klasy - sama funkcja typu "getInstance" może być dziedziczona. To i tak mniej a na bank będzie działać.

Drugim rozwiązaniem jest zrobienie statycznej tablicy "instancji" - wtedy w get() odwołuj się do $instance[self::$nazwa] - To powinno troszkę pomóc i nie byłoby potrzeby dawać $instance w tych klasach. wink.gif

ALBO:

Zupełnie inne podejście smile.gif Po co robić rozszerzalny singleton, z którego musiała będzie dziedziczyć każda klasa by była singletonem...

Można zrobić inaczej wink.gif Zróbmy tak by dowolna klasa mogła być traktowana jako singleton ;P Zróbmy fabrykę singletonów wink.gif

  1. class singleton
  2. {
  3. protected static $instance = array();
  4.  
  5. private function __construct() {}
  6.  
  7. public static function getInstance($className)
  8. {
  9. if(!isset(self::$instance[$className]))
  10. self::$instance[$className] = new $className;
  11.  
  12. return self::$instance[$className];
  13. }
  14. }
  15.  
  16.  
  17. class a
  18. {
  19. public function identify() { echo 'jestem A!'; }
  20. }
  21.  
  22. class b
  23. {
  24. public function identify() { echo 'jestem B!'; }
  25. }
  26.  
  27. class c
  28. {
  29. public function identify() { echo 'jestem C!'; }
  30. }
  31.  
  32. $a = singleton::getInstance('a');
  33. $b = singleton::getInstance('b');
  34. $c = singleton::getInstance('c');
  35.  
  36. $a->identify();
  37. $b->identify();
  38. $c->identify();


Zamiast używać wtedy a::getInstance(); używamy singleton::getInstance('a'); - to daje nawet więcej możliwości ;P

Co Ty na to?
Orzeszekk
Fabryka singletonow chyba nie zapewnia ze te klasy tworzone jako singletony maja tylko jedna instancje? wciaz mozna je utworzyc konstruktorem.

fabryki singletonow uzywam :] dla klas gdzie musi byc np. po jednej instancji singletona dla kazdego ID, wtedy tez robie taka tablice jak ty. Tylko ze wtedy ta fabryka singletonow jest definiowana w ciele tej samej klasy ktorą zwraca wiec moge zrobic chroniony konstruktor.

Myslalem nad czyms zeby tworzyc static protected $instance zaraz przed wywolaniem konstruktora w singletonie, jakos dynamicznie, ale z tego co widze nie da się.

tablica statyczna $instance chyba jeszcze bardziej spowolni ten singleton bo za kazdym razem trzeba bedzie wywołac funkcje get_called_class.

skoro nie ma lepszego rozwiazania to bede dodawal singletony recznie biggrin.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.