Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: singleton i dziedziczenie
Forum PHP.pl > Forum > PHP > Object-oriented programming
ksiadz
mam problem z singletonem przez dziedziczenie a mianowicie napisalem taki kod
  1. <?php
  2.  
  3. class system
  4. {
  5. protected static $instance;
  6.  
  7. protected function __construct()
  8. {}
  9.  
  10. public static function get_instance()
  11. {
  12. if( self::$instance === false )
  13. {
  14. self::$instance = new self();
  15. }
  16.  
  17. return self::$instance;
  18. }
  19. }
  20.  
  21. class innysystem extends system
  22. {
  23. public function main_run()
  24. {
  25. }
  26. }
  27.  
  28. $system = innysystem::get_instance();
  29. $system->main_run();
  30.  
  31. ?>

ale podczas pobierania referencji przez funkcje get_instance() tworzy sie nowy obiekt z tym ze jest to 'system' a nie 'innysystem' wiec jak to najprosciej naprawic by we wszystkich klasach potomnych nie trzebabylo wklepywac tej samej funkcji get_instance() ?
dr_bonzo
Niestety musisz recznie dopisac get_instance() dla kazdej z klas pochodnych. Jako ze nie przeciazyles tej metody w klasie pochodnej, get_instance() bedzie zawsze wywolywana dla obiektu klasy nadrzednej.
Imperior
Co gorsza, nie da się (przynajmniej ja nie mogłem) pobrać nawet nazwy tej "rzeczywistej" klasy.
dr_bonzo
Nawet get_class() nie dziala sad.gif
ksiadz
jedyne co mi sie udalo uzyskac to tylko to
  1. <?php
  2.  
  3. class system
  4. {
  5. protected static $instance = array();
  6.  
  7. protected function __construct()
  8. {}
  9.  
  10. public static function get_instance( $classname=__CLASS__ )
  11. {
  12. if( ! isset( self::$instance[ $classname ] ) )
  13. {
  14. self::$instance[ $classname ] = new $classname();
  15. }
  16.  
  17. return self::$instance[ $classname ];
  18. }
  19. }
  20.  
  21. class innysystem extends system
  22. {
  23. public static function get_instance()
  24. {
  25. return parent::get_instance( __CLASS__ );
  26. }
  27.  
  28. public function main_run()
  29. {
  30. }
  31. }
  32.  
  33. $system = innysystem::get_instance();
  34. $system->main_run();
  35.  
  36. ?>

moze ktos ma lepszy pomysl na dziedziczenie singletona dry.gif
dr_bonzo
No i chcesz stworzyc instancje klasy 'innysystem'
  1. <?php
  2. $blabla = innysystem::get_instance();
  3. ?>

co konczy sie wywolaniem:
  1. <?php
  2. new innysystem();
  3. ?>

Aby to wywolanie bylo mozliwe -- konstruktor klasy innysystem musi byc publiczny, a jak jest publiczny to mozna stworzyc obiekt w sposob tradycyjny, co burzy koncepcje singletona.

A poza tym skoro juz implementujesz metode get_instance() w klasie pochodnej to po prostu napisz ja tak jak w klasie 'system'.
Bora
  1. <?php
  2. class Container
  3. {
  4.    private static $container = array();
  5.  
  6.    private static $instance;
  7.  
  8.    private function __construct()
  9.  
  10.     public static function getInstance()
  11.     {
  12.         if( self::$instance === false )
  13.         {
  14.             self::$instance = new self();
  15.         }
  16.  
  17.         return self::$instance;
  18.     }
  19.  
  20.    public static function get( $name )
  21.    {
  22.       if( isset( self::$container[ $name ] ) )
  23.       {
  24.          return self::$container[ $name ];
  25.       }
  26.    }
  27.    
  28.    public static function set( $name, $value )
  29.    {
  30.       self::$container[ $name ] = $valule;
  31.    }
  32. }
  33. class Module
  34. {
  35.    static $modules = array();
  36.    
  37.    public static function _get( $name )
  38.    {
  39.       $container = Container::GetInstance(); 
  40.       $container->get($name);
  41.    }
  42.    
  43.    public static function _set( $name, $value )
  44.    {
  45.       $container = Container::GetInstance(); 
  46.       $container->get($name, $valule); 
  47.    }
  48. }
  49.  
  50. class Core extends Module
  51. {
  52. }
  53.  
  54. class Shop extends Module
  55. {
  56. }
  57.  
  58. $core = new Core;
  59. $shop = new Shop;
  60.  
  61. $core->test = 'Testujemy';
  62.  
  63. echo 'Core: '.$core->test.'<br/>Shop: '.$shop->test;
  64. ?>

pisane w locie ale powinno zadzialac.

widze ze piszac w pospiechu pomylilem tematy: http://forum.php.pl/index.php?showtopic=33537
dag
Hmm IMHO jest to błąd projektowy. Jeśli używać wzorca projektowego SINGLETON to tylko w ten sposób do jakiego jest zalecany, czyli do zwracania referencji obiektu i uniemożliwienie tworzenia nowych obiektów.

Jeśli już musisz dziedziczyć po jakieś klasie to lepiej rozbić tę klasę. IMHO będzie to lepsze rozwiązanie i czytelniejsze z projektowego punktu widzenia.
NuLL
A co sądzicie o pomyśle na singletonFactory :?: Chyba wiadomo o co chodzi smile.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.