Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MVC] Pytań kilka...
Forum PHP.pl > Forum > PHP > Pro > Archiwum Pro
Stron: 1, 2, 3, 4
Zepco
Ponieważ nie mam dostępu do forum DEV, a wiem, że tam po części problem MVC był poruszany, postanowiłem zadać kilka pytań.

Coraz więcej mówi/pisze się na temat MVC (Model-View-Controller) ale pomimo usilnych starań nie mogę zrozumieć pewnych mechanizmów, tymbardziej, że większość przykładów podawanych jest w Java'ie.

Może zacznę od tego co już wiem, jeśli się mylę, proszę poprawcie mnie. smile.gif
Cała aplikacja składa się z trzech części:

:arrow: Kontrolera, który odbiera operacje z zewnątrz (input) i odpowiednio je przetwarza, wywołując konkretny model (modułu) i metodę tegoż modelu. Może również odwoływać się bezpośrednio do widoku.

:arrow: Modelu, który jest niejako modułem odpowiedzialnym za jakiś ułamek pracy aplikacji (menu, news, sonda itp, itd.). Także jak widać w przeciwieństwie do kontrollera istnieje wiele modeli. Jak wcześniej wspomniałem model odbiera od kontrolera odpowiednie rządania, przetwarza je i wynik może przesłać do widoku.

:arrow: Widok natomiast wszystkie dane wysłane z modelu lub kontrolera wysyła na zewnątrz (wyświetla wynik na WWW, tworzy dokument XML, PDF itp.). Tak więc może być kilka podwidoków, które wywołane przez widok głowny tworzą efekt końcowy widoczny dla użytkownika.

A teraz czas na pytania:
* w jaki sposób elementy te komunikują się?
* wiem, że najbardziej naturalnie będzie zastosować programowanie obiektowe, ale czy da się to zrobić strukutralnie?
* co jest w przypadku gdy jeden model jest zależny (potrzebuje danych) od drugiego modelu?
* czym są akcje (actions) i łańcuchy (chains)?

Jeśli coś pominąłem, proszę dopiszcie, Myślę, że dyskusja na ten temat wpłynie w jakimś stopniu na rozpowrzechnienie tego rozwiązania, a chyba na tym nam zależy, aby łatwiej tworzyć aplikacje webowe i w przyszłości korzystać z już napisanego kodu...
rzseattle
No wiec tak sorry ale odpowiem nie po kolei :

ad 4

Akcje sa to logicznie podzieone operacje tzn ze w akcji starasz sie zawrzec najbardziej niepodzielna operacje jaka sie da. Czyli na przyklad akcje : zaloguj, usun artykul, dodaj artykul, pokaz menu itd. Akcje dzielimy naa logiczne i widoki. Akcje logiczne sa odpowiedzialne za realizacje zadan takich jak dodaj, usun, powiarz, sprawdz itd. podczas gdy akcje widoki maja za zadanie zwrocic dane do przegladarki.
Łancuch akcji polega na tym ze jezeli wciskasz przycisk usun artykul to najpierw wlacza sie akcja potwierdzajaca wybor potem ta akcja uruchamia akcje usuwajaca artykul ktora z kolei wywluje widok pokazujacy liste artykulow, taki lancuszek.

ad 1

Kontroler dostajac odpowiednie dane uruchamia odpowiednia akcje ktora uruchamia odpowiedni model. Mozna ten schemat komplikowac ale generalnie tak to wyglada.

ad 2

Jesli udalo by ci sie to oprogramowac strukturalnie to ja chcialbym taki silnik zobaczyc winksmiley.jpg

ad3

Wlasniesie spotkalem z takim problemem. No coz poprostu w akcji uruchamiam dwa modele.

ps Dodamtylko ze zadaniem modelu jest tylko i wylacznie stworzenie abstrakcji na dane tak aby jezeli sie cos zmieni np. w bazie to grzebiesz tylko w modelu a nie we wszystkich akcjach.
radziel
Cytat
[...] Modelu, który jest niejako modułem odpowiedzialnym za jakiś ułamek pracy aplikacji[...]


Mylisz dwa pojęcia,
model ma za zadanie komunikację z bazą i zwracanie danych.

moduł to zbiór akcji które sąodpowiedzialne za "przetwarzanie" danych z modelu.

Mam nadzięję że dobrze wytłumaczyłem winksmiley.jpg
rzseattle
Cytat(radziel)
Mylisz dwa pojęcia, 
model ma za zadanie komunikację z bazą i zwracanie danych.

moduł to zbiór akcji które sąodpowiedzialne za "przetwarzanie" danych z modelu.

Mam nadzięję że dobrze wytłumaczyłem winksmiley.jpg


No nie do konca winksmiley.jpg. To nie musi byc koniecznie baza danych, moga byc pliki, xml czy jeszcze jakies inne zrodlo danych.
radziel
Cytat
No nie do konca winksmiley.jpg. To nie musi byc koniecznie baza danych, moga byc pliki, xml czy jeszcze jakies inne zrodlo danych.


No tak, ale wkażdym razie model zwraca dane do obróbki winksmiley.jpg
Zepco
Cytat
No wiec tak sorry ale odpowiem nie po kolei :
ad3

Wlasniesie spotkalem z takim problemem. No coz poprostu w akcji uruchamiam dwa modele.


Nie wiem czy dobrze rozumiem, ale w pliku konfiguracyjnym mógłby być wpis o zależności (dependencies) od innego modelu.

A jak sprawa ma sie z widokiem i podwidokami?
Czy widok jest tą klasą główną, która wysyła dane do odpowiedniego podwidoku, a ten wysyła go na wyjście, czy też wyborem widoku zajmuje się kontroler?
rzseattle
Cytat
Nie wiem czy dobrze rozumiem, ale w pliku konfiguracyjnym mógłby być wpis o zależności (dependencies) od innego modelu.

A jak sprawa ma sie z widokiem i podwidokami?
Czy widok jest tą klasą główną, która wysyła dane do odpowiedniego podwidoku, a ten wysyła go na wyjście, czy też wyborem widoku zajmuje się kontroler?


Jak juz wspomnialem model jest klasa tworzaca abstrakcje na zrodla danych, wiec jesli potrzebuje w danej akcji dwoch modelow to poprostu includuje oba i kozystam z dwoch przy czym jeden o drugim nie musi nic "wiedziec".

Nie rozumie co rozumiesz przez polwidok?? Akcje logiczna?

Lancuszek akcji jest tworzony w ten sposob:

1) Router "dekoduje" url i wysyla do kontrolera jak akcje ma uruchomic
2) Kontroler sprawdza czy akcja potrzebuje zalogowania , czy jest plik akcji itd...
3) Kontroler uruchamia akcje.
4) Akcja wykonuje sie i po zakonczeniu wywoluje inna akcje
5) Na koncu jest zawsze akcja - widok ktora wysyla dane do przegladarki i nie wywoluje juz innej akcji
6) Wykonywany jest destruktor kontrolera

THE END winksmiley.jpg

