[MVC] Model Layer uitgelicht
ik heb de voorbije dagen erg veel gelezen over het MVC-pattern, een ORM en het datamapper-pattern.
de VC van het MVC is voor mij nu vrij duidelijk. Ik heb een eigen interpretatie gemaakt die waarschijnlijk nog wel een pak beter kan maar het volstaat voor wat ik nu wil doen.
Dan schiet er nog de model over. Ik heb hier op het forum geleerd dat je de database / storage moet benaderen vanuit een mapper en een Domain object. Dit topic op stackoverflow ging er nog een beetje dieper op in en voegde aan deze twee elementen nog "de model" toe.
De model layer bestaat dus uit:
- Domain object
- Mapper
- Model
- StorageClass
Het domain object is vrij duidelijk, het houd de data vast en controleert of de data aan het juiste type voldoet. Het domain object is niet verantwoordelijk voor de storage van de data.
De mapper is de verbinding tussen het domain object en de storage. In de mapper staat geen SQL, de mapper spreekt enkel de juiste storage classe aan die op zijn beurt de rest van het werk doet.
Model zorgt ervoor dat er geen logica in de controller komt.
Je zou dus kunnen zeggen dat de model en mapper er zo uit zien:
Model
- getAll()
- getTopFive()
- getRow()
- save()
Mapper
- select()
- update()
- delete()
Maar is de mapper en de model eigenlijk niet gewoon hetzelfde en kan je deze niet samenvoegen tot één classe?
Maar achtergrond informatie over mijn manier van denken vind je in deze PDF
Bedankt voor het lezen!
Gewijzigd op 23/01/2013 12:23:07 door Jasper DS
Maar mijn antwoord op de vraag of de mapper en het model niet samen gevoegd zouden kunnen worden is het volgende.
Kan je je een situatie voorstellen waarin je het ene wel wil aanpassen en het andere niet? Zo ja, dan zou ik het gescheiden houden. In dit specifieke geval kan ik me bijvoorbeeld voorstellen dat je voor een applicatie een normale relationele database gebruikt. MySQL, Oracle, MSSQL, DB2, whatever. Volgend jaar echter krijg je de geest en wil je veranderen naar een nosql database. Op zich kan daarmee je hele applicatie gelijk blijven, alleen de manier waarop je de data in de backend verwerkt wordt anders. In mijn ogen blijven de functies zoals je die in het model hebt gedefinieerd dan gelijk, maar de implementatie van de mapper zal anders worden.
Bovenstaand voorbeeld is wellicht niet van toepassing op jou. Probeer dan een situatie voor jezelf te schetsen waarbij je wel de een wilt veranderen en de ander niet. Kan je zo'n situatie werkelijk niet bedenken, dan kan je waarschijnlijk de twee samenvoegen.
P.S. bovenstaande denkwijze geldt natuurlijk niet alleen voor dit deel van een applicatie, maar voor alle onderdelen. Het is in feite mijn grondbeginsel voor het aanmaken van een nieuw object of niet.
Wouter J op 23/01/2013 13:57:22:
Lees eens deze mooie minitut van Niels over models, mappers en meer in het MVC pattern: http://www.phphulp.nl/php/forum/topic/oop-gedachtengang/85017/3/#609065
Ook die reactie heb ik al tientallen keren doorgenomen alle paterns opgezocht etc. Ik vind dat Gateway-pattern wel interessant maar weet nog niet hoe ik dat moet implementeren.
Erwin H:
Ik heb die tut van Niels niet doorgelezen, dus mogelijk dat ik iets dubbels zeg, bij voorbaat excuses dan.
...
...
Hoi Erwin,
ik ben wel van plan om meerder storage types te ondersteunen. Dus dat ik eigenlijk als ik een nieuwe storage toevoeg (Json, Mysql, MSSql) dat ik eigenlijk enkel de storage classe (lees adapter(?)) hoef aan te passen. Maar om dat te bereiken kan ik de mapper en de model nog steeds samenvoegen hé?
Ik dacht dat de regel was dat een mapper enkel Crud methodes kon bevatten ofzo? Indien dat het geval was kon de mapper eigenlijk voor eender welk object gebruikt worden niet?
Quote:
Dus dat ik eigenlijk als ik een nieuwe storage toevoeg (Json, Mysql, MSSql) dat ik eigenlijk enkel de storage classe (lees adapter(?)) hoef aan te passen. Maar om dat te bereiken kan ik de mapper en de model nog steeds samenvoegen hé?
Ja, jij hebt ooit de database abstractie layer nog 1 klasse opgeschoven en in Storage klassen ondergebracht. Erwin plaats die Database Abstractie in de Mapper. Nu wordt bij jou de Model slechts alleen een wrapper die zijn functies naar een directe Mapper equivalent stuurt, wat natuurlijk volstrekt zinloos is.
Quote:
Ik dacht dat de regel was dat een mapper enkel Crud methodes kon bevatten ofzo?
Nee, we hebben (jij hebt) ooit een MapperInterface gemaakt die ervoor zorgt dat we tenminste toegang hebben tot de 4 crud methods. Maar je kan zoveel methods erin doen als je wilt, getById; getByName, ect.
oké mooi, dan denk dat ik in mijn geval de mapper of de model kan schrappen (kwestie van naamgeving). Ik kan de mapper dan alle functies geven die ik denk te gebruiken.
Code (php)
In de controller word de model aangeroepen met de specifieke functies, nooit de mapper.
Lijkt jullie dat oke?
KISS - Keep It Simple Stupid.
Tevens is regel 4 natuurlijk uit den boze, hiervoor moet je dependency injection gebruiken.
Het mag, het lijkt mij alleen een extra laag vol met onnodige moeilijkheid. Een principe dat hier dan vaak genoemd wordt is Tevens is regel 4 natuurlijk uit den boze, hiervoor moet je dependency injection gebruiken.