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:
<?php
$this->getAll();
?>
Maar ik zou ook dit kunnen doen:
<?php
$this->get();
?>
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:
<?php
$this->delete('foo'); // verwijdert foo
$this->delete(); // verwijdert alles
?>
Ik ben benieuwd wat jullie vinden.
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.
Dat is dus inderdaad ook waarover ik nu in dubio zit. Van de ene kant is het handig om maar 1 method get() te hebben, omdat ik dan maar 1 method hoef te onthouden :) Maar het is inderdaad de vraag of die ene method dan niet teveel hooi op z'n vork neemt.
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.
De constructor kan bij een active record pattern wel een voorbeeld zijn van een methode die meerdere functies heeft.
<?php
class User
{
public function __construct($id = null)
{
if (isset($id)) {
$this->getById($id);
}
}
private function getById($id)
{
// <...>
}
private function getByName($name)
{
// <...>
}
}
?>
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.
Thanks Ward, goed voorbeeld inderdaad. Maar is dit vergelikjbaar met de situatie zoals ik die schetste?
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().
Lijkt me niet handig als een functie verschillende dingen kan doen afhankelijk van de parameter. In elk geval niet met deze naamgeving.
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.
Een delete() die alle betandden verwijdert zonder parameter, is inderdaad een nogal extreem voorbeeld van hoe het niet moet. Zo'n functie wil je niet schrijven.
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.
Ward, ik zou het ook nog via parameters kunnen doen, bijv.
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?
Laat ik de vraag breder trekken. Wanneer is het slim om functies met min of meer dezelfde functionaliteit op te splitsen in meerdere functies?
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.