Przedstawilem to w sporym uproszczeniu, ten schemat tez mozna komplikowac, ale mniej wiecej tak to dziala.
Zepco
Specyfikacja URLa oczywiście nie ma znaczenia i zależy jedynie od wyobraźni twórcy?
Czy dane wysłane przez POST i GET oraz te, które są zawarte w SESSIONS wyciągane są bezpośrednio przez modele, czy też tym też zajmuje się kontroler?
radziel
Cytat
Specyfikacja URLa oczywiście nie ma znaczenia i zależy jedynie od wyobraźni twórcy?
Czy dane wysłane przez POST i GET oraz te, które są zawarte w SESSIONS wyciągane są bezpośrednio przez modele, czy też tym też zajmuje się kontroler?

Zajmuje się tym kontroler - najlepiej napisz klasę / funcję (zależy jak programujesz winksmiley.jpg ), która będzie zajmować się danymi z input'a.
rzseattle
Cytat
Specyfikacja URLa oczywiście nie ma znaczenia i zależy jedynie od wyobraźni twórcy?


I od konfiguracji serwera winksmiley.jpg

Cytat
Czy dane wysłane przez POST i GET oraz te, które są zawarte w SESSIONS wyciągane są bezpośrednio przez modele, czy też tym też zajmuje się kontroler?


Nie trzeba MVC zeby wiedziec ze w pozadnym silniku nie uzywa sie tych tablic ( bezpieczenstwo). Tak na wstepie konstruktor kontrolera powinien wywolywac obiekt input ktory zajmie sie skladowaniem danych zewnetrznych. Sesje tez najlepiej zamaskowac pod jakas metoda kontrolera. Pamietaj tez ze zmienna z jednej akcji nie bedzie widoczna w drugiej wiec tez musisz pomyslec nad sposobem przekazywania tych zmiennych. Najlepiej wtedy dodac opcjonalny argument dla metody zapisujacej zmienna ktory powie "umiesc mnie w sesji" smile.gif.

ps Nie przesadzaj z tym Pomogl Mi
kubatron
A mógłbym zapytać gdzie to można ściagnąć jak zainstalować,jakis kurs/manual i co to jest rolleyes.gif
scanner
Jeden z dostępnych: http://phiend.sourceforge.net
Nalfein][WR
Cytat
Nie wiem czy dobrze rozumiem, ale w pliku konfiguracyjnym mógłby być wpis o zależności (dependencies) od innego modelu.


Mógłby być, ale po co. Możesz po prostu includować (bezpośrednio przez include() lub przez inny obiekt - menedżera klas aplikacji) plik z klasą odpowiedniego modelu z poziomu innego modelu.

Cytat
A jak sprawa ma sie z widokiem i podwidokami?
Czy widok jest tą klasą główną, która wysyła dane do odpowiedniego podwidoku, a ten wysyła go na wyjście, czy też wyborem widoku zajmuje się kontroler?


Wyborem widoku zajmuje się kontroler, a raczej (przeważnie) ostatnia akcja w łańcuszku, tutaj nazywamy ją akcją widoku, gdzieniegdzie możesz ją znaleźć pod nazwą kontrolera widoku (ViewController). W niej ładujesz i wypełniasz szablon. Akcja widoku wypełnia sam widok, czyli przeważnie szablon Smarty, arkusz XSLT. Sam widok przeważnie nie jest klasą, chyba, że zastosujesz technikę kompilacji szablonów do klas. Na razie takiego engine-u pod php nie ma, ale już się robi (u mnie tongue.gif). Do widoku przekazujesz dane, porcję danych, możesz ją przechowywać w osobnej warstwie obiektów typu DataSpace/DataProvider, wtedy akcja widoku po prostu wybiera obiekty "dostawców danych" i obiekt(y) "widoku". Podwidoków w php nie ma wyodrębnionych jako tako, gdyż jak już wspomniałem widok jest płaski, inne widoki po prostu {include}-ujesz przez Smarty jak zwykłe fragmenty szablonów.
bumelang
Cytat
Jak juz wspomnialem model jest klasa tworzaca abstrakcje na zrodla danych [ciach!]


Może jestem nadgorliwy, ale chodzi bardziej o to, że w kontrolerze nie są podejmowane żadne działania z zakresu logiki aplikacji. Kontroler steruje widokami, czyli po prostu interface'm użytkownika, zaś całość logiki zawiera się w modelu. Różnica jest taka, że model nie reprezentuje źródła danych. Fakt, że typowy model to np. wywołanie
[php:1:e6cd80946a]$managerProduktow->dodajProdukt($p)[/php:1:e6cd80946a]
ale od abstarkcji na źródło danych różni się to tym, że model może tu robić niezłą zamotkę z danymi, która z punktu widzenia kontolera jest nieistotna, i tu jest prawdziwy zysk - ktoś zmienia implementację logiki, ale logika prezentacji się nie zmienia.

Z resztą nie da się ukryć, że MVC ma największy sens przy aplikacjach heterogenicznych, gdzie model jest napisany w innym języku programowania, albo przynajmniej jest uruchamiany na innym serwerze.
rzseattle
Cytat
zaś całość logiki zawiera się w modelu.

Musze przyznac ze sie pogubilem. Tworzac pod MVC nie spotkalem sie z sytuacja kiedy model w oparciu o dostarczone mu dane mial decydowac co ma zrobic ( a tak chyba definiujemy logike aplikacji :?: ), wrecz przeciwnie wszystko jest umieszczone w pojedynczych akcjach i to one decyduja co zrobic, przekazujac to modelowi ktory wie jak i gdzie. Jakdla mnie to jest czysta abstrakcja na zrodlo danych

Cytat
... ale od abstarkcji na źródło danych różni się to tym, że model może tu robić niezłą zamotkę z danymi, która z punktu widzenia kontolera jest nieistotna, i tu jest prawdziwy zysk - ktoś zmienia implementację logiki, ale logika prezentacji się nie zmienia.


Jesli mozna wiedziec to co rozumiesz przez "zamotke z danymi". Bo dla mnie zbior operacji ukryty pod jedna metoda to juz jest abstrakcja i biorac pod uwage ze model zajmuje sie danymi zewnetrznymi ( przeciez nie robimy w akcji $mathModel->dodaj($this->input['a'], $this->input['b'], $this->input['c']) ) to dla mnie jest to abstrakcja na zewnetrzne zrodla danych. A to czy operacje na danych sa proste czy skomplikowane to mnie nie interesuje.

No ale moze zle rozumie stwierdzenie "Logika aplikacji" winksmiley.jpg
bumelang
Wszystko wskazuje na to, że mamy odmienne pojęcia na "abstrakcję źródła danych". Z tego, co wiem, to w typowym znaczeniu oznacza ona po prostu klasę dostępową do źródła, niezależną od implementacji na konkretnej bazie danych czy pliku - taki API, jak np. AdoDB.

Innymi słowy, w 3-warstwowym modelu aplikacji najniżej jest warstwa dostępu do danych (do której API dostępu z warstwy drugiej można określić "abstrakcją na źródło danych", jeśli takie jest zastosowane).

Warstwa druga, która jest najczęściej modelem, stanowi tymczasem zbiór klas czy funkcji tzw. "logiki biznesowej", co przede wszystkim oznacza, że ta warstwa + warstwa danych tworzy gotową aplikację - realizuje wszystkie zadane operacje na bazie danych, uwierzytelnianie użytownika, tworzy jakieś logi, wywołuje jakąś usługę SOAP, wysyła maila, cokolwiek, ale jest to kompletny, działający system, tyle, że zamiast interface'u użytkownika udostępnia API programistyczne dla warstwy jeszcze wyższej.

Warstawa kontrolera i widoku to tymczasem warstwa prezentacji, czyli jeszcze wyżej. I teraz wygląda to tak, że użytkownik się loguje, łaczy się z kontrolerem, któremu przesyła żądanie, ten czyści dane wejściowe i jeśli wszystko jest ok wywołuje funkcję zaloguj($login, $haslo) warstwy logiki biznesowej (czyli model) i sprawdza, czy to się powiodło, ale nie wie nic o szczegółach implementacji w modelu i - przede wszystkim - nie ma dostępu do bazy danych, nie może wywołać żadnego zapytania SQL. Później kontroler przekazuje sterowanie do odpowiedniego, w zależności od powodzenia operacji, widoku - ale to jest jasne.

Oczywiście 3-warstwowy model aplikacji jest tu tylko po to, żeby objaśnić zagadnienie modelu jako takie w kontekście "abstrakcji źródła danych". W rzeczywistym systemie z zastosowanym MVC mogą być z równym powodzeniem tylko 2 warstwy - sama prezentacja i model.

Jak widzisz, być może że tylko 1 pojęcie sprawiło, że myślisz, że tego nie rozumiesz, a rozumiesz - jeśli tak to sorry za zamotkę winksmiley.jpg
rzseattle
Cytat
Warstwa druga, która jest najczęściej modelem, stanowi tymczasem zbiór klas czy funkcji tzw. "logiki biznesowej", co przede wszystkim oznacza, że ta warstwa + warstwa danych tworzy gotową aplikację - realizuje wszystkie zadane operacje na bazie danych, uwierzytelnianie użytownika, tworzy jakieś logi, wywołuje jakąś usługę SOAP, wysyła maila, cokolwiek, ale jest to kompletny, działający system, tyle, że zamiast interface'u użytkownika udostępnia API programistyczne dla warstwy jeszcze wyższej.


No maly OT sie zrobil. Ale czy udostepnianie API programistycznego ktore maskuje wszelkie zrodla danych i nie wymaga wiedzy skad i dokad podazaja zmienne nie jest abstrakcja na zrodlo. Dla mnie wlasnie tu jest granica - Dopiero tam gdzie przestajemy sie interesowac czy dane pochodza z ADoDB czy jakiegos obiektu obslugujacego XML konczy sie abstrakcja. Ale rozumiem twoje podejscie , jednak zauwaz ze np ADoDB tez udostepnia API programistyczne ktore ulatwia obsluge bazy danych.

No ale jak juz powiedzialem OT smile.gif.
bumelang
Być może to jest OT, ale nie wiem, czy można nazwać abstrakcją na źródło danych coś, co nie koniecznie operuje na danych w bazodanowym sensie i nie koniecznie ma dostęp do źródła danych. Przecież model może np. pobrać informacje o dostępności produktu przez SOAP, sprawdzić stan rachunku bankowego, zamówić produkt i przelać kasę. I to wszystko w jednym wywołaniu modelu.

A warto też dodać, że model może być np. aplikacją w C, która ma za zadanie obliczyć symulowane odsetki, a kontroler tylko robi exec('/usr/bin/odsetki -sklada_miesieczna 3000');
Zepco
Jak dla mnie takie OT mogą być, o ile mieszczą się w pewnych ramach tematu tak jak powyższa polemika. :-)

