konto usunięte

Temat: Budowa Frameworków

Marcin Olichwirowicz:
Przemysław R.:
Michał Jarosz:
Zrobić model reprezentujący uprawnienia :P

a jak mam kontroler bez modelu?

Modele nie są de facto powiązane z controllerami. One są luźnymi obiektami, dostarczającymi metody które wykonują jakieś operacje na bazie danych.

właśnie
więc jak zgrabnie i rozsądnie korzystać z bazy danych w modelach jaki jakiś helperach? de fakto obie grupy obiektów są od siebie odseparowane

konto usunięte

Temat: Budowa Frameworków

Przemysław R.:
Marcin Olichwirowicz:
Przemysław R.:
Michał Jarosz:
Zrobić model reprezentujący uprawnienia :P

a jak mam kontroler bez modelu?

Modele nie są de facto powiązane z controllerami. One są luźnymi obiektami, dostarczającymi metody które wykonują jakieś operacje na bazie danych.

właśnie
więc jak zgrabnie i rozsądnie korzystać z bazy danych w modelach jaki jakiś helperach? de fakto obie grupy obiektów są od siebie odseparowane

Ja osobiście stosuję taką praktykę, że grupuję podobne operacje na bazie w modele. Np. ModelUser, zawiera operacje związane z użytkownikiem, itp.

ORMy takie jak Doctrine znowu pozwalają na automatyczne wygenerowanie modeli z bazy danych. I np. taki model User nie dość, że mapuje się na twoją tabele o nazwie `user`, może reprezentować jej pojedynczy record i dostarczać wielu metod ORMowych, to jeszcze samemu można taki model uzupełniać o własne metody (Doctrine serwuje pustą klasę, odpowiednio zadziedziczoną).

Temat: Budowa Frameworków

Przemysław R.:
w jaki sposób elegancko rozwiązać sytuację w której dostęp do bazy danych mam w klasie modelu, ale czasem chciał bym odpytać bazę np przy sprawdzaniu uprawnień albo podobnym zadaniu zupełnie nie związanym z modelem?

klasa DB powinna byc wydzielona z modelu biznesowego, to czesc aplikacji i w zaleznosci od rodzaju bazy powinna ladowac odpowiedni "driver" np dla mysqli itp itd

klasa ta w moim mvc jest singleton'em ktorego instance mozesz wyciagac w dowolnym miejscu systemu i niezaleznie czy jest juz zainicjowany czy tez nie, pierwsze wywolanie utworzy obiekt, kazde nastepne skorzysta z istniejacej instancji

np w modelu mozesz miec tylko:

$this->DB = Application_Drivers_DB::getInstance();


ta jedna linijke umieszczasz w kazdym odelu w ktorym siegasz do DB, wiele frameworkow tworzy taki obiekt "globalnie" rejestrujac go w registry co prowadzi do komicznych sytuacji istnienia obiektu DB nawet wtedy gdy go nie potrzebujesz - jednym slowem, planuj madrze i uruchamiaj minimum potrzebne do wykonania skryptu w danym kontrolerze i w danej akcji
Wojciech Soczyński

Wojciech Soczyński Programista
eksplorator -
blog.wsoczynski.pl

Temat: Budowa Frameworków

Modele są zupełnie niezależne od kontrolerów i od widoku. Odpowiadają za logikę biznesową (również enkapsulują "wyciąganie z bazy"). Kontroler na podstawie danych z requestu, wyciąga odpowiednie rzeczy z modelu i przekazuje do widoku gdzie są wyświetlane.

To jest taki ogólny schemat od którego są różne wariacje. Należy pamiętać, że warstwa modelu nie odpowiada tylko za komunikacje z bazą, co więcej to nie należy w ogóle do jej obowiązków.

Komunikacja z bazą odbywa się w warstwie infrastruktury, która zajmuje się wszystkimi technicznymi rzeczami związanymi np z bazą danych czy czytaniem konfiguracji.

Model jest abstrakcyjnym bytem, który obrazuje rzeczywiste pojęcie w świecie realnym. Czyli tak jak MOli napisał ModelUser - jest abstrakcją rzeczywistego użytkownika.
Artur Świerc

Artur Świerc Programista PHP/Java

Temat: Budowa Frameworków

tak, tylko w phpie przyjęło się, że model == db - błędne założenie.
Alan Gabriel B.

Alan Gabriel B. Software Engineer,
IFX

Temat: Budowa Frameworków

Widziałem tam pewne (słuszne) wątpliwości co do rejestru - może to i to pomoże.
Wojciech Soczyński

Wojciech Soczyński Programista
eksplorator -
blog.wsoczynski.pl

Temat: Budowa Frameworków

