Ostatnimi czasy w poszukiwaniu pracy odwiedzam co jakiś czas potencjalnych pracodawców. Rozmowa kwalifikacyjna przebiega pomyślnie do momentu spotkania z „specjalistą” lub menadżerem działu IT. Zdarza się, że jestem często proszony o wykonanie zadania testowego.
Podczas spotkania w pewnej częstochowskiej firmie spotkałem się z zarzutem błędnego zachowania dostępu do danych. Podczas tego artykułu postaram się udowodnić błędne myślenie nie których programistów. Sam znajduję się na początku kariery, ale ucząc się staram się zachowywać podstawowe założenia programistyczne.
Problem polega na użyciu klasy połączeniowej z bazą danych MYSQL. Klasa może wyglądać np. tak jak na listing 1, sama klasa nie jest problemem artykułu.
class Query { private $host='' ; private $uzytkownik='' ; private $haslo='' ; private $naz_bazy=''; private $link;public function __construct() {$this->connect();}public function connect() { $this->link = mysql_connect($this->host, $this->uzytkownik, $this->haslo); if(!is_resource($this->link)) throw new Exception(mysql_errno()." -Zle parametry polaczenia"); if(!mysql_select_db($this->naz_bazy,$this->link)) throw new Exception(mysql_errno()." -Zle wybrana baza");} function setrecord($sql) {//tu tresc funkcji}}
Listing 1. Przykład klasy dokonującej połączenie z Bazą Danych MySql.
Istotą tego artykułu jest przedstawienie problemu dostępu do danych. Podczas spotkania usłyszałem, że należy to robić poprzez dziedziczenie, a moje metody były błędne. Listing 2 przedstawia tą wizję.
Class JakaKlasa extends Query {public function insertAdvert() { $sql=' '; $this->setrekord($sql);}public function selectAdvert() { $sql=' '; $this->getrekord($sql);}}
Listing 2. Błędny przykład inicjalicji klasy Query
Jak widzimy dostęp do danych uzyskujemy poprzez dziedziczenie wszystkich metod klasy Query. Jest to sposób wygodny, ponieważ nie musimy za każdym razem tworzyć nowego obiektu, jednak nie jest on optymalnym rozwiązaniem. Jeśli dane metody miały by zadziałać potrzeba nam odziedziczyć również konstruktor klasy Query. Dlaczego taka metoda nie jest dobra?
Jest kilka powodów, poniżej spróbuje wyjaśnić moje racje:
-
brak założenia metody opóźnionej inicjalizacji, połączenie z bazą powinno się otwierać tylko wtedy kiedy jest potrzebny dostęp do danych z bazy
-
czasami potrzeba nam stworzyć klasę, w której poszczególne metody będą realizować zupełnie inne zadania, więc nie ma sensu tworzyć połączenia w momencie tworzenia konstruktora, tylko wtedy kiedy wywołamy konkretną metodę, zadaniem programisty jest dostarczenie danych projektantowi
Argumentem zwolenników tej metody jest to, że otwieramy tylko jedno połączenie z BD dla jednego modułu. Takie sformułowanie wynika z braku wiedzy danej osoby, ponieważ funkcja mysql_connect według definicji: „Jeśli, ponownie wywołamy mysql_connect() z tymi samymi argumentami, nie zostanie nawiązane nowe połączenie, lecz zamiast tego, zostanie zwrócony identyfikator obecnie otwartego połączenia. .”(). Wynika z tego że dopóki nie zamkniemy połączenia, lub skrypt nie zakończy swojego działania, gdy wywołujemy połączenia za pomocą inicjacji obiektu naszej klasy Query z listingu 1 w danym skrypcie połączenie zostanie otwarte tylko raz. Przykład listingu 3 wyjaśni idee tego rozwiązania.
Class JakaKlasa {public function insertAdvert() { $sql=' '; $conn= new Query(); $conn->setrekord($sql);}public function selectAdvert() { $sql=' '; $conn= new Query(); $conn->getrekord($sql);}}
Listing 3 Poprawne użycie klasy połączeniowej
Teraz, gdy w naszym jakimś skrypcie stworzy obiekt naszej JakieśKlasy i wywołamy kolejno metody to połączenie wywoła się tylko raz wbrew mylnemu wnioskowaniu niektórych ludzi. Co o tym sądzicie?
