Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [OOP] 'Budowa interfejsów bazodanowych'.
Forum PHP.pl > Forum > PHP
MagnuM
Witam,
przeczytałem artykuł ze strony głównej pt. 'Budowa interfejsów bazodanowych' i zaintrygowała mnie kwestia dziwnych funkcji zawartych w umieszczonych tam klasach. Z resztą widziałem podobne w innych artykułach.

Przytocze tutaj taki przykład z sekcji artykułu zatytułowanej 'Składamy wszystko w całość'.

  1. <?php
  2. /* Notes:
  3.    $db - instance of ADOdb connection object.
  4.    $user - instance of the User DB Interface
  5.    $topic - instance of the Topic DB Interface
  6. */
  7. $db->StartTrans();
  8.  
  9. // update the user's total # of posts
  10. $user->setNumPosts($user->getNumPosts() + 1); // PRZYKŁAD
  11. $user->submit($db); // PRZYKŁAD
  12.  
  13. // update the topics # of messages
  14. $topic->setNumMessages($topic->getNumMessage() + 1);
  15. $topic->submit($db);
  16.  
  17. // create the new message
  18. $message = new Message();
  19. $message->setTopicID($topic->getTopicID());
  20. $message->setTopic($_POST['userTopic']);
  21. $message->setMessage($_POST['message']);
  22. $message->setPoster($user->getUserID());
  23. $message->submit($db);
  24.  
  25. $db->CompleteTrans();
  26.  
  27. ?>


Jaki jest sens używania tego typu funkcji jak tutaj: setNumPosts(), getNumPosts(), submit() ?
Wydaje mi się że kod:

  1. <?php
  2. $user->setNumPosts($user->getNumPosts() + 1);
  3. $user->submit($db);
  4. ?>


Można z powodzeniem zapisać tak:
  1. <?php
  2. $user->numPosts += 1; // przyjmujac ze w konstruktorze do zmiennej $numPosts wczytywana jest ilsoc posto
    w uzytkownika
  3. ?>


A później w destruktorze wysyłać do bazy zgromadzone przez cały czas działania skryptu dane.

Pozdrawiam.
LBO
Settery udostepniają mozliwośc np. walidacji danych przed dalszymi akcjami np.:
  1. <?php
  2. $client->setEmail('name@domain.com');
  3. ?>

a definicji klasy:
  1. <?php
  2. public function setEmail($email)
  3. {
  4. if (Filter::isEmail($email) !== true) {
  5. throw new ClientException('e-mail is not valid');
  6. };
  7. }
  8. ?>
hwao
Cytat
A później w destruktorze wysyłać do bazy zgromadzone przez cały czas działania skryptu dane.

Nie do końca, ponieważ często zachodzi potrzeba operacji na danych które powinny zostać uakualnione, jeżeli były to destruktor to różnie to bywa. Pisanie za każdym rażem unset" title="Zobacz w manualu php" target="_manual() też nie jest najlepszym pomysłem, dlatego właśnie stosuje się te metody.

Wspomne tylko jeszcze, że php udostepnia bardzo ubogi mechanizm dotyczący właściwości klasy.

@LBO: Mozna by próbować osiągnąć efekt o którym piszesz, korzystając z magicznej metody __get(), tylko sam nie wiem, jak z zwracaniem wyjątków (z tego co pamiętam to działają aż miło smile.gif )
LBO
Oczywiście, że można używać magiczne metody, ale:
1. Operacje dodatkowe mogą się od siebie różnić, czyli trzeba by było pokombinować nad rozpoznaniem argumentów.
2. Czy to by były magiczne metody czy wklepane hardcoded nie ma znaczenia - idea ta sama, by uzywać gettery i settery. Temat i objętość artykułu po prostu nie pozwalał na zajęcie się tym i opisanie.
bigZbig
@hwao