Tak na marginesie chciałem zapytać skąd czerpaliście informacje na temat MVC?
Sh4dow
Moze troche sie wtrącam do waszej zrozmowy, ale moze powiecie mi pare rzeczy. Jako ze nie obeznany jestem tak jak Wy, nie zawsze kojaze co za skroty uzywacie, albo jakies pojecia anglojezyczne. No ale nie o oto i do konca chodzi. Jak napisal scanner ze jeden z takich MCV jest dostepny na necie oczywiscie tam zagladolem. Ale niestety moja wiedza tajemna nie byla wstanie przegrysc samego manuala, wiec o testach na phiendzie nie bylo mowy.
Ale po kolejnych postach zaczyna cos mi swiatac na temat calego tego MVC.

Bumelang napisał o 3 warstwowym poziomie aplikacji, szczerze mowiac dopiero jego post dal mi do myslenia jesli chodzi o cale zagdanienie MVC.

Jesli dobrze zrozumialem do pierwsza warstwa jest odpowiedzialna za pobranie danych, naprzyklad skrypt rozpoznaje zapytanie, np User chce zobaczyc na stronie komantarze do artykulu, wiec skrypt rozpoznaje ze chodzi o komentarze o jakies danej specyfikacji, wiec lpobiera dane dla tej specyfikacji (pliki, bazy danych, sockets itd). Procz tego apytania, sa standardowe zapytanie, powiedzy o konfiguracje strony (tytul, adres, kolor itd). Jako standardowe zapytanie przy wiekszosci odslon.
Ta warstwa teoretycznie konczy swoje zadanie i przesyła dane do drugiej warstwy, której zadaniem jest przetworzenie wszystkich otrzymanych danych. Tutaj nawołując do przykladu, skrypt powiedzmy ze w komentarzach przetwarza text (np BBcode) ustawia zapis daty i jakie pare tam innych opcji mniej waznych.
Przetworzone dane wędruja teraz do warstwy ktora zajmuje sie wyswietlanie, powiedzmy ze beda to Smarty, które generuja nam gotowy kod wysylany do przegladarki. i tutaj piszecie jeszcze o wykonaniu destruktora.

A teraz pare Pytanek:
- czy dobrze zrozumialem to zagadnienie? oczywiscie jest ono mocno uproszczone.
- czy warstwa 2(czyli przetwarzanie danych) moze czesciej pobierac dane z 1 warstwy? Np. po otrzymaniu danych, podczas przetwarzania pobrac dodatkowe informacje, czy trzeba przewidziec to w 1 warstwie i wyslac odrazu.
- czym jest destruktor, jakie jest jego działaniei i co sie stanie jesli go nie bedzie?
Cytat
Oczywiście 3-warstwowy model aplikacji jest tu tylko po to, żeby objaśnić zagadnienie modelu jako takie w kontekście "abstrakcji źródła danych". W rzeczywistym systemie z zastosowanym MVC mogą być z równym powodzeniem tylko 2 warstwy - sama prezentacja i model.

czy zalozenie 2 warstw mam rozumiec poprze poprzez polaczeni pierwszej i drugiej? Ma to jakas zalete?
hawk
Cytat
Jak napisal scanner ze jeden z takich MCV jest dostepny na necie oczywiscie tam zagladolem. Ale niestety moja wiedza tajemna nie byla wstanie przegrysc samego manuala, wiec o testach na phiendzie nie bylo mowy.

Hmm, jako autor phienda potwierdzam że proste to-to nie jest. A moje anty-patriotyczne podejście do lokalizacji manula :oops: niektórym nie ułatwia sprawy. Ale podobno gdzieś tutaj na forum powstaje tłumaczenie.

