![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 663 Pomógł: 6 Dołączył: 3.06.2007 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
*Plik Bootstrap* Każdemu obiektowi który ma mieć zakres globalny przekazujemy w konstruktorze context
Każdy obiekt globalny dziedziczy po klasie System_Object
Obiekt Kontext
Przykłądowa klasa. Wszystkie inne na podobnej zasadzie. Nie ma żadnych setterów, getterów, wszystko bez zbędnych kodów.
sposób użycia
Moim zdaniem to musi być ostateczne rozwiązanie problemu globalsów. Bardzo proszę o dyskusję Czy singletony zamiast tego byłyby wydajniejsze ? Podobno singletony to zło. Ja już zgupłem do reszty @_@ Ten post edytował Black-Berry 5.11.2008, 09:24:28 |
|
|
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 246 Pomógł: 31 Dołączył: 13.11.2006 Skąd: się znamy? Ostrzeżenie: (0%) ![]() ![]() |
Masz racje. Singleton zazwyczaj oznacza źle zaprojektowaną aplikacje: to taki GOTO OOP.
Najważniejsze jest zaplanowanie odpowiedniego workflow obiektów. Rozwiązanie z przekazywaniem obiektów jest dobre. Dodałbym jeszcze interface dla każdej z klas i zamiast bezpośredniego dostępu przez get i sety (private $contex) odpowiednie metody. Nie wszędzie potrzebujesz automagiczności a dostęp przez metody daje dodatowe możliwości nadpisania po drodze przez dziecko (tak samo nie wymagaj klasy ale instanceof). |
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 663 Pomógł: 6 Dołączył: 3.06.2007 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
|
|
|
![]()
Post
#4
|
|
Grupa: Zarejestrowani Postów: 246 Pomógł: 31 Dołączył: 13.11.2006 Skąd: się znamy? Ostrzeżenie: (0%) ![]() ![]() |
Oczywiście korzystanie z referencji jest szybsze.
Nie musisz pobierać instancji obiektu ale masz do niego bezpośredni "skrót". Typując parametr po nazwie klasy pozwalasz przekazać tylko obiekty danej klasy. Używając instanceof w połączeniu z interface zapewniasz sobie spójne API jeśli chciałbyś kiedyś podmienić którąś z klas. Np.: ? Request -> (WebRequest/ConsoleRequest). To właśnie jest istotą OOP. Obiekty mają pracować ze sobą a nie być połączone na sztywno. |
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 879 Pomógł: 189 Dołączył: 14.06.2006 Skąd: Bytom Ostrzeżenie: (0%) ![]() ![]() |
empathon mylisz się. Type hinting właśnie służy do tego co opisałeś. Jeśli zdefiniujesz interfejs i w klasach będziesz go implementował to spokojnie to zadziała. Może jak zobaczysz kod to sobie przypomnisz bo na pewno o tym wiesz:
Co do tematu to od siebie dodam, że warto zainteresować się wzorcem http://martinfowler.com/articles/injection.html W kontekście php najlepszą prezentacją jaką widziałem jest ta. A w niej 3 kluczowe linki do projektów: http://phpcrafty.sourceforge.net/ http://garden.tigris.org http://www.stubbles.net/wiki/Docs/IOC |
|
|
![]()
Post
#6
|
|
Grupa: Zarejestrowani Postów: 53 Pomógł: 1 Dołączył: 28.09.2007 Skąd: Gdynia Ostrzeżenie: (0%) ![]() ![]() |
Witam
Znalazłem inne rozwiązanie problemu globali. Moje podejście jest minimalistyczne. Minimum pisania, maximum czytelności, pełna funkcjonalność. Używam statycznych singletonów, najprościej przedstawię to na hiper-uproszczonym przykładzie. Dodaję sobie do aplikacji klasę app, która jak sama nazwa wskazuje, trzyma dane aplikacji... Kod class app { public static $qa; ... } Zmienna app::$qa przechowuje mi np informację, czy aplikacja jest odpalona w trybie testowym. W dowolnym miejscu kodu sprawdzam sobie... Kod if (app::$qa) ... ...i pozamiatane. Stanu aplikacji nie muszę "przekazywać" do modułów. Mogą sobie go sprawdzać od ręki, w każdej chwili, mogą go też zmieniać. W zasadzie moja klasa app jest też pewnym rodzajem rejestru, ale prostszym. Dodatkowo posiada pewną kolosalną przewagę: jeśli używasz Eclipse, ZendStudio, albo podobnego cuda z opcją CodeAssist lub AutoComplete - wszystkie klucze tego rejestru będą się "wklepywać" automatycznie po wpisaniu 1, góra 3 pierwszych liter. Oczywiście klasa app w rzeczywistości robi dużo więcej poza samym trzymaniem stanu. Najpierw inicjuje się, inicjuje całą aplikacje, wgrywa pliki, otwiera bazę, no wszystko co tam jest potrzebne na dzień dobry i nie podpada pod specjalistyczne moduły. Ciekawi mnie, jakie moje rozwiązanie ma wady i dlaczego kurcze nikt takiego myku nie używa? Ten post edytował pp-layouts 3.11.2008, 22:55:43 |
|
|
![]()
Post
#7
|
|
Grupa: Zarejestrowani Postów: 663 Pomógł: 6 Dołączył: 3.06.2007 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
(..)Co do tematu to od siebie dodam, że warto zainteresować się wzorcem dependency injection (..) Dzięki za linki. Trochę poczytałem i wydaje mi się że to co ja napisałem to właśnie ten wzorzec tylko całkowicie zautomatyzowany. Czy się nie mylę?Ciekawi mnie, jakie moje rozwiązanie ma wady i dlaczego kurcze nikt takiego myku nie używa? Myślę że temu, że to przeczy zasadom obiektowości. Poza tym większość ludzi używa singletonów na podobnej zasadzie a ponoć są szybsze niż klasy statyczne ale mogę się mylić. Moje rozwiązanie różni się tym od Twojego, że (na podstawie tego co mi napisał empathon) jest o wiele szybsze w działaniu. A poza tym przy lekkiej modyfikacji możnaby do różnych klas dodawać różne konteksty. Myślę, że moje rozwiązanie nadaje się tylko dla leniwych ale ja jestem raczej leniwy więc mi leży. |
|
|
![]()
Post
#8
|
|
Grupa: Zarejestrowani Postów: 1 387 Pomógł: 273 Dołączył: 18.02.2008 Ostrzeżenie: (0%) ![]() ![]() |
Black-Berry, nie wiem czy do końca zrozumiałem Twój kod, ale imho trochę go przekombinowałeś. Jeżeli coś palnąłem, to mnie popraw (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)
Czyli z obiektu $context pobierasz listę elementów i w pętli (no właśnie - po co w pętli? Zwykłe przypisanie nie zadziała?) ładujesz wszystkie obiekty do tablicy $this->context, do której upraszczasz sobie później dostęp przez gettera. A co jeżeli po tym obiekcie, doda się następny? Nie będziesz miał do niego dostępu - lista elementów będzie już stara. Poza tym, dostęp do obiektów nie powinien być taki prosty. W ten sposób mieszasz elementy klasy z globalnymi. Poza tym pozwalasz na takie cuda:
Co ma obiekt $buffer, do bazy danych? (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg) Ja u siebie robię to tak: mam jeden główny obiekt $ffCore który zajmuje się wczytywaniem innych i 'komunikacją' między nimi. Początek przykładowej klasy wygląda tak:
Utworzenie jej obiektu:
Główny kontroler sprawdza, czy zawiera już instancję obiektu o takiej nazwie. Jeżeli nie, tworzy ją. W przy tworzeniu, '$ffCore' przekazuje swoją instancję w konstruktorze i umożliwia mu stworzenie aliasów do innych obiektów, które będą potrzebne. A jeżeli jakiś obiekt pojawi się później, zawsze mogę utworzyć alias do samego $ffCore, czego jednak staram się unikać. |
|
|
![]()
Post
#9
|
|
Grupa: Zarejestrowani Postów: 663 Pomógł: 6 Dołączył: 3.06.2007 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Dzxięki L0ud. Wszystko o czym mówisz jest całkowitą prawdą. Pętla była pozostałością po czymś co przestało być potrzebne i teraz już ją wywaliłem. Muszę to przemyśleć jeszcze raz bo faktycznie starsze elementy nie mają dostępu do nowych. Cuda takie jak to:
chyba nie będą takim problemem bo każdy kto trochę myśli to zamiast tego napisze:
No i czasem buffer też potrzebuje dbDrivera jeśli np będzie chciał cach'a całej strony zapisać do bazy danych. Mówi się dużo na temat ukrywania niektórych obiektów ale piszę już ponad rok i zawsze wychodza takie sytuacje w których jeden obiekt wymaga takiego o którym wcześniej nie pomyslałem i wtedy znowu trzeba przerabiać konstruktor, tworzyć nowego settera, gettera. Trochę się mi to już znudziło i chcę to maksymalnie zautomatyzować. Edit: Tak po chwili zastanowienia... Czy obiektr language potrzebuje obiektu user? Albo czy config potrzebuje dbDriver? Myślę, że nie i takie hierarchiczne poukładanie jest pewną formą wyłączenia zbędnych obiektów z obiegu. Idąc w górę drzewka zawsze znajdę powiązanie. Np language potrzebuje session. Idąc w dół nie widzę takich zależnosci ale może ktoś się do tego ustosunkuje. P.S. Dlaczego masz takie dziwne prefiksy klas 'ff' (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) ? Ten post edytował Black-Berry 5.11.2008, 09:50:42 |
|
|
![]()
Post
#10
|
|
Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Cytat P.S. Dlaczego masz takie dziwne prefiksy klas 'ff' ? PHP nie obsługuje jeszcze przestrzeni nazw (namespace) i trzeba sobie jakoś radzić z unikalnym nazewnictwem klas. "ff" jest zapewne skrótem od nazwy projektu, na przykład nazwa sfRequest oznacza Request z projektu symfony (działa to na dokładnie takiej samej zasadzie jak prefiksy w nazwach tabel w bazie danych).
|
|
|
![]()
Post
#11
|
|
Grupa: Zarejestrowani Postów: 663 Pomógł: 6 Dołączył: 3.06.2007 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
No tak ale osobiście źle mi się to czyta. Może lepiej tak jak w zendzie. Jeśli masz framework o nazwie Ziuziu to klasy piszesz
Ten post edytował Black-Berry 5.11.2008, 14:53:17 |
|
|
![]()
Post
#12
|
|
Grupa: Zarejestrowani Postów: 1 387 Pomógł: 273 Dołączył: 18.02.2008 Ostrzeżenie: (0%) ![]() ![]() |
'ff' to skrót od nazwy projektu. Akurat nazewnictwo to sprawa indywidualna (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg) Ja do nazywania czegokolwiek używam mixedCase, a Ci wygodniej inaczej - coś jakby CamelCase ze znakami podkreślenia.
Wracając do tematu, pokazałem swój sposób rozwiązania tego problemu. Po prostu w konstruktorze odbieram $ffCore i z niego robię sobie aliasy do wymaganych mi obiektów. Dzięki temu później w klasie nie mam dostępu do niepotrzebnych obiektów i od razu widzę jakie ma zależności. Gettera mogę wykorzystać do czegoś innego i nie mam problemów typu brak hermetyczności (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg) Pozdrawiam |
|
|
![]() ![]() |
![]() |
Aktualny czas: 27.09.2025 - 05:38 |