Nach über einem Jahr melde ich mich mit einem neuen Eintrag bei euch! Heute möchte ich über Konfigurationsobjekte schreiben. Vor allem auch über die Vorteile gegenüber einfacher Arrays oder überladener Konstruktoren.

Früher war nicht alles besser…

Ich kenne noch diverse alte PHP Skripte, Bibliotheken und Frameworks deren Klassen alle nötigen Informationen direkt im Konstruktor verlangt haben. Das artet nur leider schnell in unlesbarem Code aus.
Wenn die Klasse dann noch diverse Optionale Parameter mitbringt ist das Chaos beinahe perfekt.

Oh übrigens verwende ich in meinen Beispielen keine Namespaces – ihr solltet das in eurem Code allerdings tun 😉

// Code-Beispiel.
$comp = new PeriodicInterval(new DateTime(), 4, 'days');

$comp->getNextInterval();
// ...

Häufig kann man aber auch Konfigurationen einzeln pflegen:

// Code-Beispiel.
$comp = new PeriodicInterval();
$comp->setStartDate(new DateTime());
$comp->setInterval(4, 'days');

$comp->getNextInterval();
// ...

Dies gefällt mir persönlich schon viel besser – unschön ist nur, das man die PeriodicInterval Klasse mit Konfiguration zumüllt (Member Variablen, Getter, Setter, …). Allerdings ist es bei diesen beiden Vorgehensweisen möglich Type Hinting zu nutzen! Yeah!

Konfiguration via Array

Konstruktoren mit Arrays als Parameter sorgen zwar für aufgeräumt wirkenden Code, bringen aber ganz diverse andere Probleme mit sich:

// Code-Beispiel.
$comp = new PeriodicInterval([
   'startDate' => new DateTime(),
   'interval' => [4, 'days']
]);

$comp->getNextInterval();
// ...

Die Probleme fangen bei den Namen der Array-Keys an. Sind diese korrekt geschrieben? CamelCase oder doch mit Binde- oder Unterstrich? Darüber hinaus wird der Code in PeriodicInterval ziemlich aufgeplustert da jetzt sämtliches Type Hinting innerhalb des Konstruktors übernommen werden muss.

Zumindest gibt es die Möglichkeit mit Hilfe von Klassenkonstanten die Array-Keys richtig zu füllen 😉

// Code-Beispiel.
$comp = new PeriodicInterval([
   PeriodicInterval::CONFIG_STARTDATE => new DateTime(),
   PeriodicInterval::CONFIG_INTERVAL => [4, 'days']
]);

$comp->getNextInterval();
// ...

Man kann die Logik natürlich auch in diesem Fall wieder in eine eigene Methode auslagern um den Konstruktor sauber zu halten:

// Code-Beispiel.
$comp = new PeriodicInterval();
$comp->setConfig([
   PeriodicInterval::CONFIG_STARTDATE => new DateTime(),
   PeriodicInterval::CONFIG_INTERVAL => [4, 'days']
]);

$comp->getNextInterval();
// ...

Dieser Code gewinnt allerdings auch keinen Schönheitswettbewerb…

Konfigurationsobjekte

Kommen wir schließlich zum eigentlichen Inhalt dieses Artikels: Konfiguration von Objekten mit Hilfe anderer Objekte. Hierbei haben wir nun wieder die gleichen Optionen wie vorhin (Konfiguration im Konstruktor oder via separaten Methoden übergeben).

// Code-Beispiel.
$config = new PeriodicIntervalConfig();
$config->setStartDate(new DateTime());
$config->setInterval(4, 'days');

$comp = new PeriodicInterval($config);

$comp->getNextInterval();
// ...

Ich persönlich schreibe meinen Code immer etwa so:

// Code-Beispiel.
$config = (new PeriodicIntervalConfig())
   ->setStartDate(new DateTime())
   ->setInterval(4, 'days');

$comp = new PeriodicInterval($config);

$comp->getNextInterval();
// ...

Und was ist nun so großartig daran Objekte zu nutzen anstatt alles direkt im PeriodicInterval zu machen?

  • Saubere Trennung von Konfiguration und Logik! Wie vorhin geschrieben überfrachten wir unsere ursprüngliche Klasse nicht mit Member-Variablen, Klassenkonstanten, Gettern und Settern.
  • Wir können in unserer Komponente nur via Getter auf Konfigurationen zugreifen – wir wissen also immer genau was wir für Typen erhalten (wenn sauber Entwickelt wurde 😉 )
  • Wir können die Konfiguration serialisieren und komplett abgekapselt irgendwo abspeichern (Datenbank / Cache).
  • Es kann sich positiv auf die Testbarkeit auswirken 🙂

Darüber hinaus möchte ich kurz die Vorteile von separaten Gettern und Settern erläutern:

  • Wir können uns auf das Type Hinting von PHP verlassen.
  • Es ist möglich eingegebene Werte validieren.
  • Es ist möglich Werte zu verarbeiten bevor wir diese zurückliefern.
  • Wir können mit Hilfe von PHPDoc die Inhalte und Verwendung dokumentieren.

Validieren von Konfiguration?

Diesen Punkt möchte ich noch kurz ausformulieren, da ich es für sehr wichtig und einen Mehrwert halte. In meinem Beispiel arbeite ich nativ mit DateTime Objekten. Wir können aber weitere Setter anbieten um es dem Entwickler leichter zu machen mit verschiedenen Typen zu arbeiten:

// Code-Beispiel.
$config = new PeriodicIntervalConfig();
$config->setStartDate(new DateTime());

// Weitere Setter, die intern in DateTime umwandeln.
$config->setStartDateAsString('2017-11-18');
$config->setStartDateAsTimestamp(1511006400);

// Lesen der Konfiguration - liefert immer DateTime zurück
$config->getStartDate();

Moment, was ist mit anderen Programmiersprachen?

Natürlich lässt sich dieses Konzept auf beliebige Programmiersprachen anwenden. Also auch in Javascript – jeder von euch kennt bestimmt die üblichen Javascript Komponenten die fast immer ausschließlich via Objekt konfiguriert werden („Objekt“ wie in „assoziatives Array“).

Es dürfte auch hier nichts dagegen sprechen Konfigurationsobjekte zu verwenden 🙂 (Außer vielleicht das private Variablen in Javascript nicht ganz einfach sind)

Vielleicht stelle ich euch ja beim nächsten Mal meine PeriodicInterval Komponente komplett vor… Wann auch immer das sein wird 😉

Bis dahin wünsche ich euch einen angenehmen Tag und wie immer Happy Coding!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.