Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Singleton a dziedziczenie
Forum PHP.pl > Forum > PHP > Object-oriented programming
tornax
witam,

Zastanawiałem się ostatnio czy można w jakiś sposób w trakcie wykonywania programu poszerzyć metody klasy.

Przykładowo napisałem i korzystam z włąsnej, prostej klasy (mysql) do łączenia się z bazą mysql, wykorzystuje ona singleton. Teraz, tworzę obiekty innych klas (u mnie różne moduły) które mogą sobie w razie potrzeby korzystać z połączenia z baza mysql przez uzyskanie referencji do obiektu klasy mysql

  1. <?php
  2. class mysql
  3. {
  4. // Singleton
  5. // przy tworzeniu automatyczne polaczenie z baza -> konstruktor
  6. }
  7.  
  8. class mysql_plus extends mysql
  9. {
  10. //Cokolwiek
  11. }
  12. ?>


Jednak zastanawiałem się czy możliwe było by dziedziczenie od klasy mysql tak aby ją poszerzyć a jednocześnie nie tworzyć dodatkowego obiektu? W teorii oczywiście nie ma takiej opcji bo mamy nową klasę czyli utworzenie jej obiektu powinno spowodować utworzenie nowego obiektu klasy która dziedziczyła - czyli nowego obiektu klasy mysql_plus, a tego nie chcę poza tym załóżmy że nieznam danych potrzebnych do zrealizowania kolejnego połączenie z baza MySQL

W takim razie czy można zastosować jakiś wybieg z poszerzaniem metod (i właściwości) istniejącego już obiektu danej klasy ?
dr_bonzo
Zeby rozszerzyc klasy mysql musisz:
1. wyedytowac ta klase i utworzyc obiekt od nowa
lub
2. rozszerzyc ta klase (extends mysql...) i utworzyc obiekt tej podklasy

Mozesz zastosowac Dekorator, dziedziczysz po mysql, wrzucasz w nowy obiekt tego singletona (obiekt) i przekazujesz do niego wszystkie stare metody i dodatkowo masz dostepne nowe metody:

  1. <?php
  2. class MysqlDecorator extends Mysql .// klasa bazowa dla dekoratorow
  3. ...
  4.  
  5. class SomeMysqlDecorator extends MysqlDecorator...
  6. ...
  7.  
  8. $db_new = new SomeMysqlDecorator( $mysql_singleton )
  9. ...
  10. $db_new->query();
  11. // a w srodku przekazujesz do
  12. public function query( $str )
  13. {
  14.  #this->mysql->query( $str )
  15.  
  16. ...
  17. ?>


Oczywiscie ta delegacje mozna uproscic stosujac __call() i func_args (czy jakos tak) zeby nie pisac recznie tych wszystkich tetod.
tornax
No widzisz, faktycznie mógłbym tak zrobić gdyby nie fakt że konstruktor klasy mysql jest odpowiedzialny za łączenie z bazą, zaraz to rozwinę

Skrypt który tworzę zakłada wykorzystywanie modułów, które w teorii, jeżeli ktoś wie jak, będzie mógł pisać każdy. Jednak nie chcę udostępniać tym piszącym osobom informacji dotyczących: nazwy hosta, bazy danych, użytkownika i hasła - czyli wszystkiego co jest potrzebne do zrealizowania połączenia

Oczywiście nie udowstępniam też linku do połączenia tylko daję możliwość realizowania wszystkich zapytać przez interface klasy mysql

Mógłbym napisać klasę która wyglądała by tak

  1. <?php
  2. class mysql_ex
  3. {
  4.  
  5. public $mysql = mysql::singleton();
  6.  
  7. public function pobierzText($id)
  8. {
  9.  ...
  10. $wynik = $this->mysql->squery('Zapytanie'); //jaks metoda wykorzystujaca zwykle quryy()
  11.  ...
  12. }
  13. }
  14. ?>


Tylko problem polega na tym ze jezeli chcialbym skorzystac z czesci tych wlasciwosci klasy mysql (np. tego squery()) to musiałbym w klasie mysql_ex robić jakieś takie dziwaczne i totalnie nie ptraktyczne przepisania, jak

  1. <?php
  2. ...
  3. public function squery($args)
  4. {
  5. return $this->mysql->squery($args)
  6. }
  7. ....
  8. ?>


Lekko mówiąc bezsensu
UDAT
Cytat(tornax @ 12.10.2006, 13:17:34 ) *
Tylko problem polega na tym ze jezeli chcialbym skorzystac z czesci tych wlasciwosci klasy mysql (np. tego squery()) to musiałbym w klasie mysql_ex robić jakieś takie dziwaczne i totalnie nie ptraktyczne przepisania, jak

  1. <?php
  2. ...
  3. public function squery($args)
  4. {
  5. return $this->mysql->squery($args)
  6. }
  7. ....
  8. ?>


Lekko mówiąc bezsensu


Istnieje coś takiego jak __call, __get, __set , więc nie musisz przepisywać ( co zresztą napisał dr_bonzo, chociażby:

  1. <?php
  2. function __call ( $func, $args ) {
  3. call_user_func_array ( array ( $this->mysql, $func ), $params );
  4. }
  5. ?>



----
Możesz użyć konenera IoC lub wzorca Registry
dr_bonzo
A czemu pisza te moduly na twoim produkcyjnym serwerze?
Testujesz te moduly nainnym serwerze i jak sa ok to wrzucasz na serwer.
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.