![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
![]() Grupa: Zarejestrowani Postów: 359 Pomógł: 12 Dołączył: 16.01.2009 Ostrzeżenie: (0%) ![]() ![]() |
MVC jest oczywiście jest wzorcem na ściąganie danych i obróbkę i wyświetlenie. Ale co z całą resztą? Można napisać klasy do tylko potrzebnych rzeczy, ale gdzie je poumieszczać i gdzie dawać ich wywołania?
Powiedzmy, że mam taki układ folderów: Kod application |- models |- views |- controller I napisałem sobie klasę powiedzmy do obsługi sesji. Gdzie ją umieścić i gdzie wstawiać kod operujący na tej klasie? Mam na myśli bardziej ogólne rozwiązanie, bo nie wiem co robić z różnymi dodatkowymi klasami, które nie mają nic wspólnego z MVC, ale są mi równie potrzebne -------------------- |
|
|
![]()
Post
#2
|
|
![]() Grupa: Zarejestrowani Postów: 4 340 Pomógł: 542 Dołączył: 15.01.2006 Skąd: Olsztyn/Warszawa Ostrzeżenie: (0%) ![]() ![]() |
Układ katalogów to akurat najmniej istotna sprawa. Daj sobie folder classes na równi z Application
-------------------- I'm so fast that last night I turned off the light switch in my hotel room and was in bed before the room was dark - Muhammad Ali.
Peg jeżeli chcesz uprawiać sex to dzieci muszą wyjść, a jeżeli chcesz żeby był dobry ty też musisz wyjść - Al Bundy. QueryBuilder, Mootools.net, bbcradio1::MistaJam http://www.phpbench.com/ |
|
|
![]()
Post
#3
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Tak się składa, że akurat tzw. "sesja" to nic innego jak kolejny model.
|
|
|
![]()
Post
#4
|
|
![]() Grupa: Zarejestrowani Postów: 359 Pomógł: 12 Dołączył: 16.01.2009 Ostrzeżenie: (0%) ![]() ![]() |
No dobra, to inny przykład: filtr danych, który zawierałby w sobie parser BB codu, cytowanie, nl2br i takie tam w klasie np. Filter. Albo klasa przerabiająca drzewko z mysql na tablicę to wypisania, która jednak nie może być wyświetlona "tak po prostu", tylko może być częścią treści?
-------------------- |
|
|
![]()
Post
#5
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Dobra to inaczej:
Cytat MVC jest oczywiście jest wzorcem na ściąganie danych i obróbkę i wyświetlenie. Nie. MVC to wzorzec, który kreuje architekturę całej aplikacji, sposób w jaki poszczególne warstwy aplikacji się ze sobą komunikują.To jak wygląda struktura katalogów to już jest kompletnie bez znaczenia - ot, może ona odwzorowywać nazwę klasy. Patrz na to jakie będziesz miał te klasy: - MyProject\Controller\AbstractController - MyProject\Views\TableView - MyProject\TextUtils\BBCodeParser - AnotherProject\ORM\BlahBlah - YetAnotherProject\TableDecorator - YetAnotherProject\NumberUtil\Converter |
|
|
![]()
Post
#6
|
|
![]() Grupa: Zarejestrowani Postów: 952 Pomógł: 154 Dołączył: 20.01.2007 Skąd: /dev/oracle Ostrzeżenie: (0%) ![]() ![]() |
Asmox -> to też jest model korzystający z usług dostarczanych przez framework
![]() W ogóle taka dygresja, niekoniecznie związana z Twoją osobą ![]() Ten post edytował Zyx 14.12.2010, 22:38:07 -------------------- Specjalista ds. głupich i beznadziejnych, Zyx
Nowości wydawnicze: Open Power Collector 3.0.1.0 | Open Power Autoloader 3.0.3.0 |
|
|
![]()
Post
#7
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
Asmox... Najprościej i najogólniej rzecz ujmując można napisać tak:
Model - operuje na danych, różnych jego formach, manipuluje nimi. View - służy do prezentacji danych. Controller - steruje przepływem informacji i procesami aplikacji. Rzuciłeś sesją. Ma ona gdzieś pokazywana? Nie. Wylatuje widok. Czy sesja w jakiś sposób steruje przepływem informacji w aplikacji? Nie sama w sobie jest informacją i sama siebie kontroluje oraz modyfikuje. Jest więc warstwą operacji na danych - jest więc modelem. Rzucasz filtry przykładowe? Proszę bardzo... Zwróć uwagę, że to nic innego niż zmiana, manipulacja danymi, nie wykraczająca dalej. Nie są one bowiem ani wyświetlane, ani nie jest wymagana ingerencja zewnętrzna w ten proces. Dostajesz polecenie: weź A i zrób z tego B. Znowu kłania się warstwa modelu. Warstwy mogą ze sobą współpracować.Przykład? Widok wyświetla pewne informacje, które idą do Kontrolera. Ten decyduje na podstawie działań użytkownika, że Model musi zmienić strukturę danych do innej formy i przekazać ją do Widoku ponownie.Na tym właśnie polega MVC. Rozgraniczanie obsługi pewnych czynności i funkcjonalności do wybranych warstw za nie odpowiedzialnych. Tak jak powiedział Zyx... Nie zrozumiesz, lub zrobisz to w sposób niekoniecznie dobry jeśli zaczniesz naukę "od dupy strony" ![]() Ja przez naprawdę długi czas nie wiedziałem o czymś takim jak wzorce projektowe. Ale nieświadomie je stosowałem bo wychodziły naturalnie podczas pisania. gdy zacząłem je poznawać po prostu usystematyzowałem wiedzę i tyle. Różnica jednak polegała na tym, że zanim zacząłem je stosować świadomie, miałem już kilka lat nauki obiektówki w C++ i liźnięcie Javy, która jest bardziej rozbudowana w tych dwóch językach niż w PHP. Tam specyfikatory dostępu, dzielenie zakresów działania, dziedziczenie, hermetyzacja są naturalnym elementem języka. Obiektówki się na tej bazie można uczyć i zrozumienie potem tego co w PHP lub dowolnym innym języku z nią próbują zrobić jest analogiczne. Są różnice, ale znając ogólne zasady widzisz tylko je w porównaniu do standardu. I tylko ich się uczysz. Dzięki temu nie uczysz się standardów kilku języków, ale jeden i różnice w stosunku do niego. Jest to prostsze. -------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]()
Post
#8
|
|
Grupa: Zarejestrowani Postów: 743 Pomógł: 0 Dołączył: 11.11.2003 Skąd: Toruń Ostrzeżenie: (0%) ![]() ![]() |
Podczepię się pod temat
![]() thek napisałeś: Cytat Model - operuje na danych, różnych jego formach, manipuluje nimi. View - służy do prezentacji danych. Controller - steruje przepływem informacji i procesami aplikacji. Ok, dajmy na to mamy edycję posta na forum. Zadania jakie mamy do wykonania to: 1. Odebranie zapytania http 2. Pobranie posta 3. Sprawdzenie czy on istnieje 4. Wpisanie nowej treści 5. Zapis 6. Wyświetlenie I teraz moje pytanie kto ma za co odpowiadać: 1. Controller 2. Controller za pomocą Modelu 3. Controller za pomocą Modelu 4. Controller za pomocą Modelu 5. Controller za pomocą Modelu 6. Controller za pomocą Widoku Czy dobrze rozumuję? Jeśli tak to czy taki kod z użyciem propela byłby poprawny? Kod w kontrolerze:
O co mi chodzi... Wszystko co piszę, piszę praktycznie tylko i wyłącznie w Kontrolerze (oczywiście poza widokiem), a Modelu praktycznie nie dotykam. Wywołuję tylko jego metody których dostarcza mi Propel. Czy to poprawne podejście? Czy np. sprawdzenie czy post istnieje i wpisanie treści do niego nie powinno odbyć się w modelu ? Z góry dzięki za jakiekolwiek rady. -------------------- Słońce zachodzi ... kolejna noc nadchodzi ...
|
|
|
![]()
Post
#9
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
1. Nie, MVC akurat w ogóle nie określa jak ma zostać obsłużone żądanie HTTP.
2. Tak. 3. Model - w przypadku nieistnienia może wywalić wyjątek. Kontroler może co najwyżej obsłużyć ten wyjątek - ale nie musi. 4. Tak. 5. Tak. 6. Widok za pomocą modelu. Cytat Jeśli tak to czy taki kod z użyciem propela byłby poprawny? [...] Wywołuję tylko jego metody których dostarcza mi Propel. Czy to poprawne podejście? Utożsamienie modelu z ORMem to podstawowy błąd. Model może co najwyżej tego ORMa wykorzystywać w swoich wnętrznościach.
|
|
|
![]()
Post
#10
|
|
Grupa: Zarejestrowani Postów: 743 Pomógł: 0 Dołączył: 11.11.2003 Skąd: Toruń Ostrzeżenie: (0%) ![]() ![]() |
Czyli powinienem mieć np. klasę modelu obsługującą posty forum a w niej funkcję editPost() i z kontrolera wywołać tylko model->editPost() z ewentualnie zwróconym wyjątkiem tak? A resztą powinien zająć się model.
Czyli tak: Klasa modelu
Klasa kontrolera:
O coś takiego chodzi? A może jeszcze inaczej tak:
W tym pierwszym przypadku przekazuję całe zadanie modelowi, w drugim pobieram najpierw post, a potem przekazuję go spowrotem do modelu w celu edycji. Cytat Utożsamienie modelu z ORMem to podstawowy błąd. A czy jeśli rozszerzam klasy ORM'a o własne metody, które modyfikują w jakiś sposób dane to nie są one modelem? Ten post edytował Kuziu 16.12.2010, 10:04:17 -------------------- Słońce zachodzi ... kolejna noc nadchodzi ...
|
|
|
![]()
Post
#11
|
|
![]() Grupa: Zarejestrowani Postów: 952 Pomógł: 154 Dołączył: 20.01.2007 Skąd: /dev/oracle Ostrzeżenie: (0%) ![]() ![]() |
Podstawowe kryterium brzmi: czy Twoja architektura pozwala Ci zamiast ORM-a użyć czegoś innego? Jeśli da się jako model reprezentować operacje na plikach, transmisję przez sieć czy cokolwiek innego, to OK. Od biedy takie rozwiązanie ujdzie, choć wg mnie jest ono mało elastyczne i w ten czy inny sposób prawie zawsze wymusi na Tobie przeniesienie części odpowiedzialności modelu gdzie indziej. Natomiast jeśli masz sytuację, gdzie model musi być ORM-em (błąd popełniany przez autorów co najmniej połowy frameworków), to jest już nieciekawie, bowiem Twoja aplikacja formalnie może tylko z bazy danych korzystać i z niczego innego, jako że nie możesz tego normalnie odwzorować w systemie.
-------------------- Specjalista ds. głupich i beznadziejnych, Zyx
Nowości wydawnicze: Open Power Collector 3.0.1.0 | Open Power Autoloader 3.0.3.0 |
|
|
![]()
Post
#12
|
|
Grupa: Zarejestrowani Postów: 743 Pomógł: 0 Dołączył: 11.11.2003 Skąd: Toruń Ostrzeżenie: (0%) ![]() ![]() |
Nie ograniczam się tylko do ORM chociaż szczerze mówiąc w 90% korzystam z jego funkcjonalność gdyż większość operacji jednak jest wykonywana na bazie danych.
Co do rozwiązania, mógłbyś trochę szczegółowiej opisać o tej elastyczności, którą według Ciebie tracę? -------------------- Słońce zachodzi ... kolejna noc nadchodzi ...
|
|
|
![]()
Post
#13
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
1. Model nigdy, ale to absolutnie nigdy nie powinien korzystać z danych globalnych (w ogóle nic nie powinno z nich korzystać, poza kilkoma drobnymi wyjątkami) takich jak tablica $_POST.
2. Jeżeli chcesz używać ORMa w aplikacji MVC zastanów się nad użyciem Doctrine2 - ma on inną architekturę niż Propel czy wersja 1 - niewspółmiernie bardziej przyjazną dla środowiska MVC. |
|
|
![]()
Post
#14
|
|
![]() Grupa: Zarejestrowani Postów: 952 Pomógł: 154 Dołączył: 20.01.2007 Skąd: /dev/oracle Ostrzeżenie: (0%) ![]() ![]() |
Najprostszy możliwy przykład: masz sobie widok do wyświetlania listy elementów. I teraz wyobraź sobie, że chcesz wyświetlić sobie nagłówki czegośtam pobranego przez RSS lub jakąś usługę sieciową. Jeśli powiesz, że "OK, do operacji CRUD interfejsem modelu będzie ten definiowany przez ORM-a", masz lipę, ponieważ najprawdopodobniej Twój widok będzie umiał operować tylko na modelach z bazy i nie będzie potrafił obsłużyć modelu RSS, który formalnie będzie posiadać nieco inny interfejs. Gdyby Twój interfejs modelu dla operacji CRUD i wyświetlania listy elementów był bardziej ogólny, a operacje ORM byłyby pod nim ukryte, problem by nie istniał. Zresztą, nawet nie muszą to być usługi sieciowe. Wystarczy, byś chciał wyświetlić listę plików w katalogu, albo zawartość wgranej na serwer paczki z pluginem.
Drugi rodzaj elastyczności dotyczy samej struktury bazy danych i tego, co jest w niej trzymane. Podam Ci przykład z systemu do automatycznego testowania programów, który rozwijam. Programy są ładowane przez odpowiednie formularze, więc aplikacja operuje bardzo dużą ilością plików. W pierwotnej wersji pliki były składowane na dysku, a meta-informacje o nich były w bazie. Później jednak zdecydowaliśmy się wszystko wpakować do bazy, gdyż utrzymanie spójności takiej struktury stawało się coraz trudniejsze. I tu pojawiła się lipa, bo system był zrobiony na Zend Frameworku, gdzie ORM == Model (Doctrine 1) i nagle się okazało, że aby te pliki były w bazie, muszę przepisać... większość "kontrolerów". Fajnie, co nie? Ten post edytował Zyx 16.12.2010, 15:46:12 -------------------- Specjalista ds. głupich i beznadziejnych, Zyx
Nowości wydawnicze: Open Power Collector 3.0.1.0 | Open Power Autoloader 3.0.3.0 |
|
|
![]()
Post
#15
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
W przypadku edycji posta i MVC część wyjaśnił Ci już Crozin. Ogólnie wyglądało by to tak, że kontroler ze strony dostaje wszystkie dane i musi zdecydować co zrobić. Ogólnie powinien te dane pchnąć do modelu (nawet dane superglobalne powinny do niego iść jako parametr a nie jawnie poprzez użycie choćby $_POST już wewnatrz), który zacznie odwalać całą robotę. Błędy zaś zasygnalizuje kontrolerowi. Jeśli jednak wszystko pójdzie OK to są dwa podejścia:
1. Model sam wywołuje Widok 2. Model zwraca obrobione dane do Kontrolera, który decyduje o tym jaki Widok zajmie się ich wyświetleniem. To drugie rozwiązanie jest najczęściej spotykane we frameworkach. -------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]()
Post
#16
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
@thek:
Ad. 1) Chyba na odwrót? Bo jak model miałby wywołać widok? Ad. 2) I nie ma to wtedy zbyt wiele wspólnego z MVC... w dodatku w takim przypadku widok = szablon. |
|
|
![]()
Post
#17
|
|
![]() Grupa: Zarejestrowani Postów: 441 Pomógł: 71 Dołączył: 3.09.2007 Skąd: wrocław Ostrzeżenie: (0%) ![]() ![]() |
No to ja też mam małe pytanko w temacie, gdzie np. walidować dane - w kontrolerze czy w modelu ?
-------------------- |
|
|
![]()
Post
#18
|
|
![]() Grupa: Zarejestrowani Postów: 2 291 Pomógł: 156 Dołączył: 23.09.2007 Skąd: ITALY-MILAN Ostrzeżenie: (10%) ![]() ![]() |
No to ja też mam małe pytanko w temacie, gdzie np. walidować dane - w kontrolerze czy w modelu ? kontroler....w modelu co najwyzej mozesz walidowac "operacje" na plikach/baza danych/sockety itp...itd... -------------------- Zainteresowania: XML | PHP | MY(SQL)| C# for .NET | PYTHON
http://code.google.com/p/form-builider/ Moj blog |
|
|
![]()
Post
#19
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
ad1) i tutaj właśnie dotykamy tego czym jest faktycznie i jak powinno działać MVC
![]() ![]() ad2) Masz rację. Ale czyż widoki nie są tak naprawdę szablonami? Widok ma po prostu dostać dane i je zaprezentować w jakiejś formie, którą ma zaprogramowaną. W zależności od danych może je nieco inaczej przedstawić, ale na tym się jego funkcjonalność kończy. Zmiana formy prezentacji pociąga za sobą pewne zmiany w pracy Modelu, przestawienie go na nieco inny tryb, gdzie używa innych funkcji własnych. Najprościej to "pokazać". Masz dane które normalnie wyświetlasz jako strony, ale możesz także w GUI określić, że "jeśli mam ten przełącznik aktywny w widoku, to nie wyświetlaj ich, ale zwracaj mi w wyniku pliki pdf.". Takie działanie zmusiło by Model do nieco innej pracy. -------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]()
Post
#20
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
1) Pytałem w kontekście aplikacji webowej, gdzie jest to niemożliwe ze względu na środowisko pracy (protokół HTTP). Chociaż w sumie można to już teraz osiągnąć wykorzystując WebSockets (albo [tutaj nazwa projektu/ów] które to symulują tam gdzie nie ma natywnego wsparcia dla WS), ale nie AJAX.
2) Gdyby widok miałby być szablonem, to wzorzec by się nazywał MTC - nie byłoby potrzebny na wprowadzanie nowych terminów. Tak jednak nie jest.
Cytat kontroler....w modelu co najwyzej mozesz walidowac "operacje" na plikach/baza danych/sockety itp...itd... Oczywiście, że nie kontroler, a model. Ten pierwszy nawet nie do końca może wiedzieć z czym ma do czynienia, tylko i wyłącznie model wie jakie dane są dla niego odpowiednie.
Ten post edytował Crozin 17.12.2010, 11:52:37 |
|
|
![]() ![]() |
![]() |
Aktualny czas: 19.08.2025 - 07:02 |