Ja myślę że kojarzenie MVC z warstwami jest zbytnim uproszczeniem. Owszem, MVC wymusza podział aplikacja na warstwy (w ogóle wymusza sensowną organizację aplikacji). Ale warstw może być więcej niż 3, np:

1) baza danych (mySQL)
2) warstwa abstrakcji nad bazą danych (ADODB)
3) klasy Modelu (php)
4) Kontroler (php)
5) klasy Widoku (php)
6) szablony Widoku (Smarty)
7) wynik końcowy (HTML)

To daje 7 warstw smile.gif . Dzielić można różnie, ale ważne jest to, że wg. MVC aplikacja powinna mieć 3 główne częśći:

1) Model: logika biznesowa, operacje na źródle danych (np. baza danych), nic nie wie o HTML

2) Widok: logika prezentacji, czyli nie tylko szablony (ale implementacja Widoku za pomocą szablonów jest dobrym pomysłem), wie jak wyciągnąć potrzebne dane z Modelu

3) Kontroler: zbiera to wszystko do kupy, wie że jest żądanie strony i decyduje co należy zrobić żeby wygenerować odpowiedź

MVC pozwala łatwo modyfikować aplikację, np. zmieniać bazę danych, strukturę URLi, wygląd strony, przejść z HTML na PDF, itd. Bo jest podział odpowiedzialności i hermetyzacja.

Cytat
Tak na marginesie chciałem zapytać skąd czerpaliście informacje na temat MVC?

Niektórzy, nie chwaląc się, czerpali m.in. z dokumentacji phienda biggrin.gif , ale poza tym polecam artykuły w php|architect z maja i czerwca 2003. Jakoś trafiłem na promocję i darmowy numer.

Poza tym, jak tylko ruszy portal php.pl, pokaże się na nim mój obszerny artykuł na ten temat. Na razie leży sobie gotowy w DocBooku i czeka, aż będzie gdzie go umieścić.
bumelang
Cytat
Tak na marginesie chciałem zapytać skąd czerpaliście informacje na temat MVC?


Ja prywatnie znam to zagadnienie z Javy, gdzie jest kilka framework'ów MVC - np. Struts albo WebWorks i też kilka książek dotyczących wzorców projektowych. Nie mniej, jeśli nie znasz Javy, to niewiele Ci to pomoże - ale na lekturkę być może warto zawsze się szarpnąć, bo koncepcja jest wspólna.

Cytat
Jak napisal scanner ze jeden z takich MCV[...]

Mylisz trochę pojęcia - MVC to nie jakiś program czy skrypt, tylko strategia pisania interface'u użytkownika. Taką strategię w bardziej rozwiniętych obiektowo językach nazywa się wzorcem projktowym. Ten wzorzec definiuje po prostu, że ma być ten model, view i controller i jak mają ze sobą współpracować. Wybór konktretnego ułatwiacza to nie wybór MVC.

A co do tego, co napisałeś potem, to chyba za bardzo namieszałem z tymi warstwami. MVC nie ma z tym nic wspólnego. Model, widok i kontroler to 3 klasy i tylko tyle. Teraz, jeśli masz aplikację pisaną w architekturze 3-warstowej, to tak wychodzi, że kontroler i widok są w warstwie klienta (prezentacji) a model w warstwie logiki biznesowej. Ale ogólnie mówiąc architektura 3-warstwowa jest niezależna od MVC jako pojęcie.

Działa to tak: użytkownik wysyła żądanie w sensie HTTP, np. wypełnia jakiś formularz i klika "Submit", gdzie akcja formularza jest ustawiona na skrypt, w którym znajduje się kontroler. Ten łączy się z modelem, wywołuje tam jakieś metody biznesowe i gdy te zwrócą mu już efekty swojej pracy, to w zależności od tego, jakie one są, przekazuje to wywołanie do odpowiedniego widoku, czyli odpowiedniej strony php (która może być napisana w Smarty). W php w najprostszym wariancie może być to po prostu
[php:1:a43ca395d1]<?php
/* Kontroler */
if($model->zaloguj($login, $haslo) == SUCCESS) //wywołanie modelu
include("strona_glowna.php"); // wywołanie widoku
else
include("blad.php"); // wywołanie innego widoku
?>[/php:1:a43ca395d1]

Różnica w architekturze pomiędzy MVC a jego brakiem jest taka, że bez MVC logika jest zaszyta w kontrolerze (można powiedzieć, że nie ma warstwy logiki). Nie można jednak traktować Smarty jako kolejnej warstwy, bo to nie o to chodzi.

Natomiast aplikacja może być 2-warstwowa w takim sensie, jak napisałem wtedy, jak nie ma bazy danych, tylko np. coś liczy. Wtedy warstwa danych nie istnieje, nie że łączy się z jakąś inną w jedność.

Mam nadzieję, że nie zaciemniłem za bardzo obrazu tymi warstwami smile.gif
DeyV
jak już trwa taka zaciekła rozmowa na temat MVC, to zauważę, że warto ponownie zainteresować się ciekawym systemem WACT http://www.phppatterns.com/index.php/artic...cleview/85/1/9/
System ten, poza paroma ciekawymi innowacjami, pokazuje również (z tego co zdążyłem się zorientować po paru minutach przegladania) bardzo ciekawy sposób komunikacji pomiędzy modelem a widokiem, któy pozwala na przeniesienie zainicjowania procesu pobrania danych przez view, dopir0o w momencie, gdy te dane będą mu potrzebne.
Chyba nie trzeba nikogo przekonywać, jak często takie rozwiązanie może być bardzo przydatne.
hawk
Hmm, ciekawe...
Z tego co na razie widziałem, WACT ma bardzo fajny system szablonów. Wspominał o tym gdzieś Nalfein (ale o idei, nie o WACT): wyciągać dane z modelu tylko wtedy, kiedy widok naprawdę ich potrzebuje, a nie jak np. w Smarty najpierw wyciągać, a potem zobaczymy czy widok w ogóle z nich skorzysta. To jest wielki plus.

I sam język szablonów jest ładny, taki XML-owy smile.gif . Czyli podobny do Struts w Javie. Albo nie do samego Struts, ale do JSP generalnie. Taka strona wygląda jak JSP i działa mniej więcej jak JSP.

Ale nie widziałem tam jeszcze samego kontrolera :? . Może dlatego że coś mi strona WACT kiepsko działała. Anyway, gdzie tam jest założenie, że mamy jeden główny skrypt (kontroler) i akcje? Gdzie rozdział między akcjami a modelem? W tutorialu widziałem SQL przemieszany z assignami do szablonu.

No ale niedokładnie szukałem, a sam WACT jest pre-alpha. Na razie wydaje mi się, że to jest świetne rozwiązanie widoku, ale nie całego MVC.
scanner
Cytat
Hmm, jako autor phienda potwierdzam że proste to-to nie jest. A moje anty-patriotyczne podejście do lokalizacji manula :oops: niektórym nie ułatwia sprawy. Ale podobno gdzieś tutaj na forum powstaje tłumaczenie.
Jako szef Content Teamu Mogę powiedzieć, że tłumaczenia już jest gotowe, niestety tłumaczka nie miała do dyspozycji edytora XML, zatem ja żmudnie w wolnych chwilach przenosze wszystko z Worda. Dostępne na CVS'ie (dla developerów) jest już 4,5 rozdziału i byłbym wdzięczny hawk, gdybyś na to zerknął. Jutro powinieniem dodać końcówkę 4 i może cały 5 rozdział.
Hawk: w razie uwag, proszę na PW lub maila smile.gif

