Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Dwa rozwiązania
Forum PHP.pl > Forum > PHP > Object-oriented programming
szumigt
Witam !!!
Zacznę od tego że jestem tutaj całkiem nowy więc proszę o wyrozumiałość jeśli palnę coś nie zgodnego z zasadami panującymi na tym forum. Do tej pory zajmowałem się programowaniem w PHP4. Głównie były to informacje pochodzące bezpośrednio z MySQL-a. Teraz zmiana serwera skłoniła mnie do przesiadki na PHP5.
Pierwszy przykład i pojawiły się już pierwsze pytania.. Otóż przypuśćmy ze mamy taką klasę.

1.
CODE
class config {
public $settings=array();
function __construct () {
$this->settings = $this->get_settings()
}
function get_settings() {
return parse_ini_file("config.ini", TRUE);
}

}


Prosta klasa która będzie pobierała dane z pliku konfiguracyjnego i je zapamiętywała. Teraz załóżmy istnienie drugiej która będzie miała za zadanie połączyć się z bazą MySQL-a. Mam do wyboru dwa warianty z czego jeden i drugi funkcjonują identycznie.

2a.
CODE
class db {
public $connect=0;
function __construct() {
$ob = new config();
$this->connect = mysql_connect($ob->settings['host'],$ob->settings['user'],$ob->settings['passwd']);
mysql_select_db($ob->settings['db']);
}
}


2b.
CODE
class db extends config {
public $connect=0;
function __construct() {
$ob = config::get_settings();
$this->connect = mysql_connect($ob['host'],$ob['user'],$ob['passwd']);
mysql_select_db($ob['db']);
}
}


Pytanie teraz brzmii który jest poprawny merytorycznie - zgodnie z zasadami. CZy sensowne jest tworzenie w takiej sytuacji nowego obiektu czy poprostu wywołanie funckji z klasy bez tworzenia obiektu.?? Acha doam że założenia będą jeszcze kolejne. Tzn następne klasy będą korzystać z w/w. Np Klasa strona będzie korzystać i z db i z config. Klasa validator tylko z config. Klasa Login będzie i z db i config ... itd.

Doradźcie cosik...
Inzabi
Obie metody są ok, wszystko zależy od projektu.

Błędem natomiast jest trzymanie danych do autoryzacji w pliku ini, chyba, że to tylko dla przykładu tongue.gif
szumigt
Nie to nie było dla przykładu. Dlaczego jest błędem?? Jeśli nadam mu odpowiednie prawa a po za tym przecież mogę go umieścić po za katalogiem strony i tak nik z zewnątrz się do niego nie dostanie...

No dobrze, a jak wygląda sprawa z optymalizacją. Czy pod tym względem jedna czy druga metoda nie zabiera np więcej zasobów serwera ... questionmark.gif
Cysiaczek
Chyba nie - obie metody są normalne. jedyna różnica to to, że w drugim przykłądzie robisz kopie tablicy. Moższ zrobić referencję. Generalnie rób tak jak Ci wygodniej.

Pozdrawiam.
szumigt
To teraz inaczej. Przyjmijmy że klasa config ma taką samą treść ale teraz klasa db ma postać:
CODE

class db {

public $connect=0;
public $result=0;
public $rows=array();
public $names=array();

function __construct() {
$ob = new config();
$this->connect = mysql_connect($ob->settings['host'],$ob->settings['user'],$ob->settings['passwd']);
mysql_select_db($ob->settings['db']);
}

function fetch_rows($query) {
$this->result = mysq_query($query);
$this->rows = mysql_fetch_assoc($this->result);
}

function fetch_names() {
for($i=0;$i<mysql_num_fields($this->result);$i++)
$this -> names[$i] = mysql_field_name($this->result, $i);
}

}


Teraz jest ona większa i ma więcej właściwości. Jeśli teraz powiększamy nasz projekt przez kolejną klasę....

CODE

class Page {
public $menu = array();
public $dbase;

function __construct() {
$this -> dbase = new db();
}

function get_menu(&$dzial) {
$this -> dbase -> fetch_rows("SELECT * FROM cms WHERE parent = $dzial");
while($this -> dbase -> fetch_rows() ) {
$this->menu[] = $this -> dbase -> rows;
}
}

}


To tym razem tworzę w pamięci większy obiekt a tym samym więcej zajmuje on miejsca w pamieci. Koniec z końcem i tak korzystam tylko z jednej metody pobierającej dane ...
Inzabi
Wszystko zależy od techniki programowania. Ale jeśli klasa ma mieć tylko jedną metodę, to może wystarczy ci zwykła funkcja. Nie do wszystkiego na siłe trzeba robić klasy.

