Dobra, trochę na speedzie jest pisany ten wpis, także może być w nim parę nieścisłości i niedociągnięć, ale mam nadzieje że poprawicie mnie w komentarzach. O co chodzi? Kod tutaj opisany poniżej nie jest mojego autorstwa, niektóre treści też zrzynam bezpośrednio z książki bo nie ma innych słów by to opisać. Jest prawie na żywca zdarty z książki „PHP 5 Zaawansowane Programowanie”, także odczepić się proszę, nie piszę że ja to napisałem, jak już ktoś coś wymyślił, to nie mam zamiaru wymyślać koła na nowo, tylko poskładać wszystko do kupy i połączyć by to działało. No dobra to jedziemy. Trochę nie po kolei, z tymi klasami, ale wybaczcie. Zaczynamy.
Słowem wstępu
Jest sobie taki interfejs w php, który się zwie Iterator, posiadający 5 metod, które informują foreach jak sobie ma radzić z argumentami niebędącymi tablicą. On zaś (co jeszcze dziwniejsze) dziedziczy po kolejnym interfejsie który się zwie Travesrable. To co poniżej zobaczycie w pełnej krasie, jest implementacją mapy.
Ale do rzeczy, po cholerę nam takie pyszne rzeczy? Otóż jeżeli chcielibyśmy sobie obiektowo przechowywać elementy w zmiennej nie będącej tablicą i przeiterować jest foreachem, to jak to zrobicie? No to pokaże Wam jak to można było by zrobić:
/* odpowiedni foreach dla ($objIt as $key => $value ) */
$objIt = new MyIterator();
for( $objIt->rewind(); $obj->valid(); $objIt->next() ) {
$key = $objIt->key();
$member = $objIt->current();
}
Trochę mało to Wam mówi jeszcze, ale jak spojrzycie na dalszą część tekstu to się sami przekonacie.
Klasa Collection
Na omówieniu tej klasy, przysłużę się przykładem z książki.
Pisząc aplikację, często zachodzi potrzeba utworzeniu obiektów, które zawierają w sobie grupę innych obiektów. Na przykład w systemie obsługi dziekanatu potrzebna będzie klasa Student oraz Course. Obiekt Student zapewne będzie miał przypisany więcej niże jeden obiekt Course. Pierwsze nasuwające się rozwiążanie to dodanie tablicy obiektów Course jako zmiennej składowej obiektu Student.
Przykład z książki:
class Student {
public $courses = array();
//... itd
}
$objStudent = new Student( 124 );
foreach( $objStudent->courses as $objCourse ) {
print $objCourse->name;
}
I wracamy do omówienia problemu:
Oczywiście gdyby taki sposób był najlepszy, to by nie było mowy o klasie Collection (trochę to przerobiłem )
Powyższe rozwiązanie sprawia kilka problemów. Po pierwsze, publiczny dostęp do tablicy obiektów Course nie jest zgodny z zasadą hermetyzacji. Nie ma możliwości weryfikacji zmian w tablicy czy modyfikacji stanu obiektu Student, gdyby zaszła taka potrzeba. Po drugie, taka implementacja nie określa porządku elementów w tablicy ani sposobu odnalezienia poszukiwanego obiektu. Po trzecie, i najważniejsze, aby zapewnić dostęp do informacji o kursach każdemu użytkownikowi klasy Student, informacje te muszą zostać pobrane z bazy danych za każdym razem, gdy pobierane są informacje o studencie. Oznacza to że nawet jeśli konieczne jest jedynie wyświetlenie imienia studenta, pobierane są wszystkie informacje o kursach. Niepotrzebnie zwiększa to obciążenie serwera baz danych i zmniejsza wydajność aplikacji.
Klasa Collection została zaprojektowana tak, aby rozwiązać wszystkie te problemy. Zapewnia obiektową otoczkę dla tablicy i implementuje mechanizm leniwej konkretyzacji, czyli opóźnienia procesu tworzenia elementów kolekcji aż do czasu, gdy są one naprawdę potrzebne. Nazywa się ją „leniwą”, ponieważ decyzja o tym, kiedy tworzyć konkretne egzemplarze obiektów, jest podejmowana przez samą aplikację.
Dobra, o co ogólnie chodzi? Chodzi o to że nasza klasa Collection, jak sama nazwa wskazuje jest kolekcją obiektów, czyli dodajemy do niej obiekty, a ona zgrabnie je przechowuje w swoim ciele. I to by było na tyle z filozofią klasy Collection, żeby zbytnio nie przeciągać, to poniżej mamy już dwie gotowe klasy które razem z sobą współpracują, są na żywca wydarte z mojego FW, także BDT_Loader, jak po samej nazwie można się domyślić, wczytuje klasy, także nie mam tu nic więcej do dodania. Klasa BDT_Collection_Exception jest po prostu klasą wyjątków, i tu też nie mam nic więcej do dodania.
W naszym przykładzie będziemy potrzebowali dwie klasy, Collection (BDT_Collection) oraz CollectionIterator (BDT_Collection_Iterator). Obiekt klasy CollectionIterator jest tworzony w metodzie getIterator. Pod ciałem klasy, krótki opis.
Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...
Zwiń
Czytaj na blogu autora...