Tak czy inaczej wszystko zależy od tego jaką aplikację budujemy. Nie należy używać koparki do sadzenia kwiatków w ogrodzie.

Przy małej aplikacji, ale na tyle dużej by robić ją we wzorcu mvc, można sobie mapować tabele z bazy danych 1:1 z klasą modelu.

Czym większa jest aplikacja, tym bardziej warstwa modelu będzie miała więcej klas. Pojawią się np. różne klasy typu 'SERVICE', które będą abstrahować funkcjonalności końcowe dla klienta, konkretne usługi które ma świadczyć nasza aplikacja. Polecam poczytać o Domain Driven Design.

Tak samo, rejestr moim zdaniem się sprawdza w niezbyt dużych aplikacjach gdzie nie mamy wielu powiązań między klasami. Natomiast przy większych rozwiązaniach polecałbym zastosowanie wzorca Dependency Injection (wstrzykiwanie zależności) lub Inversion of control - realizacje DI z użyciem kontenera który konfiguruje dla nas obiekty.

Generalnie tak naprawdę nie ma czegoś takiego jeden złoty sposób jak coś zrobić, wszystko jest zależne od tego jaki cel chcemy osiągnąć i w jakim kontekscie. Podejście, które sprawdzi sie dobrze w jakiejś sytuacji niekoniecznie będzie dobre w innej.

Z technik uniwersalnych jakie mogę polecić to stosowanie interfejsów. Interfejsów, które nie definiują nam klasy a bardziej funkcjonalności które dana klasa ma realizować. Dzięki temu nasz kod będzie mógł być zaimplementowany na wiele różnych sposób. Ułatwia to też refaktoring.

Uff ale się napisałem ;P
Artur Świerc

Artur Świerc Programista PHP/Java

Temat: Budowa Frameworków

Wojtku IoC to chyba nie w phpie. Chociaż kiedyś czytałem o jakiś libach dla Symfony, nie wiem czy się sprawdziło, bo piszę głównie w ZF - tutaj twórcy chyba jeszcze o tym nie myślą. Wielka szkoda, patrząc jaką furorę robi IoC w Springu czy JSF - cały config np w xmlu i mamy na tacy wszystkie powiązania.

Registry czy context się zawsze przydaje, nawet w dużych aplikacjach. Byle nie pchać tam wszystkiego, robi się śmietnik jak z niegdyś z globalami.

Dobrze piszesz o mapowaniu - wg mnie sprawdza się w aplikacjach dobrze zaprojektowanych, w których wiemy, że będziemy stosowali zasadę "zrobić, zgarnąć kasę i zapomnieć". Co innego, gdy cały czas dochodzą nowe featury, a nasza baza która powinna być sztywna jest strasznie dynamiczna.
Alan Gabriel B.

Alan Gabriel B. Software Engineer,
IFX

Temat: Budowa Frameworków

Wojciech Soczyński:
[...] zastosowanie wzorca Dependency Injection (wstrzykiwanie zależności) lub Inversion of control - realizacje DI z użyciem kontenera który konfiguruje dla nas obiekty.

To nie do końca jest tak jak napisałeś.
Inversion of Control jest zasadą wg której system powinien być zdecentralizowany i dążyć do decouple'ingu obiektów (w granicach zdrowego rozsądku). Dependency Injection natomiast jest jednym ze sposobów w którym można osiągnąć IoC tj. jednym z zastosowań IoC.
Na IoC - prócz samego DI - składają się m.in. Eventy (szczególnie widać to w Javie, gdzie są one wbudowane natywnie) i (niedostępne w PHP) Aspekty.

Pomyliłeś też samo IoC z Kontenerem IoC. IoC != Kontener IoC.

Kontener IoC to coś w rodzaju fabryki obiektów w której konfigurujesz budowanie obiektów (programowanie deklaratywne), zamiast pisania tego z palca (programowanie imperatywne).
Alan Gabriel B.

Alan Gabriel B. Software Engineer,
IFX

Temat: Budowa Frameworków

Artur Świerc:
Registry czy context się zawsze przydaje, nawet w dużych aplikacjach. Byle nie pchać tam wszystkiego, robi się śmietnik jak z niegdyś z globalami.

O ile system nie korzysta z samych singletonów - o czym w przedszkolu uczą, że się robić nie powinno - to zawsze znajdzie się w nim odpowiednik któregoś z tych dwojga.

Symfony posiada komponent do konfigurowania DI, ale tak naprawdę to jest zamiennik kontekstu.
Alan Gabriel B.

Alan Gabriel B. Software Engineer,
IFX

Temat: Budowa Frameworków

Artur Świerc:
tak, tylko w phpie przyjęło się, że model == db - błędne założenie.

