[oop] wel of niet optionele method?
Even geleden heb ik het met jullie gehad over de invulling van een User class. Nu heb ik daar toch nog een vraag over.
In de praktijk zul je van veel users hun tel.nr. willen weten. Bijvoorbeeld van klanten die iets bestellen, of van de administrators die de website beheren. Aan deze personen is het heel logisch om hun tel.nr. te vragen.
Oké denk ik dan. Als ik aan veel users hun tel.nr. wil vragen dan lijkt het me dus handig om in de User class een set/getPhoneNumber method op te nemen. Toch?
Echter... en daar gaat mijn vraag over... er zijn ook situaties waarin je aan een user niet zijn/haar tel.nr. zal vragen. Bijvoorbeeld aan mensen die zich inschrijven op een forum (zoals bijv. dit forum). Toch heb je dan wel een set/getPhoneNumber method in de User class staan. Is dat een gebruikelijke situatie?
Alvast bedankt voor de reacties.
En zie hier waarom je geen algemene User klasse kan maken.
Ga je dan een extra UserWithPhoneNumber class maken?
Als ik een forum maak zou ik een User object maken zonder telefoonnummer en als ik een webshop maak zou ik een User object maken met telefoonnummer.
In het kader van DRY zou ik niet graag voor ieder project (forum/webshop) een aparte User willen maken. Liever wil ik dan een kant-en-klare User uit de library kunnen halen.
En dan rest dus de keuze... maak je 2 varianten. Dus 1 User zonder tel.nr. en een aparte "ExtendedUser" die de basis User class extend en wel een tel.nr. heeft. Óf, maak je 1 User class met tel.nr. en accepteer je dat je die ene functie niet altijd gebruikt?
Van de ene kant zeg ik, maak 2 classes. Maar van de andere kant twijfel ik of ik niet gewoon 1 complete User class moet maken, waarvan je sommige functionaliteit (in dit geval tel.nr.) niet altijd gebruikt. Wat is wijsheid? Stel dat ik 2 classes zou gebruiken en ik besluit om na een aantal maanden toch om een tel.nr. te gaan vragen, dan moet ik overal de classes gaan aanpassen. Terwijl als ik 1 class gebruik de tel.nr. functionaliteit al direct beschikbaar is. Tja... best lastig...
DRY werkt op project basis, DRY moet je niet willen toepassen op je hele werk. Het meeste van OO maak je zodat je het overal kunt gebruiken, echter zijn er sommige objecten die implementatie specifiek zijn, zie hier met het User object (eigenlijk elke entity) een perfect voorbeeld hiervan!
Onnodige properties in een object hebben vind ik 1 van de vreselijkste dingen die er is :)
Ik snap wat je bedoelt hoor met die onnodige properties. In de praktijk zul je behoorlijk vaak om een tel.nr. vragen. Hartstikke handig als die functionaliteit dan standaard al aanwezig is. Jouw oplossing, die ik dus wel begrijp, zou inhouden dat je de tel.nr. functionaliteit nú achterwege laat, en telkens gaat inbouwen op het moment dat je die nodig hebt. Ik weet niet of dat wel zo zinvol is.
Laat ik een praktijk voorbeeld geven. Onder mijn auto zit een trekhaak. Ik heb het ding nog nooit gebruikt, maar als ik ooit een aanhanger achter mijn auto wil hangen, hoef ik niet gelijk een andere auto te kopen. Daarnaast heb ik ook geen enkele last van het ding. Het zit niet in de weg, en m'n auto gaat er ook niet langzamer van rijden. Ander voorbeeld. In m'n auto zit ook zo'n sigarettenaansteker-oplaad-aansluiting. Ik gebruik het nooit, maar het zit niet in de weg. Correctie... dat is grappig, ik gebruik 'm wel eens! Namelijk als ik m'n TOMTOM erop aansluit. Dat is dus wat ik bedoel te zeggen. Een stukje basis-functionaliteit is denk ik nooit weg. Je hebt het niet altijd nodig, maar op het moment dat je het nodig hebt, is het er wel. Prettig idee toch?
Dus je moet het zo willen maken dat je een vendor directory hebt waar je core inzit van je framework. Vervolgens vul je op basis van elk project de models, controllers en views in. Je gaat immers ook niet al een auto met alle functionaliteit mogelijk inbouwen in de veronderstelling dat er ooit een klant komt die het allemaal wil hebben. Je hebt immers een fabriek waar alle benodigde materiaal beschikbaar is en a.d.h.v. de wensen van die klant bouw je de auto die hij/zij wilt.
Ik ben het voor een groot deel volledig met je eens. Echter, ik heb het op dit moment enkel over de basisfunctionaliteit. Het gaat om basis-dingen waarvan ik weet dat ik ze vrij vaak (vaker wel dan niet) zal nodig hebben. Dan is de keus... bouw je het alvast in. Of laat je het achterwege en ga je het telkens toevoegen op het moment dat je het nodig hebt. Mijn voorkeur gaat dan toch uit naar dat eerste.
Om mijn gedachte een beetje vorm te geven... Als je vrachtwagenbanden onder je auto monteert, en er een vrachtwagenmotor in legt... voor het geval dat, ja... dan sla je de plank wat mij betreft wel mis. Maar als je een aansluiting voor een oplader in een auto maakt... dan zou ik zeggen dat dat juist handig is. Die oplader heb je niet vaak nodig. Misschien maar tussen de 1 en 10% van de tijd dat je in de auto zit. Maar het is toch verdomd handig dat die aansluiting er zit zodat je (bijv.) je TOMTOM kunt aansluiten, en je niet eerst een andere auto moet regelen omdat je anders de TOMTOM niet kan gebruiken.
Want jij bent hier al jaren lang bezig met niet zomaar een auto, maar met een raceauto. Ik weet in ding zeker, daar zit geen oplader in voor het geval de coureur zijn telefoon moet opladen. Daar zit alleen in wat er echt nodig is en dan kan per race verschillen, dus bouw je per race een nieuwe auto (of pas je hem aan).
Toevoeging op 21/04/2014 00:18:19:
Ander code voorbeeld: ik weet zeker dat elke entity die je maakt getId en setId zou hebben. Oei, ik zou hem maar snel in een algemene Entity klasse opnemen... En waarom maak je eigenlijk alleen een base User klasse? Een Page object kan misschien ook reuze handig zijn. En wat dacht je van een PhpForumTopic object, je gebruikt hem bijna nooit maar toch he, als je hem maar in 1% van je applicaties gebruikt zou het toch handiger zijn om die ook alvast op te nemen. Wacht, zei ik daarnet applicatie? Waarom ben ik uberhaupt nog een applicatie aan het schrijven, stel nou dat je 80% van die dingen daar nog een keer wilt gebruiken... Snel opnemen!
Heel veel jaar geleden heb jij iemand uitlegt wat een framework is met, hoe kan het ook anders, een voorbeeld van een auto. Je vertelde dat een framework als het ware de motor levert en de versnellingsbak, maar dat jij dan deze versnellingsbak aan de versnellingspook moet verbinden en de motor ook aan de versnellingsbak. Het framework levert de accu, en jij moet alleen nog even het opladertje aan de accu verbinden. Ik zou zeggen: Blijf lekker bij dit voorbeeld, geef alleen de basis dingen in het framework.
Klopt, maar ik bouw gelukkig geen race-auto, maar een auto voor dagelijks gebruik. En die voorbeeldjes, en de gesprekken met jullie, helpen me wel om uiteindelijk tot een keuze te komen waarbij ik me prettig voel, en nog belangrijker, die ik kan onderbouwen. Soms is die keuze dezelfde als die van jou, en soms ook niet. Maar dat is ook niet erg. Veel belangrijker is dat jij en ik je in onze eigen keuzes kunnen vinden en er voor openstaan.
Zoals Wouter zegt, DRY is per project. Voor ieder project zijn de requirements voor een user klasse anders. Daarom is het ook onmogelijk om een generic user class te maken, dat gaat niet.
Nogmaals, ik zeg ook niet dat ik een generic user class wil maken. Ik heb het over het opnemen van functionaliteit die veelvuldig terugkomt. Dat is wat anders.
Nee, dan maak je alsnog een generic user class. :P
Lol... laten we het er op houden dat ik dan een generiekeRE class maak ;)
Je hebt alsnog geen generieke user class nodig, omdat, zoals ik al zei, de requirements voor elk project qua user anders zijn.
Yup.. maar even een simpel voorbeeld.. iedere user heeft een mailadres. Dat is dan toch al generieke functionaliteit?
waarom zou iedere user een emailadres hebben?
waarom niet? :-s
Ik heb nog nooit een user zonder mailadres gezien.
Nu ben je gewoon koppig en zodanig overtuigt van je eigen idee dat al onze argumenten van geen belang meer zijn.
Ik denk niet dat we je verder kunnen helpen.
Dat schat je dan toch echt verkeerd in.
Kun je mij dan een voorbeeld geven van een gebruiker, dus iemand die op jouw/een website kan inloggen, maar die geen mailadres heeft?
Echt, serieus. Ik heb me nog nooit ergens zonder mailadres kunnen aanmelden. Jij wel?