Ola,

Ik heb een vraagje... ik heb een class waarin ik de naam van een constante kan ophalen. Nu had ik in 1e instantie een method waarbij telkens 2 controles plaatsvinden, en daar heb ik nu een method van gemaakt met een extra overkoepelende controle. Dit laatste heb ik gedaan om, indien de method meer dan 1x wordt aangeroepen, geen dubbele controles te hoeven uitvoeren. Ik ben benieuwd welke versie jullie beter vinden en waarom. Hieronder even 2 voorbeeldjes van hoe het ongeveer werkt.

Voorbeeld 1:

<?php
class Language {

const DUTCH = 1;

static private $languages_values;

static public function getConstName($value) {
if (!isset(self::$languages_values)) { // controle 1
$ref_class = new \ReflectionClass(self::class);
self::$languages_values = array_flip($ref_class->getConstants());
}
if (!isset(self::$languages_values[$value])) { // controle 2
thow new \Exception('de value bestaat niet!');
}
return self::$languages_values[$value];
}

}
?>
In de opzet hierboven wordt telkens als je getConstName() aanroept eerst gecontroleerd of de property languages_values wel is geset, en daarna wordt gecontroleerd of de value in die array voorkomt.

Nu heb ik er dit van gemaakt:

Voorbeeld 2:

<?php
class Language {

const DUTCH = 1;

static private $languages_values;

static public function getConstName($value) {
if (!isset(self::$languages_values[$value])) { // extra controle
if (!isset(self::$languages_values)) {
$ref_class = new \ReflectionClass(self::class);
self::$languages_values = array_flip($ref_class->getConstants());
}
if (!isset(self::$languages_values[$value])) {
thow new \Exception('de value bestaat niet!');
}
}
return self::$languages_values[$value];
}

}
?>
Ik heb er dus een extra if-statement omheen gezet, die direct al kijkt of de value bestaat. Wat vinden jullie van deze aanpak?
Maar ik wil dus "value objecten" (noem je dat zo?) gebruiken, waardoor ik dus zoiets kan doen:

<?php
$user = new User();
$user->setName('Ger');
$user->setGender(gender::MALE);
$user->setLanguage(language::DUTCH);
?>
Dat kan toch niet anders? Dan heb je toch constanten nodig?

<input type="select" name="language">
<option value="1">Nederlands</option>
<option value="0">Wartaal</option>
</select>

Dus jij gaat eerst je object aanspreken om die value's te presenteren, en daarna ga je nog eens een methode ontwikkelen om de bijbehorende inhoud weer te geven?

In principe ben je als je gegevens binnen een applicatie opslaat hard aan het coderen, en dat kan nooit je bedoeling zijn.
Maar Ger, is dat dat niet gewoon een andere manier van werken? Jij suggereert nu dat wat ik doe fout is. Ik zie echter het probleem (nog?) niet. Misschien kun je me dat dan uitleggen.

Ik vind dit:

$user->setGender(gender::FEMALE);

prettiger lezen en te begrijpen dan

$user->setGender(2);

Wat is daar dan precies verkeerd aan?
Wat jij nu hebt is geen value objecten, in value objecten:
<?php
$user = User::hire('Ger', Gender::parse('male'), new Language('Dutch'));
?>
Hoe noem je de constructie die ik nu gebruik dan?
Laten we de vraag eens andersom stellen.
Wat is voor jouw het voordeel om van een iemands geslacht een object te maken?

En met alle respect voor alle ISO normen men is (of denkt) man of vrouw.

Maar je gebruikt constanten in het algemeen om een bijv. een nummer een bepaalde betekenis te geven, en niet om zomaar een hoop gegevens te genereren die je ergens anders vandaan weer moet gaan ophalen.,
Nou, ISO normen implementeren waar mogelijk lijkt me niet verkeerd. Daarbij is het voordeel dat als je een geslacht opslaat als 2 het minder ruimte in beslag neemt dan wanneer je het opslaat als "female". Net zoals 'de' minder ruimte in beslag neemt dan 'germany'. Die korte values besparen dus ruimte. Dat is toch een goede reden?

Kijken we dan verder... dan vind ik het handiger om te zeggen setColor(color::red) of setLanguage(language::french), dan bijv. setColor(2) en setLanguage('fre') om maar wat te noemen.

Wat is daar dan verkeerd aan? Het is toch gewoon een werkwijze die je zelf prettig vindt?
Als jij het prettig vind om als elke keer dat er een NIEUWE taal aan je website toegevoegd wordt je code aan te gaan passen ...........
Ja, maar gaat het je er nu om of het wel of niet "fijn" is, of doe ik ook daadwerkelijk iets verkeerd? Als die landen bijv. uit een configuratie-bestand zouden komen, is het dan wel oké?
"Maar ik wil dus "value objecten" (noem je dat zo?)"
Nee. En dat voorbeeld heeft absoluut geen value OBJECTEN.
Je hebt geen object dat het mannelijk geslacht of de Nederlandse taal voorsteld.

Je wilt alleen objecten kunnen hebben die een valide waarde vertegenwoordigen.
Je zult de waarde dus moeten valideren aan de hand van bijvoorbeeld
- hardcoded waardes (gebruik dan aub constanten, magic numbers are evil)
- geconfigureerde waardes
- magie (dit is gelukkig onmogelijk)

Op die manier kun je dan een public function setGender(Gender $gender) hebben en weten dat $gender altijd valide is.

Constanten zijn handig om magic numbers (http://en.wikipedia.org/wiki/Magic_number_%28programming%29) te voorkomen. Wat jij nu doet is magic numbers wegwerken door ze als constanten met een beschrijvende naam te defineren. Dit is een goed iets.
Maar via reflection de naam van de constante (die per conventie alleen uit hoofdletters bestaan) op te gaan zoeken i.p.v. een helper method schrijven die op basis van bijvoorbeeld een switch een tekst versie produceert is niet echt mooi.
De tekst versie van een waarde hoort naar mijn idee niet af te hangen van de variabele/constante naam die naar de waarde verwijst.

Ik weet niet of jouw constructie een naam heeft...

Reageren