Dokumentacja phienda po polsku w założeniach ma ukazać się na php.pl.
cagrET
Cytat
Anyway, gdzie tam jest założenie, że mamy jeden główny skrypt (kontroler) i akcje? Gdzie rozdział między akcjami a modelem?

Jeżeli dobrze doczytałem to doszli do wniosku, że kontroler jest zbędny w php. Kod jest mniej elastyczny, trudniej jest go zintegrować z innymi aplikacjiami. Za kontroler uznano sam Apache, a akcjami są pliki .php

czyli struktura aplikacji jest w stylu:

/news/view.php
/news/list.php
/news/edit.php

/forum/viewTopic.php
/forum/viewForum.php

etc
Nalfein][WR
Cytat
Jeżeli dobrze doczytałem to doszli do wniosku, że kontroler jest zbędny w php. Kod jest mniej elastyczny, trudniej jest go zintegrować z innymi aplikacjiami. Za kontroler uznano sam Apache, a akcjami są pliki .php


Wow! A już myślałem, że tylko ja jestem taki crazy, żeby zrywać ze wszystkimi standardami ;P Założenia bardzo fajne, popieram wszystkiema ręcami i nogami.

Ale to ma też minusy, bo nie można dać dwóch urli (np. pl-"electronics" i en-"elektronika") pod jedną akcję, chyba, że będziemy chamsko robili require() przy w drugim pliku. Dlatego robię u siebie akcje tylko wywoływane (wybierane) ze skryptów w "site dir", a implementecje są dalej w "code dir". W ten sposób zyskuję to co chcieli w WACT - eliminuję router (do pewnego etapu - pliki w "site dir" mogą być routerami, bo mogę napisać /forum/viewpost.php/110), ale zachowuję możliwość zmiany URLi bez zmiany nazwy pliku z akcją.
hawk
Minusów jest więcej:
- Co zrobić, jak tego pliku akurat nie ma? Kontroler sobie poradzi, Apache nie.

- Nie każda akcja musi kończyć się wyświetleniem HTMLa - patrz akcje logiki. A tak co? Robić require w tych plikach, i skończyć z taką siecią powiązań?

- Jak będziesz chciał zmienić np. lokalizację WACT, albo jakiekolwiek inne ustawienie globalne, to globalny regexp po wszystkich plikach albo z godzinka roboty...

Jest różnica pomiędzy wywaleniem w ogóle kontrolera, a eliminację routera. Chociaż pojęcie routera jest nasze autorskie i nie występuje w MVC. Hierarcha katalogów jako sposób wybierania akcji do wywołania OK, ale oni idą znacznie dalej.

BTW, trochę zabawne że oni mimo to piszą o MVC. Zrobiliśmy framework oparty o wzorzec Model-View-Controller, ale wywaliliśmy z wzorca cały kontroler laugh.gif . Co nie znaczy że wszystko co dobre musi być MVC. Ale jeżeli ktoś usilnie stara się przedstawić swój projekt jako MVC, to o czymś świadczy...
Nalfein][WR
Nie wywalili kontrolera, ale wywalili obiekt typu FrontController. Akcje logiki to też przecież warstwa kontrolera.
hawk
Ale warstwa kontrolera bez kontrolera? biggrin.gif
To tak jak system bazodanywy bez bazy danych. Albo aplikacja obiektowa bez obiektów.

Zresztą, u nich nie ma akcji logiki.
Nalfein][WR
Chyba za dużo nad Phiendem przesiedziałeś winksmiley.jpg To tak jak rozproszona baza danych (np. pliki XML) czy jak aplikacja obiektowa bez menedżera obiektów. Ja robię to tak np. w pliku /forum/view.php mam:

[php:1:17e5bd469d]
<?php
$app = CodeZone::instance();
$action = $app->create('ViewForumAction', 'actions/forum');
$app->run($action);

// albo $app->execute($request, $response, $action);
// aby realizować testy XP z obiektami FakeRequest oraz FakeResponse
?>
[/php:1:17e5bd469d]

Metoda ::run() klasy aplikacji przekazuje obiekt $action do kontrolera wraz z obiektami $request, $response, które tworzy. Kontroler obsługuje żądanie wypełniając $response, a aplikacja wyrzuca wynik na ekran. Nie wywołujemy tutaj jawnie kontrolera (FrontControllera), przez co możemy w ogóle z niego zrezygnować w prostych aplikacjach, a może za tym wszystkim siedzieć nawet Phiend2.

© Paladine Framework winksmiley.jpg
cagrET
Cytat
- Co zrobić, jak tego pliku akurat nie ma? Kontroler sobie poradzi, Apache nie.

Już raz to gdzieś pisałem
Kod
<IfModule mod_rewrite.c>

    RewriteEngine On

    RewriteCond %{REQUEST_FILENAME} !-f

    RewriteCond %{REQUEST_FILENAME} !-d

    RewriteRule ^(.*)$ error/404.php [L]

</IfModule>


Cytat
- Nie każda akcja musi kończyć się wyświetleniem HTMLa - patrz akcje logiki. A tak co? Robić require w tych plikach, i skończyć z taką siecią powiązań?

Nie rozumiem co miałeś tutaj na myśli. Kto powiedział że każda akcja musi się kończyć wyświetleniem htmla ? Jaka sieć powiązań ? To właśnie użwając FronControllera jest dużo niepotrzebnych includów.

Cytat
- Jak będziesz chciał zmienić np. lokalizację WACT, albo jakiekolwiek inne ustawienie globalne, to globalny regexp po wszystkich plikach albo z godzinka roboty...

Bardziej cenię sobie elastyczność. Ty już jesteś przyklejony na zawsze do tych ustawień globalnych. Ja mam wolną rękę. A gdy potrzebuję globalnych zmian REGEXP jest idealnym narzędziem biggrin.gif

Cytat
BTW, trochę zabawne że oni mimo to piszą o MVC. Zrobiliśmy framework oparty o wzorzec Model-View-Controller, ale wywaliliśmy z wzorca cały kontroler laugh.gif . Co nie znaczy że wszystko co dobre musi być MVC. Ale jeżeli ktoś usilnie stara się przedstawić swój projekt jako MVC, to o czymś świadczy...

Nie zapominaj że php jest językiem skryptowym. Nie widzę sensu kopiować wszystkiego krok w krok z innych języków, bo w php się to po prostu nie sprawdza. O kontrolerze już pisałem że jest, tylko inaczej pojmowanym.
hawk
To w takim razie każda aplikacja w php jest oparta o wzorzec MVC, bo w każdej występuje Apache jako kontroler. Dochodzimy do absurdu.
Sh4dow
Hmm, tak szczerze mowiac, to kazda strona napisana w php, z wykozystaniem, bazy danych, jest juz oparta na modelu MVC.
Jesli dobrze wszystko rozumiem, to kazda strona dziala na takim założeniu. Dziwne by to chyba wygladało jak by szlo to w odwrotnym kierunku.
zeby nie zrobic gafy opieram sie na zend.com. Chyba kazda strona pobiera najpierw dane, pozniej dane sa obrabiane w tak zwanej "business logic" a na koncu sa/"moga byc" wyswietlane.
mam nadzieje ze teraz rozumiem to, jakos prawidlowo. Patrzac na to co wy mowicie, to jedyne czym moga sie roznic "wasze" strony od "moich" (mowie tutaj o sposobie pisania) to jest taka ze wy tworzycie zaawansowane klasy, a ja siedze jeszcze po czesci w procedurach.
Nalfein][WR
Cytat
To w takim razie każda aplikacja w php jest oparta o wzorzec MVC, bo w każdej występuje Apache jako kontroler. Dochodzimy do absurdu.


Jeśli uważasz, że wzorzec FrontController-a = całe MVC to może i tak smile.gif Tylko, że Apachem możemy wskazać jeden obiekt MVC, zależnie co mamy pod urlami - akcję lub widok. Chyba, że w plikach .php wybieramy widok i akcję wypełniającą widok (ViewController jak się zresztą ją określa) - wtedy mamy taki rozproszony kontroler, a Apache robi za router.
KaGe
OK
MVC itd...
Ale jak to wygląda w praktyce? - w momencie, gdy mamy zabrać się za pisanie właściwego projektu - opisać klasy itd...

czy ktoś ma jakiś gotowy wykresik prezentujący np. podział klas na MVC - w miarę dokładny?

Bo z tego co tu się pojawia to ja to widzę jakoś tak:

+KONTROLER © - max nadrzędnie
|- MODEL_a (M) - ściąga dane z bazy i operuje na nich fizycznie
|- MODEL_b (M) - inna klasa operująca na danych - np. danych usera itd..
|- MODEL_c (M) - jeszcze co innego - np. odpowiedzialnego za newsy, artukuły itd...
|- WIDOK (V) - dostaje info z kontrolera - po przetworzeniu odpowiedniego modelu i wyświetla to lub tworzy plik z wynikiem - w każdym bądź razie jest wywoływany na końcu i zajmuje się tylko prezentacją

Czy dobrze rozumuję?
marcin96
http://phppatterns.com/index.php/imagecata...cleview/19/1/1/

...tyle tylko, że w większości frameworków MVC masz jeden obiekt kontrolera, który wywołuje odpowiednie akcje/widoki w odpowiedzi na dane wejściowe. Model łączy się z akcjami/widokami poprzez agregację (czyli tak jak na tamtym diagramie) lub kompozycję (a nie przez dziedziczenie... bo wtedy to już masz model zagnieżdżony w akcjach/widokach.. a tego chcemy uniknąć przeważnie - inaczej to nie jest MVC snitch.gif) ). Czyli jedyne co robisz w widokach/akcjach, to wywołujesz odpowiednie metody odpowiednich modelów. Przynajmniej ja tak to wszystko rozumiem snitch.gif]
KaGe
Diagram widziałem, napisałem sobie nawet własne MVC - dokładnie takie samo, ale dot. czego innego - żeby się nauczyć. - nauczyłem się tego.
Ale:
1) jakbym chciał zrobić usuwanie, doadawanie itd.. - to gdzie dodać odpowiedzialne za to funkcje? - chyba do modelu, ale tam model jest tak zrobiony, że nie odpowiada konkretnemu zbiorowi danych w tabeli a jedynie służy za narzędzie. Więc może do kontrolera? - ok, ale on musiałby przekazać to wszystko do modelu i patrze pkt. wyżej....
2) nigdzie tam nie ma ustalonego id dla OKREŚLONEGO odpowiednika w bazie danych!! - ja wiem, moze nie do konca rozumiem OOP itd.. ale czy to nie jest troche malo uniwersalne, jezeli tylko kontrolerowi podaje id do wyswietlenia i nie moge potem np. zrobic tak:
[php:1:a31b6f25fe]<?php
$a = new ArticleSingleController($dao,$_GET); // gdzie $_GET[id]=2
$a-> // i tu jakos podzialac zeby display wyswietlil np. 3 art.
echo $a->view->Display();

