Zachowanie dostępu do danych w obrębie klasy

Autor: Marcin Pietruszka, dodano: 18-08-2009
Kategoria: Programowanie i tworzenie

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. .”(http://pl2.php.net/mysql_connect). 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?

Ocena 2.65/5 (52.94%) (445 głosów)

Komentarze:

  • zgadzam się
    Dodał: Gość data: 2009-12-10
    Oczywiście autor artykułu ma rację, co za bezsensowny pomysł z dziedziczeniem ani to praktyczne ani czytelne, jeżeli piszemy klasę ogłoszenia to jak ona może dziedziczyć z klasy MySQL (czy query jak w tym przykładzie) to w ogóle nie jest logiczne, a osoba sugerująca takie rozwiązanie ewidentnie jest ignorantem, który na dodatek na temat programowania nie wie zbyt dużo.

  • Dodał: Gość data: 2009-12-29
    [...] błędy ortograficzne.
  • zgadzam sie
    Dodał: sokzzuka data: 2009-12-31
    Nie ma co dziedziczyć zbyt wiele, powinno się w zasadzie dziedziczenie ograniczyć do niezbędnych przypadków, a zamiast dziedziczenia implementować interfejsy używając techniki osłabiania i wstrzykiwania zależności (Dependency Injection Pattern) oczywiście wszystko też zależy jak duży projekt robimy :>
  • konstruktor
    Dodał: Gość data: 2010-12-20
    Dziedziczenie, a dlaczego w konstruktorze klasy nie dać: $this->conn= new Query(); tylko raz inicjiujesz, zresztą przedstawiona tutaj metoda jest standardowa, a nie nowum
  • mysql_close()
    Dodał: Gość data: 2012-06-11
    Autorze jak już piszesz jakiś kod to nie rób w nim błędów :)
    Napisz co się stało z mysql_close()?

    Oczywiście nie podważam tego co jest w treści na temat dziedziczenia.


Dodaj komentarz:


Temat:
Twój nick:
Komentarz:
 

Prosimy o kulturę wypowiedzi. Komentarze zawierające niecenzuralne zwroty, bądź obrażające inne osoby będą usuwane. Kod HTML w wypowiedziach jest niedozwolony. Wydawca nie odpowiada za treść komentarzy.