Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: globals raz jeszcze :)
Forum PHP.pl > Forum > PHP > Object-oriented programming
Black-Berry
Już parę razy nad tym myślałem, w końcu zrobiłem tak jak kilka osób polecało ale dalej mam niesmak....

Mam w swoim systemie dajmy na to 5 dużych klas bazowych bez których żadna inna pomniejsza klasa nie może działać (np. dbase, log, settings,...). No i teraz dajmy na to, że tworzę nową, małą klasę - formularz. Obiektów tej klasy będzie dużo bo dużo zazwyczaj jest formularzy na stronce. No i co za tym teraz idzie - przy każdym utworzeniu obiektu formularz musze podawać w konstruktorze 5 klas głównych:

  1. <?php
  2. $form1 = new formularz($dbase, $log, $settings, $language, $session);
  3. ?>


O wiele lepsze byłoby podanie w konstruktorze klasy formularz globalsów:
  1. <?php
  2. class formularz()
  3. {
  4. __comnstruct()
  5.  {
  6. global $dbase;
  7. $this->dbase = $dbase;
  8. (..) /itd.
  9.  }
  10. }
  11. //No i dzięki takiemu rozwiązaniu zamiast...
  12. $form1 = new formularz($dbase, $log, $settings, $language, $session);
  13.  
  14. //mogę napisać poprostu...
  15. $form1 = new formularz();
  16. ?>


W tym momencie kod raczej zyskuje niewiele tracąc. Globalsy nie mogą być aż takie złe.
cbagov
Dosc dziwaczny sposob tworzenia formularzy a na dodatek mozna obejsc i to i global poprzez zwykle & czyli referencje, nie wspomne o innych rozwiazaniach jak np. tablica obiektow a nie 5 obiektow czy instancji w parametrach funkcji itp.
LBO
Stwórz kontener na te klasy które muszą istnieć i tyle. Taka klasa w wielu systemach nazywa się Kontekstem i to ja przekazujesz jako parametr.
Black-Berry
no ale na jedno wychodzi prawda? macie na myśli rejestr ? No i oczywiście klasa formularz to tylko przykład.
LBO
Nie, nie... nie rejestr - rejestr z definicji jest klasą globalną, ja mam na myśli to co napisałem Kontekst - czyli obiekt agregujący inne obiekty (tablice etc) w umiejętny sposób udostępniony w systemie, ale bron Boże globalny.
Cysiaczek
To już lepiej pobierać przez singletona zestaw tych klas wewnątrz klasy Formularz niż robić globala. Generalnie kiedy szukam kodu zewnętrznego, to widząc słówko global (gdziekolwiek)... przechodzę do następnej biblioteki - nie ufam po prostu programiście, który pisze kod z globalami. Może i singleton nie jest dużo lepszy, ale przynajmniej jest jakimś punktem zaczepienia, zdradza istnienie jakiegoś układu klas, który da się przewidziec i kontrolować w normalnym, obiektowym kodzie.

Pozdrawiam.
LBO
@cysiaczku, nie mogę się z Tobą zgodzić... singleton to pójście na łatwiznę IMO, lepiej jest dobrze zaprojektować system i udostępniać to co chcemy, tam gdzie chcemy.
wrzasq
kazdy zrobi jak mu wygodniej, ale globalsy sa z definicji zle. wystarczy ze gdzies sie zapomnisz i nadpiszesz zmienna globalna i po zawodach. mozesz tez zrobic FormularzFactory, te klase zainicjowac z podanymi obiektami/kontekstem/jak-wolisz i z niej pobierac formularze.

aczkolwiek sadze, ze to zalezy od konkretnego przykladu, i jesli na przyklad chcesz tworzyc formularze, to nie rozumiem, czemu chcesz wszystko do niej wpychac.

moim zdaniem formularza samego nie towrzysz, musisz tam wkladac jakies pola, wiec jesli po to ci sa obiekty $dbase, $settings, $session to samo przypisywanie wartosci tez odbedzie sie poza klasa formularz.

$log - logujesz raczej w obsludze nadchodzacego wypelnionego formularza, a nie w samym formularzu, bo obsluga samego formularza to kwestia przegladarki, a nie PHP.