?>[/php:1:a31b6f25fe]
Da sie tak?
marcin96
ad 1) poczytaj dokumentacje phienda snitch.gif)

http://phiend.sourceforge.net/manual/actions.html <- zwlaszcza to pomoże...

W akcjach/widokach wywolujesz jedynie odpowiednie metody modelu. np
[php:1:121515932c]<?php
$ProductModel->DeleteItem($_GET['id']); // to będzie w akcji odpowiedzialnej za usuwanie
$ProductModel->UpdateItem($_GET['id'], $_POST['data']); // a to w akcji odpowiedzialnej za update..
?>[/php:1:121515932c]

Dopiero w modelu trzymamy SQL, czy cokolwiek innego odpowiedzialnego za usuwanie, modyfikacje.. czy zwracanie danych.

ad 2) w tym przykladzie jak zobaczysz na zrodlo ( http://phppatterns.com/index.php/article/a...cleview/19/1/1/ ...bo chyba podałem wczesniej link przypadkiem tylko do samego diagramu..), to kontroler tak naprawde zostal zrealizowany w index.php:
[php:1:121515932c]<?php
switch ( $_GET['view'] ) {
case "product":
$controller=& new ProductItemController($dao,$_GET);
break;
default:
$controller=& new ProductTableController($dao,$_GET);
break;
}
?>[/php:1:121515932c]

Tamten przykład podałem aby pokazać zależność między widokami/akcjami a modelem.. natomiast jak dla mnie realizacja kontrolera jest całkowicie bezsensowna... Naprawdę polecam lekturę Phiend'a. Na stronie projektu ( http://sourceforge.net/project/showfiles.p...?group_id=90219 ) też jest źródło aplikacji, którą masz tutaj:
http://phiend.sourceforge.net/application/
KaGe
1) Czy mam w takim razie do kontrolera, oproocz $model i $view dodać np. obiekt $action , który będzie działał na modelu? czy po prostu do samego modelu dodac odpowiednie metody?

2) A moze po prostu w modelu owszem, dopisac metody usuwania itd... a potem w kontrolerze - odpowiadające im, ale juz przekazujące identyfkatory i dane? - czy tak bedzie dobrze?

3) Jeszcze jedna sprawa: Tak mi sie wydaje, ze jak robie strone w MVC to:
powinien byc 1 kontroler - ktoory by wszystko tworzyl, ustawial, usuwal itd...
modele : odpowiedzialny za baze danych, odpwiednie do newsoow itd.. ,
widoki : prezentacje kazdego z modeli do newsoow itd...

Teraz tak:
czy nie powienien byc jeszcze jeden model i odpowiadajacy mu widok : np. o nazwie SiteModel i SiteView - ktoore odpowiadaly by za cala strone?
i np: SiteView to cos takiego:
[php:1:21abc83259]<?php
Class SiteView
{
var $views;
var $model;
var $output;

function SiteView($model)
{
$this->model = $model;
}

function AddView($view)
{
$this->views[] = $view;
}

function Header()
{
// naglowek <html> itd...
}

function Footer()
{
// /html itd...
}

function Site()
{
foreach($this->views as $n => $view)
{
$this->output .= $view->Display();
}
}

function Display()
{
$this->Header();
$this->Site();
$this->Footer();
return $this->output;
}
}
?>[/php:1:21abc83259]