Bierze się to stąd, że dotychczas PHP nie posiadało bibliotek, które by ten błąd developerom wytykały - tak jak to robi Hibernate w Javie :)
Na szczęście powstaje Doctrine 2.

Wywiązała się dyskusja o ORM 1:1 vs Modele dziedzinowe. Każde z tych podejść ma swoje zalety i wady.

Database-Driven Development (1:1) oferuje bardzo szybką developerkę, to jest praktycznie prototypowanie, lecz przypłaca niezbyt wysoką elastycznością. Migracja bazy danych może przysporzyć wiele bólu głowy.

Projektowanie dziedzinowe, czyli Domain-Driven Design, to zupełnie inna - wyższa - klasa w podejściu do tworzenia oprogramowania. Kod powstaje dosyć mozolnie i trzeba znacznie więcej czasu poświęcić, aby zobaczyć pierwsze efekty pracy. Za to powstały kod jest super-elastyczny.
Przy dobrym projekcie z właściwym podziałem warstw (z grubsza są to warstwa infrastruktury <- warstwa dziedziny <- warstwa aplikacji) i programowaniem na interfejsach (design by contract) można dowolnie podmieniać źródła danych (np. z bazy relacyjnej na dokumentową), biblioteki (np. do wysyłania maili), czy nawet całe frameworki.
W dodatku za DDD podąża cała wataha pojęć:
-Encje
-ValueObjects
-Repozytoria
-Fabryki
-Serwisy
-Agregaty
-Polityki vel Strategie

Jeżeli ktoś będzie zainteresowany tematem to polecam:
Evans Eric, "Domain-Driven Design: Tackling Complexity in the Heart of Software"
Fowler Martin i in., "Patterns of Enterprise Application Architecture"
McCarthy Tim, ".NET Domain-Driven Design with C#"
Nilsson Jimmy, "Applying Domain-Driven Design and Patterns"
Wojciech Soczyński

Wojciech Soczyński Programista
eksplorator -
blog.wsoczynski.pl

Temat: Budowa Frameworków

Alan niekoniecznie trzeba mozolnie tworzyć. To zależy jakie się weźmie podejście, kod można tak pisać, żeby naturalnie ewoluował w stronę Domain Driven Design.

Poza tym ORM nie kłóci się wcale z modelami dziedzinowymi, bo ORM jest tylko warstwą infrastruktury do utrwalania ich. Oczywiście jest różnica gdy mamy ORM, który korzysta z Active Record a ORM jako Data Mapper.

Co do kontenera IoC to sam taki napisałem i dobrze daje radę. Niedługo go gdzieś opublikuje ;)
Rafał Toboła

Rafał Toboła Razor s.c. -
współwłaściciel

Temat: Budowa Frameworków

http://www.phppatterns.com/docs/?idx=design - beznadziejna grafika, ale warto zajrzeć. Szczególnie ciekawe jest: http://www.phppatterns.com/docs/design/hello_world_in_... :-).
Alan Gabriel B.

Alan Gabriel B. Software Engineer,
IFX

Temat: Budowa Frameworków

Wojciech Soczyński:
Alan niekoniecznie trzeba mozolnie tworzyć. To zależy jakie się weźmie podejście, kod można tak pisać, żeby naturalnie ewoluował w stronę Domain Driven Design.

Możesz wyjaśnić? Bo z mojego doświadczenia wynika, że jak się projektu w DDD nie zacznie "jak bozia nakazała", czyli np. używając Propela/Doctrine, to potem nie ma mowy o ewolucji.

A mozolność wynika z faktu, że do niedawna tworząc Encje/VO (których mogło być bardzo dużo) musiałem repozytoria pisać z palca. To zabiera mnóstwo czasu.
W dodatku, brakuje w PHP fajnych samodzielnych bibliotek do walidacji i tym też musiałem się zając sam.
Alan Gabriel B.

Alan Gabriel B. Software Engineer,
IFX

Temat: Budowa Frameworków

Wojciech Soczyński:
Co do kontenera IoC to sam taki napisałem i dobrze daje radę. Niedługo go gdzieś opublikuje ;)

Daj znać :)
Wojciech Soczyński

Wojciech Soczyński Programista
eksplorator -
blog.wsoczynski.pl

Temat: Budowa Frameworków

To jak ewoluować projekt to jest w zasadzie temat na osobny artykuł. Tak z grubsza mówiąc, wystarczy na początku zdefiniować kilka interfejsów do których się będzie dążyć (Repository, Entity etc).

Później tworzymy klasę domenową np. User, która będzie implementować je wszystkie. Wraz z rozrostem kodu będziemy refaktorować tą klasę i przenosić funkcjonalności do docelowych klas...

