[oop] abstract vraagje
Ik zat me ineens iets af te vragen. Als je gebruikers/users hebt, dan kun je "simpele" users hebben, en "uitgebreide" users.
Wat ik bedoel is dit. Stel iemand meldt zich via je website aan voor een nieuwsbrief. Het enige dat die persoon invult is zijn naam en e-mailadres. We kunnen dus zeggen dat het om een "simpele" user gaat, waarvan we alleen de naam en het e-mailadres weten. We kunnen ook "uitgebreide" users hebben. Stel je voor, iemand koopt een product via een webshop, dan weten we niet alleen zijn/haar naam en e-mailadres, maar ook woonplaats en adres. En in weer andere situaties weet je misschien ook wel de geboortedatum.
Nu vraag ik me af. Stel dat je een abstracte user class zou maken, waarop alle andere users zijn gebaseerd. Moet je die class dan zo "simpel" mogelijk houden (dus alleen een naam en e-mailadres), of moet je die juist zo "uitgebreid" mogelijk maken, en null returnen indien bepaalde gegevens niet bekend zijn?
Denk dat ikzelf er voor zou kiezen om op database niveau de (het?) user tabel zo uitgebreid mogelijk te maken.
En op het moment dat ik maar enkele velden nodig heb die over laat aan de php kant.
Stel nu dat je een "simpele" user hebt die zich heeft aangemeld voor de nieuwsbrief. Hoe werkt dat dan?
Ik zie 2 scenario's. De default user class is heel beperkt en bevat alleen een getName() en getMail() method. De nieuwsbrief user valt onder deze categorie.
Scenario 2. De default user class is super uitgebreid en je accepteert in het geval van een nieuwsbrief user dat bepaalde methods, bijv. getAddress(), getDayOfBirth e.d. geen resultaat opleveren.
Wat is gebruikelijk?
Ik zou altijd voor scenario 2 gaan, implementatie is stukken makkelijker en ik zie geen nadelen aan 2 tegenover 1, andersom wel.
Zodra je niet normaliseert conform de werkelijkheid, neem je een ontwerpbeslissing die consequenties heeft voor de toekomst.
Verder heeft de inrichting van je User-tabel in de database niet direct te maken met de User-klassen in uiteenlopende webapplicaties. Eén klasse die alles kan, is meestal geen goed idee.
Hoe zou jij zoiets dan doen? Zou jij dan een hele simpele abstracte user class maken met alleen een getName en getMail method?
In algemene zin zou je de vraag ook anders kunnen stellen... moet een abstracte class alleen die functionaliteit bieden die in alle classes aanwezig wordt geacht te zijn? Of moet een class juist zoveel mogelijk functionaliteit bieden, ook al is die functionaliteit voor sommige classes overbodig?
Denis kiest als ik het goed begrijp voor het eerste, terwijl Ward voor het laatste kiest. Kunnen jullie je keuzes nog verder onderbouwen?
User
naam
User_Setting
phone
birth
etc
etc
I.P.V alles in 1 tabel te zetten.
Dit ligt er ook maar net aan hoeveel users jij krijgt met alleen maar naam/email.
Gewijzigd op 23/02/2014 17:20:26 door Dennis Stolmeijer
Weet je toevallig nog een goede tutorial over ORM?
Je hebt trouwens ook PHPActiverecord.. maar daar is wel veel minder support voor http://www.phpactiverecord.org/
Gewijzigd op 23/02/2014 17:37:16 door Dennis Stolmeijer
Maar wil je wél een uitgebreid user-model, doe het dan goed. Mensen hebben meerdere e-mailadressen, meerdere adressen, enzovoort. In dat geval zou ik ook kiezen voor een sterk genormaliseerde database. Aansluitend kunnen dan verschillende applicaties dezelfde data gebruiken met verschillende klassen. En dan dus niet:
één tabel is gelijk aan één klasse.
Ward van der Put op 23/02/2014 17:38:55:
Er is hier geen goed of fout. Als je een site hebt die primair is gericht op het verzamelen van voornaam en e-mailadres van bezoekers, dan kun je het daarbij laten. Ga dan vooral niet ingewikkeld een compleet mens modelleren.
Maar wil je wél een uitgebreid user-model, doe het dan goed. Mensen hebben meerdere e-mailadressen, meerdere adressen, enzovoort. In dat geval zou ik ook kiezen voor een sterk genormaliseerde database. Aansluitend kunnen dan verschillende applicaties dezelfde data gebruiken met verschillende klassen. En dan dus niet:
één tabel is gelijk aan één klasse.
Maar wil je wél een uitgebreid user-model, doe het dan goed. Mensen hebben meerdere e-mailadressen, meerdere adressen, enzovoort. In dat geval zou ik ook kiezen voor een sterk genormaliseerde database. Aansluitend kunnen dan verschillende applicaties dezelfde data gebruiken met verschillende klassen. En dan dus niet:
één tabel is gelijk aan één klasse.
Zou je kunnen uitleggen waarom één tabel is gelijk aan één klasse, geen goede implementatie zou zijn? De hele ORM principe draait hier eigenlijk om.
p.s. met Klasse doel ik op een klasse die fungeert als een Model in het geval van een MVC of MVVM, ie implementatie
Als één gebruiker meerdere e-mailadressen heeft, zijn dat in een goed genormaliseerde database twee tabellen. Toch kun je dan één User-class hebben.
Voor veel-op-veel-relaties wordt de complicatie nog groter. Eén gebruiker kan meerdere adressen hebben. Maar één adres kan omgekeerd ook door meerdere gebruikers worden gebruikt. In een database is dat geen punt: je gebruikt gewoon drie tabellen. In een webapplicatie modelleer je dat echter niet vanzelfsprekend met drie classes. Het kunnen er ook meer of minder zijn.
Ward van der Put op 23/02/2014 18:00:30:
>> Zou je kunnen uitleggen waarom één tabel is gelijk aan één klasse, geen goede implementatie zou zijn? De hele ORM principe draait hier eigenlijk om.
Als één gebruiker meerdere e-mailadressen heeft, zijn dat in een goed genormaliseerde database twee tabellen. Toch kun je dan één User-class hebben.
Voor veel-op-veel-relaties wordt de complicatie nog groter. Eén gebruiker kan meerdere adressen hebben. Maar één adres kan omgekeerd ook door meerdere gebruikers worden gebruikt. In een database is dat geen punt: je gebruikt gewoon drie tabellen. In een webapplicatie modelleer je dat echter niet vanzelfsprekend met drie classes. Het kunnen er ook meer of minder zijn.
Als één gebruiker meerdere e-mailadressen heeft, zijn dat in een goed genormaliseerde database twee tabellen. Toch kun je dan één User-class hebben.
Voor veel-op-veel-relaties wordt de complicatie nog groter. Eén gebruiker kan meerdere adressen hebben. Maar één adres kan omgekeerd ook door meerdere gebruikers worden gebruikt. In een database is dat geen punt: je gebruikt gewoon drie tabellen. In een webapplicatie modelleer je dat echter niet vanzelfsprekend met drie classes. Het kunnen er ook meer of minder zijn.
Eens, ik had het scenario van een veel-op-veel relatie niet meegenomen. Verder delen we wel gewoon dezelfde mening en daar was ik benieuwd naar.
Dennis, merk op dat je jouw denkwijze van een ORM iets moet aanpassen. Het gaat in een ORM namelijk niet om je tabel, maar om je object. Code-first zeg maar. Dus elk object heeft zijn eigen tabel, maar niet perse elke tabel hoeft een object te hebben.
Wouter J op 23/02/2014 18:27:51:
Dus elk object heeft zijn eigen tabel, maar niet perse elke tabel hoeft een object te hebben.
Elk object een eigen databasetabel? En dus voor elk object databasetoegang?
Wouter J op 23/02/2014 18:27:51:
Als 1 User meerdere emailadressen heeft dan heeft de User object een n-n relatie met het Email object.
Dennis, merk op dat je jouw denkwijze van een ORM iets moet aanpassen. Het gaat in een ORM namelijk niet om je tabel, maar om je object. Code-first zeg maar. Dus elk object heeft zijn eigen tabel, maar niet perse elke tabel hoeft een object te hebben.
Dennis, merk op dat je jouw denkwijze van een ORM iets moet aanpassen. Het gaat in een ORM namelijk niet om je tabel, maar om je object. Code-first zeg maar. Dus elk object heeft zijn eigen tabel, maar niet perse elke tabel hoeft een object te hebben.
Bedoel je niet een 1:n relatie? n:n houd in dat hetzelfde een mailadres aan meerdere gebruiker gekoppeld kan zijn, minder gebruikelijk lijkt mij.
Ik deel jou beeld van een ORM implementatie, je hebt gelijk dat mijn uitleg het Code-first idee niet ondersteunde.
@ward
Deze concludering begrijp ik niet helemaal
Gewijzigd op 23/02/2014 18:44:17 door Dennis Stolmeijer
Neem een concreet voorbeeld. Met een class NederlandsePostcode extends Postcode en een class BelgischePostcode extends Postcode heb ik drie klassen die drie typen postcodes kunnen afhandelen. Heb ik daarvoor dan drie databasetabellen nodig? Nee, niet per se. Moet ik postcodes dan opslaan in een aparte tabel? Nee, ook dat niet.
Ward, nee postcode is dan je klasse die in je tabel komt.
Wouter J op 23/02/2014 19:27:27:
Ward, nee postcode is dan je klasse die in je tabel komt.
In welke tabel? ;-)
En hoe verhoudt die postcode zich tot objecten zoals straatnamen, huisnummers, plaatsnamen en landen?
We zijn, opnieuw, automatiseringsproblemen aan het ombuigen naar één model terwijl er meerdere geschikte modellen voor uiteenlopende problemen zijn.
Persoonlijk zou ik 2 tabellen hebben: User en Address. Die verschillende postcode klassen worden dan Value Objects.
Stel we hebben een auto en een fiets. Beiden zijn voertuigen, dus het lijkt me dan zinvol om een abstracte class Voertuig te maken. Mee eens?
Nu is mijn vraag wat er in die abstracte class thuis hoort.
We kunnen stellen dat ieder voertuig kan sturen, remmen en gasgeven. Dus in de voertuig class kunnen we de methods stuurLinks, stuurRechts, rem en gas zetten. Maar... hoort daar bijv. ook een method getNummerbord in? Veel voertuigen hebben een nummerbord, maar een fiets bijvoorbeeld niet. Plaatsen we de getNummerbord method in de voertuig class en accepteren we dat het mogelijk is dat iemand van een fietsobject het nummerbord opvraagt? Of plaatsen we getNummerbord alleen in de auto class?