Czy to jest dobre rozwiązanie?
jak np. chciałbym wyswietlic newsy to tylko bym dal w kontrolerze, ze

[php:1:21abc83259]<?php
$news= new NewsModel;
$newsview = new NewsView($news);

$siteview = new SiteView;
$siteview->AddView($newsview);

// a potem juz tylko:
echo $siteview->Display();

?>[/php:1:21abc83259]
marcin96
Cytat
1) Czy mam w takim razie do kontrolera, oproocz $model i $view dodać np. obiekt $action , który będzie działał na modelu? czy po prostu do samego modelu dodac odpowiednie metody?


Do kontrolera nie dodajesz modelu... to w akcji/widoku sobie tworzysz instancje jednego modelu.. lub więcej, jeśli masz taką potrzebę.

Wprowadziłem tutaj podział na obiekty action i view podobnie jak w phiend - te pierwsze to akcje logiki - odpowiadają za modyfikację danych (tak, operują na modelu, który posiada metody dodajElement, zmieńElement itp), a te drugie to akcje widoku - odpowiadają, za zwracanie danych klientowi - wyświetlanie, przekierowanie do innej strony itp (również operują na modelu, korzystają z metod typu np:zwróćListęProduktów, zwróćProdukt itd). Może przykładowy kod (phiend) ;>]
[php:1:4e23e0d6b9]
<?php

class ActionUpdateProduct extends Action
{

function perform()
{
$data['ID'] = $_GET['ProductID'];
$data['price'] = $_POST['ProductPrice'];
$data['name'] = $_POST['ProductName'];

$product = new Product($_GET['ProductID']);
$product->updateProduct($data);
return 'ViewProduct';
}

}



class ViewProduct extends Action
{

function perform()
{
$product = new Product($_GET['ProductID']);

$data = $product->getAsArray();

// i tutaj wyświetlanie produktu
// [..]

return true;
}

}
?>
[/php:1:4e23e0d6b9]
Cytat
2) A moze po prostu w modelu owszem, dopisac metody usuwania itd... a potem w kontrolerze - odpowiadające im, ale juz przekazujące identyfkatory i dane? - czy tak bedzie dobrze?


Kontroler służy jedynie do wybierania, którą akcję/widok ma 'uruchomić', tworzenia sesji, autoryzacji i sprawdzania, czy dany user ma uprawnienia do odpalenia danej akcji itp, natomiast nie ma nic wspólnego z modelem (yhm... jedynie np: mechanizm autoryzacji musi korzystać z modelu User, ale to już troche inna para kaloszy)

Cytat
3) Jeszcze jedna sprawa: Tak mi sie wydaje, ze jak robie strone w MVC to:
powinien byc 1 kontroler - ktoory by wszystko tworzyl, ustawial, usuwal itd...
modele : odpowiedzialny za baze danych, odpwiednie do newsoow itd.. ,
widoki : prezentacje kazdego z modeli do newsoow itd...


Dokładnie...

Cytat
Teraz tak:
czy nie powienien byc jeszcze jeden model i odpowiadajacy mu widok : np. o nazwie SiteModel i SiteView - ktoore odpowiadaly by za cala strone?
i np: SiteView to cos takiego:
[..]
Czy to jest dobre rozwiązanie?


IMHO nie bardzo... operując na MVC w stylu phiend, to zrobiłbym raczej klasę rodzica, a każdy widok aby dziedziczył po tej klasie:
[php:1:4e23e0d6b9]
<?php
Class SiteView extends Action
{

function Header()
{
// naglowek <html> itd...
}

function Footer()
{
// /html itd...
}

}

Class ViewProduct extends SiteView
{

function Display()
{
$this->header();

// tutaj inicjowanie modelu, zbieranie danych itp
// i następnie ich prezentacja

$this->footer();
}

}
?>[/php:1:4e23e0d6b9]

...albo drugie rozwiązanie (i to może być bardziej elastyczne) - zrobić widoki Header i Footer i wtedy (znowu - phiend)

[php:1:4e23e0d6b9]<?php
Class ViewProduct extends Action
{

function Display()
{
$this->_callAction('header');

// tutaj inicjowanie modelu, zbieranie danych itp
// i następnie ich prezentacja

$this->_callAction('footer');
}

}
?>[/php:1:4e23e0d6b9]
KaGe
Na phppatterns jest schemacik prezentuajcy MVC 2 i do tego jest śliczny kodzik źródłowy.

Mam pytanko w sprawie modelu (ProductModel) z tego kodu:
... a raczej kilka pytań:

1) Dlaczego ten model nie odpowiada pojedynczemu produktowi (wierszowi w tabeli bazy dancyh)?

2) ... można go napisać tak, żeby odpowiadał, ale wtedy możemy się pożegnać z listProducts - czyli wysłaniem żądania o kilka wierszy.... Jak sobie z tym poradzić

3) Czy można napisać taki model (np. articleModel) - który miałby też tablicę modeli np. CommentModel - i dzięki temu jakoś mógły sobie podporządkowywać Komentarze do samego siebie, dodawać usuwać itd...
np tak:
[php:1:7db2f59b24]<?php
Class Comment
{
var $data;
var $dao;

function Comment($dao)
{
$this->dao = $dao;

// Standardowa pusta tablica na dane - czy to doby pomysł?
$this->data[title] = "";
$this->data[body] = "";
}

function GetById($id)
{
$this->dao->query("SELECT * FROM comments WHERE id=".$id);
// i tu pojawia się kwestia : czy dać tu od razu, żeby uzupełnić całą pustą tablicę $data, czy też jakoś inaczej? - jakaś rada?
}

function cośtam?()
{
// i tu by sie przydało coś co wyciąga je po np. articleid
}

function ReturnComment()
{
// i teraz nie wiem czy dać
// return $this->data;
// czy też return $this->dao->GetRow();
// w zależności od rozwiązania, jak dam $this->data to mogę się pożegnać z późniejszym wykorzystaniem while($cośtam = $CommentModel->ReturnComment())
}
}

// i do tego klasa art
Class ArticleModel
{
var $dao;
var $data;
var $comments;

function ArticleModel() // tu wszystko po staremu
{
}

// KWESTIA OPISANA PONIŻEJ:

}

?>[/php:1:7db2f59b24]

Jak zrobić, żeby dało się tak przypisać klasie ArticleModel przynależność kolejnych Komentarzy w bazie, żeby ArticleModel zarówno odpowiadał artukułowi co jest w bazie jak i komentarzom, im przypisanym?

Wie ktoś może jak to rozwiązać?

O widoki nie pytam, bo to już w miare mały problem winksmiley.jpg
marcin96
Cytat
Na phppatterns jest schemacik prezentuajcy MVC 2 i do tego jest śliczny kodzik źródłowy.

Mam pytanko w sprawie modelu (ProductModel) z tego kodu:
... a raczej kilka pytań:

