Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: klasy i dziedziczenie
Forum PHP.pl > Forum > PHP
yeti
Witam, mam kłopot myślowy co do zagospodarowywania zasobów podczas tworzenia obiektów.

Wprowadzenie:
mamy serwis, w którym wykorzystywane są:
- 3 klasy podstawowe (połączenie z DB, obsługa zapytań, klasa serwisowa). Klasy te dzidziczą od siebie w podanej kolejności
- 1 klasa do obsługi prezentacji
- 2 klasy specjalizowane (obsługjące konkretne działy serwisu, np. newsy i forum)

Pytanie:
Czy sensowne jest rozwiązanie, w którym robimy dwie ścieżki dziedziczenia: od klasy News poprzez Prezentację i klasy podstawowe i od klasy Forum poprzez Prezentację i klasy podstawowe? Klasy News i Forum używane są rownocześnie tylko 2 razy, ale spowoduje to niepotrzebne dwukrotne wywołanie klasy Prezentacji i klas podstawowych.

Czy może jest sensowniejsze rozwiązanie?
Dodam, że funkcjonalność klas News i Forum zasadza się na użyciu metod z klas podstawowych.
SHiP
Ja może napisze jak ja to robie...

mam klase main która jest extends functions
klase functions oraz inne np user, admin, profil, stats,search itd które są extends do function.
jak mam jakąś funkcje dla wszystkich to wrzucam ją do klasy functions jeśli nie to do odpowiedniego pliku.
Później sprawdzam która klasa jest potrzebna i includuje jej pliki oraz tworze obiekt...

Nie wiem jak bym tak pare razy nie dziedziczył...
M4chu
Ja zamiast dziedziczenie poprostu przeslylalbym instancje potrzebnych klas do klasy News czy Forum, poprostu:
  1. <?php
  2.  
  3. class News
  4. {
  5. function __construct($db)
  6. {
  7. $this->db = $db;
  8. }
  9. }
  10. class Forum
  11. {
  12. function __construct($db)
  13. {
  14. $this->db = $db;
  15. }
  16. }
  17. $db = new Db;
  18. $news = new News($db);
  19. $forum = new Forum($db);
  20. ?>

Najlepsze jest to, ze operujesz na tym samym obiekcie, a w nim masz uchwyt do polaczenia z baza, liczbe wykonanych zapytan itp. Zreszta gdyby np News dziedziczylo po Db, to w konstruktorze News musialbys podac parametry bazy danych - gdybys chcial dodac jeszcze obsluge bledow czy inputa to to juz nie jest zbyt elastyczne winksmiley.jpg
yeti
Hmm, to ostatnie jest niezłe.
Popróbuję, dzięki smile.gif
bregovic
Cytat(M4chu @ 2004-09-22 18:12:45)
  1. <?php
  2.  
  3. class News
  4. {
  5. function __construct($db)
  6. {
  7. $this->db = $db;
  8. }
  9. }
  10. class Forum
  11. {
  12. function __construct($db)
  13. {
  14. $this->db = $db;
  15. }
  16. }
  17. $db = new Db;
  18. $news = new News($db);
  19. $forum = new Forum($db);
  20. ?>

zamiast przesylac referencje i zapisywac obiekt db w atrybucie (co zdaje sie zajmuje duzo pamieci) mozesz po prostu napisac w kazdej metodzie
  1. <?php
  2. classs Foo
  3. {
  4. public function OhSoFoo()
  5. {
  6. global $db;
  7. }
  8. }
  9. ?>
yeti
Można zdefiniować zmienną globalną, ale ja osobiście takich zmiennych nie lubię. IMHO są po prostu niebezpieczne.
bregovic
w jakim sensie niebezpieczne? chodzi ci o powtarzanie sie nazw zmiennych, czy o cos innego?
yeti
Cytat(M4chu @ 2004-09-22 19:12:45)
Ja zamiast dziedziczenie poprostu przeslylalbym instancje potrzebnych klas do klasy News czy Forum

Wyglądało nieźle, ale albo coś pomijam albo niestety nie działa sad.gif
Yarecki
Cytat(yeti @ 2004-09-24 00:14:16)
Wyglądało nieźle, ale albo coś pomijam albo niestety nie działa sad.gif