Mowisz i masz
  1. <?php
  2.  
  3. class User
  4. {
  5. private static $_aProprietes = array();
  6.  
  7. public function __construct() {
  8. $this->_aProprietes = array('Email' => 'info@domain.com',
  9.  'Name' => 'No name');
  10. }
  11.  
  12. private function _setEmail($sEmail)
  13. {
  14. if (Filter::isEmail($sEmail) !== true) {
  15. throw new ClientException('e-mail is not valid');
  16. };
  17. $this->_aProprietes['Email'] = $sEmail;
  18. }
  19.  
  20. private function _getName()
  21. {
  22. return 'My name is ' . $this->_aProprietes['Name'];
  23. }
  24.  
  25. public function __set($sProperty, $mValue){
  26. if(method_exists($this, '_set'.$sProperty)) {
  27. call_user_func(array($this,'_set'.$sProperty), $mValue);
  28. return true;
  29. }
  30. if(!array_key_exists($sProperty, $this->_aProprietes)) {
  31. throw new Exception('Undefined property '.$sProperty.'!');
  32. }
  33. $this->_aProprietes[$sProperty] = $mValue;
  34. return true;
  35. }
  36.  
  37. public function __get($sProperty){
  38. if(method_exists($this, '_get'.$sProperty)) {
  39. return call_user_func(array($this,'_get'.$sProperty));
  40. }
  41. if(!array_key_exists($sProperty, $this->_aProprietes)) {
  42. throw new Exception('Undefined property '.$sProperty.'!');
  43. }
  44. return $this->_aProprietes[$sProperty]
  45. }
  46. }
  47.  
  48. $oU = new User();
  49. $oU->Name = 'Bond';
  50. $oU->Email = 'bond@domain.com';
  51.  
  52. echo $oU->Master;
  53. echo $oU->Email;
  54.  
  55. ?>
LBO
No, i dobrze, bardzo ładnie BigZbig, ale pomimo tej całej otoczki fancy-oprogramowania to nadal to samo, nie uważasz?. Jak dla mnie temat zamknięty, bo jednoznacznie odpowiedzieliśmy czemu metody, a nie bezposrednia aktualizacja zmiennych.
Cysiaczek
Settery i gettery to w zasadzie jeden z ważniejszych przystanków na drodze ku dobrej hermetyzacji klas. Jak teraz sobie myślę, że ktoś mógłby swoimi brudnymi, obleśnymi łapskami dotykać moich składowych, to mi niedobrze. Interfejs musi być!!!
ActivePlayer
nie zapominajmy o ppp. składowe mozna okreslic jako private i juz nikt brudnymi łapskami nic nie zrobi z tym czego nie powinien dotykać.
splatch
Klas sie nie hermetyzuje. Hermetyzuje się dane.
Cysiaczek
Fakt. Dane, nie klasy. Dzieki za zwrócenie uwagi smile.gif
hwao
z tego co pamietam to w php5.1 takie cos
  1. <?php
  2. call_user_func(array($this,'_get'.$sProperty));
  3. ?>

Nie przejdzie smile.gif

Swoja droga to mysalem o troche innym rozwiazaniu mianowiscie
$Obiekt-><filtr><wlasciwosc>
W wyrazeniu reg. zlapac oco chodzi i odpowiednio przekazac

Np:
$Object->intId = 'string';

Obiekt rozpozna ze int i poleci do
  1. <?php
  2. private function Integer( $mValue ) { 
  3. return (int) $mValue;
  4. }
  5. ?>

A potem do wlasciwosci
bigZbig
Cytat(hwao @ 5.07.2006, 13:32 ) *
z tego co pamietam to w php5.1 takie cos
  1. <?php
  2. call_user_func(array($this,'_get'.$sProperty));
  3. ?>

Nie przejdzie smile.gif


Zawsze możesz użyć funkcji method_exists

Twoja propozycja rozwiazanie jest malo elastyczna bo ogranicza sie jedynie do rozpoznawania typow.
hwao
mozesz sobie napisac inne typy, ja tylko napisalem najprostrzy
MagnuM
Czyli jednoznacznie hermetyzacja?
A co mam zrobić w przypadku dużej ilości zmiennych w których zapisane są zwykłe liczby, które nie potrzebują jakiś hermetyzacji ze względu na to, że nie są 'zagrożone' niepożądanymi wynikami wpisywanymi przez użytkownika. Też tworzyć dla każdej takie dodatkowe funkcje ?

Ewentualnie stworzyć tablice typu $liczby i funkcje dla tej tablicy ?
bigZbig
@MagnuM - niedajmy sie zwariowac. Co prawda ogolnie rzecz biorac zalecane jest definiowanie wlasciwosci jako chronione lub prywatne, ale nie jesli ma to byc sztuka dla sztuki. W koncu poto wymyslono klauzule public aby ja stosowac.
LBO
Czyli trzeba to wyważyć, nieprawdaż. Okreslać zmienne jako publiczne, gdy nie trzeba walidować. W przeciwnym razie private i ustawiać setter.
MagnuM
Wszystko jasne, dzieki za odpowiedź.
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.