1) Dlaczego ten model nie odpowiada pojedynczemu produktowi (wierszowi w tabeli bazy dancyh)?


Bo to jest tylko prosty przykład? snitch.gif)

Cytat
2) ... można go napisać tak, żeby odpowiadał, ale wtedy możemy się pożegnać z listProducts - czyli wysłaniem żądania o kilka wierszy.... Jak sobie z tym poradzić


Nalfein napisał artykuł o podstawach OOP i tam jest przykład, który myślę pomoże Ci snitch.gif)
http://php.pl/index.php/phppl/artyku_y/apl...zanie_obiektowe
Cytat
3) Czy można napisać taki model (np. articleModel) - który miałby też tablicę modeli np. CommentModel - i dzięki temu jakoś mógły sobie podporządkowywać Komentarze do samego siebie, dodawać usuwać itd...
np tak:
[..]
Jak zrobić, żeby dało się tak przypisać klasie ArticleModel przynależność kolejnych Komentarzy w bazie, żeby ArticleModel zarówno odpowiadał artukułowi co jest w bazie jak i komentarzom, im przypisanym?

Wie ktoś może jak to rozwiązać?


Artykuły nie muszą nic wiedzieć o komentarzach - po co? Jedynie przy usuwaniu artykułu przydałoby się automatyczne usuwanie komentarzy... ale tutaj może się przydać wzorzec observer - zerknij na www.phppatterns.com . Jeśli zaś chodzi o komentarze, to wystarczy znać id artykułu, a klasa Comments już będzie posiadać metodę getCommentsByAID.

Jeśli zaś chodzi o kod, to chyba w artykule Nalfeina znajdziesz odpowiedzi na pytania snitch.gif)
KaGe
Mam problem. Chciałbym zapisywać i dodawać, szukać itd... dane w bazie na tej zasadzie, ze przekazuje nie Id, czy jakis jeden paramentr a cala tablice odpowiadajaca zawartosci danego modelu w bazie. czyli np:

ArticleModel i ArticleDataModel - gdzie ArticleDataModel jest obiektem generującym tablicę zawierającą dane artykułu. Później w ArticleData dodać metodę SaveByData($data), gidze $data to instancja ArticleDataModel i zawiera dane, które mają być zapisane. TAk samo z dodaniem. ArticleDataModel będzie mógł być tworzony bezpośrenio z formularza - co wy na to?
jak to rozwiązać?
hawk
Nie rozumiem :? ArticleDataModel i ArticleModel mają odpowiadać obiektowi Article i kontenerowi artykułów? Sugerowałbym wywalenie tego Model z nazwy klasy, bo ono tam nie pasuje a nikt nie powiedział że klasa należąca do Modelu musi mieć to w swojej nazwie. Nazwa klasy powinna odzwierciedlać jej przeznaczenie i być prosta, jasna i oczywista.
KaGe
Więc w takim razie przedstawie ten problem tak:

[php:1:22b83270b7]<?php
Class ArticleData
{
var $data = array(
art_id => null,
art_title => null
); // i tak dalej z całą resztą

function ArticleData($data=array())
{
foreach($data as $key => $value)
{
if ($data[$key] != "")
{
// tu następuje przepisanie danych z tablicy data - np. z formularza
// do tablicy tej klasy
$this->data[$key] = $data[$key];
}
}
}

function ReturnAsString()
{
$str = array();
foreach($this->data as $key => $value)
{
if (!is_numeric($value))
{
$value = "'$value'";
}
$str[] = "$key=$value";
}
return implode(" AND ", $str);
}
}

Class Article
{
// konstruktor itd...

function GetByData($data)
{
$this->dao->query("SELECT * FROM articles WHERE ".$data->ReturnAsString());
}
}

?>[/php:1:22b83270b7]


I teraz tak:
Article i ArticleData są właściwie wogóle nie związane - ArticleData jest tworzone np. tak, że jako argument podawana jest zawartość fomularza - klasa sama wie co ma sobie wziąć ;. ArticleData będzie tworzona w widokach i przekazywana do modelu Article jako argument dodawania, wyciągania z bazy itd...

Czy to jest dobre rozwiązanie? Może zaproponuje ktoś coś lepszego?
hawk
Hmm, zaczynasz od końca... co nie jest jakąś szczególną krytyką bo to jest raczej powszechne.

Bo przedstawiasz kod, a kod dużo mówi na temat algorytmów i sposobu implementacji, a mało o projekcie i założeniach jakie system miał spełniać.

Po co są klasy Article i ArticleData? Nazwa ArticleData jest myląca, bo nie wiadomo czym to się różni od Article. Piszesz że nie są związane, a potem że ArticleData jest przekazywane do Article jako argument - to jest asocjacja, nawet jeżeli tylko <<uses>>.

Dyskusja na odpowiednio wysokim poziomie abstrakcji jest bardzo trudna i często nie kończy się niczym konkretnym. Ale dyskusja na nie zdefiniowanym poziomie abstrakcji jest jeszcze gorsza.

Jest różnica pomiędzy OOP a OOD, tak jak pomiędzy programowaniem a projektowaniem w ogólności, a wątek w końcu jest o wzorcu projektowym :wink: . Mam nadzieję że nie zamieszałem zbytnio biggrin.gif .
KaGe
"Dyskusja na odpowiednio wysokim poziomie abstrakcji jest bardzo trudna i często nie kończy się niczym konkretnym. Ale dyskusja na nie zdefiniowanym poziomie abstrakcji jest jeszcze gorsza. " - chodzi mi tylko o to, czy takie przekazywanie danych jest wogoole przyjmowane za "poprawne" ? - jeśli jest to ok - będe tak pisał całą stronę, jeśli nie to trudno... - trzeba poszukać lepszego rozwiązania
Balin
Ja mam pytanie o cos innego.
Wiadomo, ze niektore akcje moga zostac wykonane, jesli uzytkownik ma odpowiedni poziom (np. usuwanie newsow tylko przez admina) - jak to dobrze przeprowadzic w aplikacji wzorowanej na mvc ?
Czy sprawdzaniem poziomu uzytkowanika ma zajmowac sie kontroler, czy tez modul artykulow powinien zarzadac wiadomosci o poziomie usera ?
gkeb
Ostatnio troche dumałem nad MVC i w związku z tym mam pytania. Zaznaczam że jestem w tym temacie poczatkujący biggrin.gif

1. Chodzi mi o przeplyw informacji między Kontrolerem Widokiem i Modelem. Zakładam, że każdy z nich to osobna klasa z czego Kontroler jest nadrzędny. Kontroler na podstawie danych z Inputa wywołuje odpowiednie metody z Modelu. Czy Model przekazuje dane zwrotne klasie Kontrolera czy bezpośrenio Widokowi?

2. Czy Model może samodzielnie pobierać dane (np. konfiguracji) z Kontrolera czy też lepiej w trakcie tworzenia klasy Modelu przez Kontroler wysłać wszystkie niezbędne dane potrzebne do pracy (login, hasło do db itp.)?

3. Rozumiem że Widok jest typu Output i nie powinien nic wysyłać do Kontrolera.

Na pewno namieszałem biggrin.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-2024 Invision Power Services, Inc.