[oop] best practice, methods met "dubbele" functie?
Is het volgens jullie wel of niet een goed idee om methods te maken die een "dubbele" functie kunnen uitvoeren? Of is dit een kwestie van persoonlijke smaak?
Bijvoorbeeld, stel we slaan in een class de properties van een product op. Via $this->get($id) kunnen we een property ophalen. Stel nu dat ik alle properties tegelijk wil ophalen, dan zou ik dit kunnen doen:
Maar ik zou ook dit kunnen doen:
Merk op dat ik geen ID meegeef. Door geen specifieke ID mee te geven, krijg ik alle IDs terug. Is dit wel of niet een goed idee?
Hetzelfde geldt voor bijvoorbeeld een delete method:
Ik ben benieuwd wat jullie vinden.
Quote:
Lijkt me geen goed idee, in 1 keer alles verwijderd, ook als dit niet de bedoeling was?
Ik zou voor het ophalen/verwijderen van alles andere namen gebruiken dan voor het ophalen data/verwijderen van 1 object.
persoonlijk zou ik gaan voor:
Code (php)
Gewijzigd op 24/11/2013 01:42:15 door Local Dev
Dankjewel voor je reactie. En geldt dat alleen voor een delete functie? Of ook voor bijv. een get/getAll functie?
Geld voor beide, wanneer je een bepaalde functie aanroept, verwacht je naar mijn mening een bepaald resultaat, een object, string, of een array, maar naar mijn mening moet je wel de controle behouden over wat de functie returned, in jouw case kan je voor onverwachte resultaten komen te staan.
Ik zie dat je je bericht nog had ge-edit. Ik gebruik zelf niet getById($id), maar get($id). Ik haal normaal gesproken alles op, op basis van een ID, dus dat hoef ik dan niet specifiek in de methodnaam te laten terugkomen. Alleen wanneer er meerdere mogelijkheden zijn om iets op te halen, pas dan zou ik voor zo'n uitbreiding kiezen. Bijv. een user class met getById en getByName. En als ik alles wil getten dan zou ik niet fetchAll zetten (tenzij bij een database) maar gewoon getAll.
Code (php)
Nu kun je met new User(1234) de record van een bestaande gebruiker bewerken en met new User() zonder ID vrij letterlijk knutselen een nieuwe gebruiker.
Dus ja, met andere parameters biedt een methode soms andere functionaliteit. Daarvoor zijn parameters immers bedoeld.
Gewijzigd op 24/11/2013 13:50:42 door Ward van der Put
In jouw voorbeeld geef je een variabele mee aan de constructor en wordt een bepaalde handeling verricht. Geef je geen variabele mee, dan wordt die handeling niet verricht.
In mijn voorbeeld wordt als je een bepaalde variabele meegeeft aan een method een bepaalde handeling verricht, terwijl als je geen variabele meegeeft een andere handeling wordt verricht. Dus de situatie ligt net ietsje anders.
Wat ik nu doe is:
$delete('foo') // verwijder foo
$delete() // geen ID ingegeven, dus verwijder alles
of
$get('foo') // haal foo op
$get() // geen ID ingegeven, dus haal alles op
Mijn vraag is of dit slim is, of dat ik beter gebruik kan maken van deleteAll() en getAll().
Reacties zijn welkom.
Want als je dus een typo maakt en die komt door de validatie dan delete je stiekem even alles. Zelfde met de get, op eens krijg je een (waarschijnlijk) array (of een arraycollection object) terug i.p.v het object wat je bedoelde.
Zou de code ook zo schrijven dat mocht er iemand anders ooit mee moet werken de persoon niet voor 'grapjes' komt te staan als een lege tabel opeens.
Maar meer in het algemeen: parameters in een methode/functie bepalen niet alleen een operand, maar ook de operaties. Kijk bijvoorbeeld maar eens naar iets eenvoudigs maar onmisbaars zoals afronden. Hier hebben we één operand en twee operatoren, waarbij de tweede operator ook nog een constante is:
float round ( float $val [, int $precision = 0 [, int $mode = PHP_ROUND_HALF_UP ]] )
Een minder extreem voorbeeld dan een delete(), maar wel met hetzelfde effect: met $precision kun je even effectief data naar de eeuwige jachtvelden dirigeren.
function delete($id, $all = false);
En als je dan $all op true zet, dat ie dan alles verwijdert. De vraag is eigenlijk waar je de grens moet trekken. Moet je 1 delete functie hebben die alles kan verwijderen, van 1 enkele ID tot alle IDs. Of moet je dit onderbrengen in 2 functies delete() en deletAll(). Hetzelfde geldt dan ook voor get() en getAll(). Laat ik de vraag breder trekken. Wanneer is het slim om functies met min of meer dezelfde functionaliteit op te splitsen in meerdere functies?
Ozzie PHP op 24/11/2013 16:04:54:
Eigenlijk heel eenvoudig: zodra je iets gaat/kunt kopiëren en plakken, heb je duplicaten die hetzelfde doen. Dan kun je beter een gedeelde methode gebruiken. Het is heel gebruikelijk (en vaak beter zelfs) dat methoden andere methoden gebruiken.Laat ik de vraag breder trekken. Wanneer is het slim om functies met min of meer dezelfde functionaliteit op te splitsen in meerdere functies?
Code (php)
De tegenhanger met 1 functie zou dan zoiets zijn:
Code (php)
Maar wat is nu de beste oplossing? Zeg je, het gaat in beide gevallen om het verwijderen van data, dus we gebruiken 1 functie (het 2e voorbeeld). Of zeg je, nee het gaat hier weliswaar om het verwijderen van data, maar er zit een verschil tussen het verwijderen van 1 element of in 1x alle data en daarom gebruik je 2 functies (voorbeeld 1). Hoe weet je nu wat de juiste (of betere) manier is? Allebei de manieren zullen werken, maar in 1 van beide manieren handiger/praktischer in gebruik?
Hangt ervan af, zoals vaker. Net verwijderde delete() nog alle bestanden, nu slechts een array.
Bijv. jQuery werkt heel erg veel met andere functionaliteiten in dezelfde functie doormiddel van argumenten. Bijv. $('#a').attr('id') verkrijgt de waarde van het id attribuut terwilj $('#a').attr('id', 'f') het attribuut id een waarde meegeeft.
Het is even een code voorbeeldje om te laten zien dat ik geen dubbele code gebruik en het volgens jouw theorie dus 2 functies mogen zijn. Het kan gaan om een array of om bestanden, maar maakt dat iets uit? Het gaat vooral om de gedachte die erachter zit. Moet je alles wat maar enigszins met het verwijderproces te maken heeft in 1 functie stoppen, of verspreid je dit over meerdere functies.
@Wouter:
Oké, thanks. Er is dus geen goed of fout. Wat vind jij zelf handiger? Eén delete functie die zowel één ID (array-key, bestand, database-row of wat dan ook) kan verwijderen als alle IDs (op het moment dat je geen ID meegeeft). Of vind jij het persoonlijk beter om 2 functies te gebruiken, een delete() en deleteAll()?
Offtopic:
Ik zie dat jij vergelijkt met null via null === $name. Waarom gebruik je niet de is_null() functie?
Ozzie PHP op 24/11/2013 16:43:16:
Oké, thanks. Er is dus geen goed of fout. Wat vind jij zelf handiger? Eén delete functie die zowel één ID (array-key, bestand, database-row of wat dan ook) kan verwijderen als alle IDs (op het moment dat je geen ID meegeeft). Of vind jij het persoonlijk beter om 2 functies te gebruiken, een delete() en deleteAll()?
Ik stem voor twee methods voor zulke use cases.
Getters & setters wil ik nog wel eens combineren:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
public function hash($hash = null)
{
switch(func_num_args())
{
case 0:
return $this->hash;
default:
$this->hash = (string) $hash;
return $this;
}
}
?>
public function hash($hash = null)
{
switch(func_num_args())
{
case 0:
return $this->hash;
default:
$this->hash = (string) $hash;
return $this;
}
}
?>
Quote:
k zie dat jij vergelijkt met null via null === $name. Waarom gebruik je niet de is_null() functie?
Eerste comment op http://us1.php.net/is_null geeft aan dat het veel sneller is met het zelfde resultaat.
Gewijzigd op 24/11/2013 19:51:51 door Dos Moonen
Ah oké thanks. Ik zal straks eens even benchmarken dan!