A co do walidacji, to w przypadku logiki biznesowej i tak trzeba ją zawsze zrobić ręcznie, do prostej walidacji wystarczy Zend_Validate.Wojciech Soczyński edytował(a) ten post dnia 24.05.10 o godzinie 15:42
Alan Gabriel B.

Alan Gabriel B. Software Engineer,
IFX

Temat: Budowa Frameworków

Wojciech Soczyński:
Później tworzymy klasę domenową np. User, która będzie implementować je wszystkie. Wraz z rozrostem kodu będziemy refaktorować tą klasę i przenosić funkcjonalności do docelowych klas...

User który implementuje te przykładowe Entity i Repository jednocześnie? To już nie lepiej od razu to rozdzielić - to tak jakbyś napisał, że robisz burdel, żeby było co sprzątać :]

Nie przekonasz mnie, system który nie był pisany od początku jako DDD później wymaga niemal całkowitego przepisania, by te wymaganie spełnić.
Takie jest moje zdanie i rozumiem, że możesz się z Nim nie zgadzać.
A co do walidacji, to w przypadku logiki biznesowej i tak trzeba ją zawsze zrobić ręcznie, do prostej walidacji wystarczy Zend_Validate.

Nie lubię tej biblioteki to już wolę ekstrahować walidatory iValidationSchema z Symfony.Alan Gabriel B. edytował(a) ten post dnia 24.05.10 o godzinie 16:02
Wojciech Soczyński

Wojciech Soczyński Programista
eksplorator -
blog.wsoczynski.pl

Temat: Budowa Frameworków

Nie o to chodzi, żeby robić burdel i go sprzątać później. Chodzi o to, że
a) powinno się kodować pod interfejs
b) w żyjącym systemie ciągły refaktoring jest nieunikniony

Ja mam takie podejście, że nie tworzę nadmiarowych klas kiedy nie mam czego w nich umieścić. Oczywiście, jeżeli mamy już zarysowany kształt systemu i wiemy co w nim będzie oraz mamy dokładną specyfikację to nie ma się co powstrzymywać i trzeba zaprojektować i zaimplementować i już.

Natomiast często jest tak, że klient który nam coś zleca tak naprawdę nie wie czego chce. Coś co miało być prostym CMS-em zmienia się nagle w sklep internetowych i portal społecznościowy. W tym przypadku podejście ewolucyjne jest lepsze, ponieważ nie kodujemy nadmiarowego kodu, natomiast zostawiamy sobie pole do jego rozwijania.

Jeżeli chodzi o Zend_Validate to moim zdaniem, jest to jedna z lepszych bibliotek Zendowych. Fajnie by było gdybyś mógł wskazać w czym walidatory z Symfony przewyższają te Zendowe na konkretnych przykładach...
Alan Gabriel B.

Alan Gabriel B. Software Engineer,
IFX

Temat: Budowa Frameworków

Wojtku, przecież zaczęliśmy od różnic między projektowaniem datacentrycznym a dziedzinowym i ja się pytałem jak chcesz skończyć projekt - zaczęty pod np. Propelem - jako projekt DDD bez przepisywania większej części kodu bazowego (podkreślam: przepisywania, a nie refaktoryzacji). Interfejsy tu nie pomogą niestety.

Natomiast często jest tak, że klient który nam coś zleca tak naprawdę nie wie czego chce. Coś co miało być prostym CMS-em zmienia się nagle w sklep internetowych i portal społecznościowy. W tym przypadku podejście ewolucyjne jest lepsze, ponieważ nie kodujemy nadmiarowego kodu, natomiast zostawiamy sobie pole do jego rozwijania.

Cóż, to jest nieodłączna część cyklu życia każdego projektu.
Wojciech Soczyński

Wojciech Soczyński Programista
eksplorator -
blog.wsoczynski.pl

Temat: Budowa Frameworków

Widocznie nie wyczułem intencji twojej wypowiedzi. Jeżeli chodzi o dokończenie projektu zaczętego z propelem a kończeniem go w DDD to myślę, że najlepiej sprawdzi się tu stara mantra: "każdy problem w informatyce można rozwiązać dodając kolejna warstwę abstrakcji" ;).

Zresztą podejście Active Recordowe nie różni się aż tak bardzo od podejścia Data Mapper + DDD. W zasadzie główna różnica jest taka, że przy Data Maperze obiekty są utrwalane, a w Active Record utrwalają się same.

Można by sprowadzić propela do roli infrastruktury a całą logikę wyekstrahować do klas usługowych i encji.Wojciech Soczyński edytował(a) ten post dnia 24.05.10 o godzinie 21:46

Następna dyskusja:

budowa portalu aukcyjnego




Wyślij zaproszenie do