Ist es zur Vereinfachung der Benutzeroberfläche besser, die getBalance()
Methode nicht zu haben ? Übergeben 0
an charge(float c);
wird das gleiche Ergebnis geben:
public class Client {
private float bal;
float getBalance() { return bal; }
float charge(float c) {
bal -= c;
return bal;
}
}
Vielleicht eine Notiz machen javadoc
? Oder überlassen Sie es einfach dem Klassenbenutzer, herauszufinden, wie er das Gleichgewicht herstellen kann?
interfaces
cqrs
David
quelle
quelle
Antworten:
Sie scheinen anzunehmen, dass die Komplexität einer Schnittstelle an der Anzahl der Elemente gemessen wird (in diesem Fall an den Methoden). Viele würden argumentieren, dass man sich daran erinnern muss, dass die
charge
Methode verwendet werden kann, um den Rest von a zurückzugeben, wasClient
viel komplexer ist als das zusätzliche Element dergetBalance
Methode. Es ist viel einfacher, die Dinge expliziter zu machen, insbesondere bis zu dem Punkt, an dem es keine Mehrdeutigkeit mehr gibt, unabhängig von der höheren Anzahl von Elementen in der Schnittstelle.Außerdem anrufen
charge(0)
verstößt das gegen das Prinzip des geringsten Erstaunens , das auch als WTFs pro Minute- Metrik (von Clean Code, Bild unten) bezeichnet wird, und erschwert es neuen Mitgliedern des Teams (oder jetzigen, nach einer Weile vom Code entfernt), bis Sie verstehen, dass der Anruf tatsächlich verwendet wird, um das Guthaben zu erhalten. Überlegen Sie, wie andere Leser reagieren würden:Außerdem verstößt die Signatur der
charge
Methode gegen die Richtlinien , eine und nur eine Sache und eine Trennung zwischen Befehlen und Abfragen durchzuführen , da das Objekt seinen Status ändert und gleichzeitig einen neuen Wert zurückgibt.Alles in allem glaube ich, dass die einfachste Schnittstelle in diesem Fall wäre:
quelle
getBalance()
einen bestimmten Wert zurückgibt und nichts ändert. Auf der anderen Seitecharge(0)
sieht es so aus, als würde es wahrscheinlich etwas ändern ... Vielleicht wird ein PropertyChanged-Ereignis gesendet? Und was gibt es zurück, den vorherigen Wert oder den neuen Wert? Jetzt müssen Sie es in den Dokumenten nachschlagen und Ihren Verstand verschwenden, was mit einer klareren Methode hätte vermieden werden können.charge(0)
als Methode zum Abrufen des Gleichgewichts, da es zufällig keine Auswirkungen hat, bringt Sie jetzt mit diesem Implementierungsdetail in Kontakt. Ich kann mir leicht vorstellen, dass eine zukünftige Anforderung, bei der die Verfolgung der Anzahl der Ladungen relevant wird, zu einem Schmerzpunkt wird, wenn Ihre Codebasis mit Ladungen übersät ist, die eigentlich keine Ladungen sind. Sie sollten Schnittstellenelemente bereitstellen, die das bedeuten, was Ihre Kunden tun müssen, und keine Elemente, die nur das tun, was Ihre Kunden tun müssen.charge()
Wenn diese Methode in einem gleichzeitigen System atomar ist, kann es für eine Methode angebracht sein, den neuen oder alten Wert zurückzugeben.IMO, das Ersetzen
getBalance()
durchcharge(0)
in Ihrer gesamten Anwendung ist keine Vereinfachung. Ja, es sind weniger Zeilen, aber es verschleiert die Bedeutung dercharge()
Methode, was möglicherweise zu Kopfschmerzen führen kann, wenn Sie oder eine andere Person diesen Code erneut aufrufen müssen.Obwohl sie möglicherweise das gleiche Ergebnis erzielen, entspricht das Abrufen des Kontostands nicht einer Belastung von Null. Daher ist es wahrscheinlich am besten, Ihre Bedenken zu trennen. Wenn Sie beispielsweise bei jeder Kontotransaktion Änderungen
charge()
am Protokoll vornehmen mussten, besteht jetzt ein Problem, und die Funktionalität muss ohnehin getrennt werden.quelle
Denken Sie daran, dass sich Ihr Code selbst dokumentieren sollte. Wenn ich anrufe
charge(x)
, erwarte ich einex
Gebühr. Informationen zum Gleichgewicht sind zweitrangig. Außerdem weiß ich möglicherweise nicht, wiecharge()
es implementiert wird, wenn ich es aufrufe, und ich weiß definitiv nicht, wie es morgen implementiert wird. Betrachten Sie dieses potenzielle zukünftige Update beispielsweise alscharge()
:Plötzlich
charge()
sieht es nicht mehr so gut aus, wenn man verwendet , um das Gleichgewicht herzustellen.quelle
charge
viel schwerer ist.Es
charge(0);
ist eine schlechte Idee, den Kontostand abzurufen: Eines Tages könnte jemand dort einen Code hinzufügen, um die getätigten Gebühren zu protokollieren, ohne die andere Verwendung der Funktion zu bemerken. Jedes Mal, wenn jemand den Kontostand abruft, wird dieser Code als Gebühr protokolliert. (Es gibt Möglichkeiten, dies zu umgehen, beispielsweise eine bedingte Anweisung, die Folgendes sagt:Diese setzen jedoch voraus, dass der Programmierer sie implementieren kann. Dies wird er nicht tun, wenn nicht sofort klar ist, dass sie erforderlich sind.
Kurz gesagt: Verlassen Sie sich nicht darauf, dass Ihre Benutzer oder die Nachfolger Ihres Programmierers erkennen, dass dies
charge(0);
der richtige Weg ist, um das Gleichgewicht zu finden, denn wenn es keine Dokumentation gibt, die garantiert nicht verpasst, sieht das ehrlich gesagt nach dem erschreckendsten Weg aus, das Gleichgewicht zu finden möglich.quelle
Ich weiß, dass es viele Antworten gibt, aber ein weiterer Grund dafür
charge(0)
ist, dass ein einfacher Tippfehler dazucharge(9)
führt, dass sich der Kontostand Ihres Kunden jedes Mal verringert, wenn Sie den Kontostand abrufen möchten. Wenn Sie über gute Unit-Tests verfügen, können Sie dieses Risiko möglicherweise mindern. Wenn Sie jedoch nicht bei jedem Anruf fleißig vorgehen,charge
kann dies zu einem Missgeschick führen.quelle
Ich möchte einen speziellen Fall erwähnen, in dem es sinnvoll wäre , weniger, mehr Mehrzweckmethoden zu haben: Wenn es viel Polymorphismus gibt, das heißt, viele Implementierungen dieser Schnittstelle ; Insbesondere, wenn diese Implementierungen in separat entwickeltem Code enthalten sind, der nicht synchron aktualisiert werden kann (die Schnittstelle wird durch eine Bibliothek definiert).
In diesem Fall ist die Vereinfachung des Schreibens jeder Implementierung weitaus wertvoller als die Klarheit der Verwendung, da erstere Vertragsverletzungsfehler vermeidet (die beiden Methoden sind nicht miteinander vereinbar), während letztere nur die Lesbarkeit beeinträchtigen, was möglich ist durch eine Hilfsfunktion oder eine Superklasse-Methode wiederhergestellt werden, die
getBalance
im Sinne voncharge
.(Dies ist ein Entwurfsmuster, für das ich mich nicht an einen bestimmten Namen erinnere: Definieren einer komplexen aufruferfreundlichen Schnittstelle im Sinne einer minimalen implementierungsfreundlichen. In Classic Mac OS wurde die minimale Schnittstelle für Zeichenoperationen als "Engpass" bezeichnet.) Dies scheint jedoch kein populärer Begriff zu sein.)
Ist dies nicht der Fall (es gibt nur wenige oder genau eine Implementierung)
charge()
, ist es sinnvoll , die Methoden der Übersichtlichkeit halber zu trennen und das für Gebühren ungleich Null relevante Verhalten einfach zu addieren .quelle
realloc
manchmal auf einigen Systemen.