Kann man generalisierende "Hilfsmethode" bereit stellen die den Code etwas organisieter machen? Ich komme da einfach nicht weiter, wie ich den Code besser organisieren kann 😕. Kann man überhaupt noch etwas dran drehen oder ist das Ende, so ziehmlich erreicht?
Ein paar Ideen:
- Verlagere die Erzeugung des SQL-Strings vom Konstruktor in eine eigene Methode
toSql
. - Verändere bei der String-Erzeugung nicht den iternen Zustand des Objekts. Setze den String lokal zusammen und lass ihn von der Methode zurückgeben.
- Entferne den
$negation
-Parameter und schreibe dir eine eigene KlasseNot
für die Negierung - Schreibe ein Interface
BooleanValue
. Die KlassenBetween
undNot
sollten dieses Interface implementieren.Not
bekommt im Konstruktor ebenfalls ein Objekt vomBooleanValue
übergeben. - Entferne den
$safe
-Operator. Ich würde stattdessen ein InterfaceNumercialValue
schreiben und dan zwei KlassenNumberLiteral
undNumberPlaceholder
, die beide das Interface implementieren.NumberLiteral
konvertiert eine PHP Wert vom Typnumber
in einen SQL-String.NumberPlaceholder
erzeugt einfach ein Fragezeichen. - Entferne die Klasse
ColumnInterface
und schreibe dir eine KlasseNumberColumn
, die ebenfallsNumericalInterface
implementiert.
Du kannst den Code von Between
dann auf das folgende reduzieren:
final class Between implements BooleanValue {
private NumericalValue $value;
private NumericalValue $min;
private NumericalValue $max;
public function __construct(NumericalValue $value, NumericalValue $min, NumericalValue $max)
{
$this->value = $value;
$this->min = $min;
$this->max = $max;
}
public function toSql() : string
{
$value = $this->value->toSql();
$min = $this->min->toSql();
$max = $this->max->toSql();
return " $value BETWEEN $min AND $max ";
}
}
Also nochmal Zusammengefasst, Interfaces:
- NumericalValue
- BooleanValue
Und Klassen:
- NumberLiteral implements NumericalValue
- NumberPlaceholder implements NumericalValue
- NumberColumn implements NumericalValue
- BoolLiteral implements BooleanValue
- BoolPlaceholder implements BooleanValue
- Between implements BooleanValue
- Not implements BooleanValue
Wenn du das für andere MySQL-Datentypen so fortsetzt, erhälst du eine eine Sammmlung vieler sehr primitiver Klassen, die alle mehr oder weniger den Aufbau wie Between
oben haben. Ein Konstruktor, der nur die Felder initialisiert und eine Methode toSql
, die den dazu passenden SQL-String erzeugt. Solche Klassen lassen sich sehr einfach testen, weil sie keinen internen veränderlichen Zustand haben. Außerdem erleichtert eine so fein-granulare Architektur die Verwendung der Library, weil die Typen eine präzise Anleitung dafür liefern, was wie wo verwendet werden darf. Typfehler können auch schon zur Entwicklungszeit angezeigt werden, das erleichtert das Debugging.
Der Nachteil ist natürlich, dass das sehr viel Schreibarbeit ist.