Hintergrund
Ich lese das "Clean Code Book" und arbeite parallel dazu an Calisthenic-Objekten wie dem Bankkonto, und ich halte mich an diese Regel:
Die 9. Regel von Calisthenic-Objekten ist, dass wir keine Getter oder Setter verwenden.
Es scheint ziemlich lustig zu sein und ich stimme diesem Prinzip zu. Darüber hinaus erklärt der Autor auf Seite 98-99 von Clean Code, dass Getter / Setter die Abstraktion brechen und dass wir unser Objekt nicht fragen müssen, sondern unser Objekt mitteilen müssen.
Das macht für mich vollkommen Sinn und ich stimme diesem Prinzip voll und ganz zu. Das Problem kommt in der Praxis.
Kontext
Zum Beispiel habe ich eine Anwendung, in der ich einige Benutzer auflisten und die Benutzerdetails anzeigen muss.
Mein Benutzer besteht aus:
-> Name
--> Firstname --> String
--> Lastname --> String
-> PostalAddress
--> Street --> String
--> PostalCode --> String
Problem
Wie kann ich vorgehen oder was kann ich tun, um Fehler zu vermeiden, wenn ich nur einfache Informationen anzeigen muss ( und bestätigen muss, dass ich für dieses bestimmte Feld keine zusätzliche Operation benötige ), um den Wert für den Vornamen in einem einfachen ( zufällige) Ausgabeunterstützung?
Was fällt mir ein?
Eine Lösung besteht darin, Folgendes zu machen:
user.getName().getFirstName().getStringValue()
Was absolut schrecklich ist, viele Regeln für Calisthenic-Objekte zu brechen und das Demeter-Gesetz zu brechen.
Ein anderer wäre so etwas wie:
String firstName = user.provideFirstnameForOutput();
// That would have called in the user object =>
String firstName = name.provideFirstnameForOutput();
// That would have called in the name object =>
String firstName = firstname.provideFirstnameForOutput();
Aber ich fühle mich mit dieser Lösung nicht wohl, die nur ein "Accessor höherer Ordnung" zu sein scheint, wie das Umgehen von Standard-Getter / Setter mit einer Methode, die nur darauf abzielt, dem Demeter-Gesetz zu entsprechen ...
Irgendeine Idee ?
quelle
Eine Richtung, über die man nachdenken sollte, wäre, eine generische Elementfunktion zur Zeichenfolgenformatierung bereitzustellen, anstatt Zugriff auf die Rohdaten zu gewähren. Etwas wie das:
Sie sehen, mit diesem Ansatz sind Sie nicht nur auf die Bereitstellung der vollständigen Daten beschränkt, sondern können auch Mittel bereitstellen, um die Daten auf bequeme und sinnvolle Weise zu transformieren. Beispielsweise müssen Sie möglicherweise Streiche mit der Groß- / Kleinschreibung spielen:
Sie können auch einige häufig verwendete, möglicherweise komplexe Formate einmal definieren, so könnten Sie beispielsweise sagen
Das Schöne an diesem Ansatz ist, dass die einzelnen Zeichenfolgen innerhalb der
User
Klasse bleiben und der aufrufende Code tatsächlich wesentlich mehr Funktionen bietet. Der Nachteil ist jedoch, dass Sie den Vorlagenmechanismus implementieren müssen, informatDescription()
dem sich einige Codezeilen befinden.Als solches könnte dies ein völliger Overkill sein: Vergessen Sie niemals, dass Programmierprinzipien nur Richtlinien sind. Und wenn das Befolgen eines anderen Prinzips gegen das KISS-Prinzip verstößt, ist es wahrscheinlich am besten, es einfach zu machen. Wenn Sie also nicht mindestens ein solches Formatierungselement benötigen, würde ich es der Einfachheit halber nicht implementieren, indem ich den Accessor-basierten Ansatz verwende.
quelle
User
Objekts, eine Vorlagensprache zu analysieren und zu kompilieren / zu interpretieren?User
Klasse diese Funktionalität selbst implementieren muss. Wenn ich nur zwei Klassen hätte, die solche Funktionen benötigen, könnten Sie darauf wetten, dass ich den Mechanismus zum Ersetzen von Vorlagen in eine eigene Klasse zerlege. Dies soll ein Beispiel dafür sein, wie Sie die Abstraktion, die bereitgestellt wird,User
auf eine Ebene heben können, auf der es sich tatsächlich um mehr als nur einen Datencontainer handelt. Und ich glaube, darum geht es beim Vermeiden von Accessoren: OOP zu machen, anstatt mit ein paarstruct
s umzugehen .