To co napisał M4chu działa bez problemów w php5 gdzie obiekty zawsze przesyłane są przez uchwyt, a nie kopiowane. W php4 ten kod powinien wyglądać jakoś tak:

  1. <?php
  2. class News
  3. {
  4. var $objDb = NULL;
  5.  
  6. /**
  7.  * Konstruktor
  8.  */
  9. function News( &objDb )
  10. {
  11. $this->objDb = &objDb;
  12. }
  13. }
  14.  
  15. $objDb = new Db;
  16. $objNews = new News( $objDb );
  17. ?>
chfast
Cytat(bregovic @ 2004-09-22 19:11:49)
zamiast przesylac referencje i zapisywac obiekt db w atrybucie (co zdaje sie zajmuje duzo pamieci) mozesz po prostu napisac w kazdej metodzie
  1. <?php
  2. classs Foo
  3. {
  4. public function OhSoFoo()
  5. {
  6. global $db;
  7. }
  8. }
  9. ?>

Tu się nie zgodze. Odniesienie się do zmiennej zapisanej wewnątrz obiektu jest kilkakrotnie szybsze niż odnoszenie się do zmiennych globalnych. A leśli chodzi o zasoby to chyba oba rozwiązania zjadają podobną ilość.
M4chu
Cytat(chfast @ 2004-09-24 09:22:01)
A leśli chodzi o zasoby to chyba oba rozwiązania zjadają podobną ilość.

Wiec jak to lepiej zrobic? smile.gif
Wiem, ze mozna jeszcze kozystac ze statycznej zmiennej i funkcji np (php5)
  1. <?php
  2.  
  3. class Foo
  4. {
  5. public static $instance;
  6. static function getInstance()
  7. {
  8. if(self::$instance == null)
  9. {
  10.  self::$instance = new Foo;
  11.  return self::$instance;
  12. }
  13. return self::$instance;
  14. }
  15. }
  16. Foo::getInstance()->method();
  17.  
  18. ?>
Ale jak to sie ma do wydajnosci?
rogrog
M4chu - to co piszesz to singletony a więc rozwiązanie szeroko stosowane właśnie w tekich przypadkach

generalnie można używać albo zmiennych globalnych albo singletonów, ale przy programowaniu obiektowym używanie zmiennych globalnych jest po prostu mało eleganckie
yeti
Cytat(bregovic @ 2004-09-22 21:35:21)
w jakim sensie niebezpieczne? chodzi ci o powtarzanie sie nazw zmiennych, czy o cos innego?

Chodzi mi o to, że w pewnym sensie tracisz kontrolę nad zmienna. Wolę wiedzieć gdzie zmienna się kończy, a gdzie zaczyna. Korzystam z tablic globalnych i to mi wystarcza. A poza tym, jak to napisano powyżej, to nie jest zbyt eleganckie smile.gif

A oto i rozwiązanie problemu:

  1. <?php
  2.  
  3.  class Db {
  4.  
  5. function dbTest(){
  6.  echo('class Db, function testDb<br />');
  7. }
  8.  
  9.  }
  10.  
  11.  
  12.  class Sql {
  13.  
  14. var $db = NULL;
  15.  
  16. function sqlTest(){
  17.  echo('class Sql, function sqlTest<br />');
  18. }
  19.  
  20. function sqlDbTest(){
  21.  echo('class Sql, function sqlDbTest<br />');
  22.  $this -> db -> dbTest();
  23. }
  24.  
  25. function Sql(&$db){
  26.  $this -> db = &$db;
  27. }
  28.  }
  29.  
  30.  $db = new Db();
  31.  $db -> dbTest();
  32.  
  33.  $sql = new Sql($db);
  34.  $sql -> sqlTest();
  35.  $sql -> sqlDbTest();
  36. ?>
ShaXbee
Cytat(Yarecki @ 2004-09-24 04:21:38)
  1. <?php
  2. class News
  3. {
  4.     var $objDb = NULL;
  5.  
  6.     /**
  7.      * Konstruktor
  8.      */
  9.     function News( &objDb )
  10.     {
  11.         $this->objDb = &objDb;
  12.     }
  13. }
  14.  
  15. $objDb = new Db;
  16. $objNews = new News( $objDb );
  17. ?>

Testowalem to rozwiazanie.
Zamiast &objDb nalezy wstawic & $objDb, ponieważ interpreter PHP4 zwraca błąd parsowania.
yeti
Cytat(ShaXbee @ 2004-10-21 17:17:14)
Cytat(Yarecki @ 2004-09-24 04:21:38)

Testowalem to rozwiazanie.
Zamiast &objDb nalezy wstawic & $objDb, ponieważ interpreter PHP4 zwraca błąd parsowania.

hehe, a co ja napisałem powyżej cool.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.