W podanym przykładzie klasa Config pobiera tylko dane, jeśli pobiera ona tylko dane do bazy, to lepiej zaimplementować tą funkcje, jak metodę klasy db.

Jeśli masz w klasie Page, wiele metod, które korzystają z obiektu db, to lepiej zrobić dziedziczenie, lub zainicjować ją w konstruktorze. Tylko weż pod uwagę, że jeżeli korzystać z wielu klas, które bedą używać klasy db, to Twoja metoda nie dość, że zmiejszy czytelność kodu, to dodatkowo możę zwiększyć ilość wykorzystanej pamięci. Dlatego w tym przypadku lepiej zainicjować klase db gdzieś na początku, aby później używać już tylko jej identyfikatora.
szumigt
Cytat(Inzabi @ 5.10.2007, 13:29:58 ) *
Wszystko zależy od techniki programowania. Ale jeśli klasa ma mieć tylko jedną metodę, to może wystarczy ci zwykła funkcja. Nie do wszystkiego na siłe trzeba robić klasy. W podanym przykładzie klasa Config pobiera tylko dane, jeśli pobiera ona tylko dane do bazy, to lepiej zaimplementować tą funkcje, jak metodę klasy db.


No na dobrą sprawę to tak. Ta klasa ma tylko za zadanie pobrac dane do konfiguracji serwisu. Międzyinnymi ilość artykułów na stronę czy Tytuł aplikacji... Moze by warto pomyslec nad tylko jedną funkcją ...

Cytat(Inzabi @ 5.10.2007, 13:29:58 ) *
Jeśli masz w klasie Page, wiele metod, które korzystają z obiektu db, to lepiej zrobić dziedziczenie, lub zainicjować ją w konstruktorze.


Tak w klasie page będą jeszcze ze cztery metody korzystające z klasy db... Ale przecież inicjacja obiektu db jest tutaj w konstruktorze... questionmark.gif

Cytat(Inzabi @ 5.10.2007, 13:29:58 ) *
Dlatego w tym przypadku lepiej zainicjować klase db gdzieś na początku, aby później używać już tylko jej identyfikatora.


Czy inicjacja w konstruktorze może tak zostać ...

Mam prośbę. Mogę Ci wysłać na maila kod wszystkich klas. Rzuciłbyś okiem co jest nie tak i ewentualnie coś zasugerował... questionmark.gif
Inzabi
Jeśli nie masz tego za dużo, to mogę rzucić okiem.
szumigt
Cytat(Inzabi @ 5.10.2007, 14:24:43 ) *
Jeśli nie masz tego za dużo, to mogę rzucić okiem.


Nie. Będzie ze 5 plików. Poszło na mail...
Sedziwoj
@szumigt
PHP5?
A gdzie deklaracja zasięgu metod, to musi być podane. To nie jest Java, która ma jeszcze jeden zasięg.
Cysiaczek
Ja sie na chwilę wtrącę.
@Sedziwoj - jak nie ma podanego zakresu widoczności przy metodzie, to automatycznie jest to metoda publiczna i dla php5 nie jest to bląd.

Pozdrawiam.
Sedziwoj
Cytat(Cysiaczek @ 11.10.2007, 16:07:48 ) *
@Sedziwoj - jak nie ma podanego zakresu widoczności przy metodzie, to automatycznie jest to metoda publiczna i dla php5 nie jest to bląd.

Nie, nie jest to błąd (w znaczeniu interpretera PHP). Ale musi być bo nie innego zasięgu, a z tymi domyślnymi rzeczami to różnie bywa, więc dlatego powinno się podawać zasięg.
Bez to pozostałość po PHP4 i tyle można moim zdaniem o tym powiedzieć.

EDIT małe dopowiedzenie.
faster
Moim skromnym zdaniem
z formalnego punktu widzenia oba podejścia są prawidłowe natomiast funkcjonalnie w opisywanym przypadku dziedziczeni klasy do obsługi bazy danych po klasie config nie jest dobrym rozwiązaniem. Dziedziczenie stosuje się raczej dla klas o "podobnej" dziedzinie czyli np:

class zwierzak
class kot extends zwierzak

lub

class db
class koszyk extends db (w tym przypadku koszyk to klasa opakowująca tablicę koszyk w bazie danych)


lepiej, jeżeli klasa db korzysta z klasy config w celu pobrania potrzebnych jej informacji

zatem ja opowiadam się za przykładem 2a - jest bardziej elegancki

pozdrawiam
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.