tak wiec, podaj konkretny przyklad jak chcesz cos rozwiazac, moze po prostu da sie cala logike danej klasy jakos lepiej rozpatrzyc, a nie tylko na sile wpychac w nia wszystkie obiekty smile.gif.
cbagov
Singleton nie pozwoli ci miec kilu kopii kiedy zajdzie potrzeba i moze powodowac konflikty w testowaniu.
Rozwiazaniem jest jak wspomnialem odwolanie przez referencje do tablicy obiektow czyli moze byc tzw. Rejestr.
Sam Rejestr mozesz -dopiero wtedy- w tzw. Singletonie zamknac bo tu S sie przyda. I to wszystko.
A zaleznosc klasy formularza od tych co wymieniles jest kompletnie nie na miejscu.
Cysiaczek
Mi właśnie chodziło (w domyśle) o rejestr, którego instancja dostępna byłaby przez singleton. To to samo, co przekazanie obiektu kontekstu przez np. konstruktor. Bardzo często, gdy przewiduję, że w którymś momencie nie dam rady przekazać obiektu, lub nie po prostu byłoby to bardzo niewygodne, to na wszelki wypadek robię z klasy Singleton (no i musi być wiadome, że to jest obiekt jednorazowej inicjacji), ale tam, gdzie mogę przekazuje go jako parametr. Ewentualnie, umieszczam w rejestrze ;]

W Symfony, bez sfContext::getInstance() ciężko byłoby przeżyć z hermetycznymi partialami ;]

Pozdrawiam.
destroyerr
Popieram rozwiązanie z kontekstem, oczywiście na wzór symfony. W wersji 1.1 nie jest to już singleton, ponieważ można mieć kilka kontekstów. Przy dobrym zaprojektowaniu singleton nie bedzie potrzebny, tylko należy go dobrze przekazywać przez obiekty.

Cytat
W Symfony, bez sfContext::getInstance() ciężko byłoby przeżyć z hermetycznymi partialami ;]

Hę? A $sf_context nie działa? tongue.gif Większość miejsc w sf pozwala na nie korzystanie z tej metody.
Black-Berry
Jak działa 'kontext'? Mógłby ktoś pokazać jak to się pisze na szybko ? Czy może to to samo co rejestr ?
LBO
Zakładam, że połknąłeś bakcyla MVC.
Wyobraź sobie, że masz kod
  1. <?php
  2. class JakiesAkcje extends Akcje
  3. {
  4. public function akcja1()
  5. {
  6. // cos tutaj robisz i nagle trzeba cos zapisac w logach
  7. $this->kontekst->logger->log('wszystko OK', Logger::DEBUG);
  8. // dalej przetwarzasz akcje i pobierasz dane z modelu
  9. $this->kontekst->pobierzModel('NazwaModelu');
  10. $zmienna = $model->pobierzZmiennaZBazy($kontekst->paramtryZadania['identyfikatorCzegostam']);
  11. // i ustawiasz te dane w widoku
  12. $this->widok->ustawZmienna('zmienna', $zmienna);
  13. }
  14. }
  15.  
  16. class NazwaModelu extends Model
  17. {
  18. public function pobierzZmiennaZBazy($id)
  19. {
  20. $db = $this->kontekst->pobierzPolaczenieDoBazy();
  21. // db moze byc na przyklad obiektem PDO i robisz zapytanie
  22. // zapytanie
  23. return $zmiennaZBazy;
  24. }
  25. }
  26. ?>
  27.  
  28. // PONIZEJ szablon dla widoku tej akcji
  29.  
  30. zmienna to <?php print $this->pobierzZmienna('zmienna'); ?>
  31. <a href="<?php print $this->kontekt->router->generujLink('jakisModul', 'jakasAkcja'); ?>">link</a>


Sęk w tym, że system powolujac do zycia akcje, model i widok powinien w jakis sposb im przekazywac obiekt kontekstu (np. w konstruktorze) i tym sposobem masz udostepnione klasy do logowania, pobierania polaczenia do bazy, pobierania modelu czy generatora linkow tylko tam gdzie to potrzebne, a nie globalnie.
Mam nadzieje, ze kod wydaje sie zrozumialy - wszystko jest po polsku, bo roznie to bywa z angielskim (bez obrazy).
Black-Berry
gorzej się czyta po polsku niz po angielsku jak dla mnie ale dzięki za pomoc smile.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.