Neben mir sitzt ein Kollege, der eine Benutzeroberfläche wie diese entworfen hat:
public interface IEventGetter {
public List<FooType> getFooList(String fooName, Date start, Date end)
throws Exception;
....
}
Das Problem ist, dass wir diesen "End" -Parameter derzeit nirgendwo in unserem Code verwenden. Er ist nur dort, weil wir ihn möglicherweise irgendwann in der Zukunft verwenden müssen.
Wir versuchen ihn davon zu überzeugen, dass es eine schlechte Idee ist, Parameter in Schnittstellen einzufügen, die momentan nicht von Nutzen sind, aber er besteht weiterhin darauf, dass eine Menge Arbeit erledigt werden muss, wenn wir irgendwann die Verwendung des Enddatums implementieren später und müssen dann den ganzen code anpassen.
Nun, meine Frage ist, gibt es Quellen, die sich mit einem Thema wie diesem "respektierten" Coding-Gurus befassen, mit dem wir ihn verknüpfen können?
end
Objekt eventuell den Parameter hinzu, und verwenden Sie sogar die Standardeinstellung, um den Code nicht zu beschädigennull
. Implementierende Klassen können dann nach Bedarf überschrieben werden.IQueryable
(kann nur bestimmte Ausdrücke annehmen) Code außerhalb des DALAntworten:
Laden Sie ihn ein, etwas über YAGNI zu erfahren . Der Begründungsteil der Wikipedia-Seite kann hier besonders interessant sein:
Andere mögliche Argumente:
„80% der Lebenszykluskosten ein Stück Software geht an Wartung“ . Das Schreiben von Code zur richtigen Zeit reduziert die Wartungskosten: Man muss weniger Code warten und kann sich auf den tatsächlich benötigten Code konzentrieren.
Quellcode wird einmal geschrieben, aber Dutzende Male gelesen. Ein zusätzliches Argument, das nirgendwo verwendet wird, würde zu einem zeitraubenden Verständnis führen, warum es ein Argument gibt, das nicht benötigt wird. Da dies eine Schnittstelle mit mehreren möglichen Implementierungen ist, wird die Sache nur schwieriger.
Es wird erwartet, dass der Quellcode selbstdokumentierend ist. Die tatsächliche Signatur ist irreführend, da ein Leser annehmen würde, dass dies
end
entweder das Ergebnis oder die Ausführung der Methode beeinflusst.Personen, die konkrete Implementierungen dieser Schnittstelle schreiben, verstehen möglicherweise nicht, dass das letzte Argument nicht verwendet werden sollte, was zu unterschiedlichen Ansätzen führen würde:
Ich brauche nicht
end
, also werde ich einfach seinen Wert ignorieren,Ich brauche nicht
end
, also werde ich eine Ausnahme auslösen, wenn es nicht istnull
,Ich brauche nicht
end
, aber ich werde versuchen, es irgendwie zu benutzen,Ich werde viel Code schreiben, der später verwendet werden kann, wenn
end
er benötigt wird.Beachten Sie jedoch, dass Ihr Kollege möglicherweise Recht hat.
Alle vorherigen Punkte basieren auf der Tatsache, dass das Refactoring einfach ist, sodass das spätere Hinzufügen eines Arguments keinen großen Aufwand erfordert. Dies ist jedoch eine Schnittstelle, und als Schnittstelle kann sie von mehreren Teams verwendet werden, die an anderen Teilen Ihres Produkts mitwirken. Das bedeutet, dass das Ändern einer Schnittstelle besonders schmerzhaft sein kann. In diesem Fall trifft YAGNI hier nicht wirklich zu.
Die Antwort von hjk bietet eine gute Lösung: Das Hinzufügen einer Methode zu einer bereits verwendeten Schnittstelle ist nicht besonders schwierig, hat aber in einigen Fällen auch erhebliche Kosten:
Einige Frameworks unterstützen keine Überladungen. Zum Beispiel und wenn ich mich gut erinnere (korrigiere mich, wenn ich falsch liege), unterstützt .NETs WCF keine Überladungen.
Wenn die Schnittstelle viele konkrete Implementierungen aufweist, müsste zum Hinzufügen einer Methode zur Schnittstelle alle Implementierungen durchlaufen und die Methode auch dort hinzugefügt werden.
quelle
(etwas später)
Das ist alles was Sie brauchen, Methodenüberladung. Die zusätzliche Methode in der Zukunft kann transparent eingeführt werden, ohne dass Aufrufe der vorhandenen Methode beeinträchtigt werden.
quelle
end
Parameter jetzt wirklich unnötig ist, und dieend
Methode -less während des gesamten Projekts (der Projekte) angewendet hat, ist das Aktualisieren der Schnittstelle die geringste Sorge, da eine Aktualisierung der erforderlich wird Implementierungsklassen. Meine Antwort zielt speziell auf den Teil "Den gesamten Code anpassen" ab, da sich der Kollege so anhielt, als müssten die Aufrufer der ursprünglichen Methode während des gesamten Projekts (der Projekte) aktualisiert werden, um einen dritten Standard- / Dummy-Parameter einzuführen .Appelle an die Behörde sind nicht besonders überzeugend; Es ist besser, ein Argument vorzulegen, das gültig ist, egal wer es gesagt hat.
Hier ist eine Reduktion ad absurdum , die überzeugen oder demonstrieren soll, dass Ihr Kollege ungeachtet seiner Sensibilität fest davon überzeugt ist, "richtig" zu sein:
Was Sie wirklich brauchen, ist
Sie wissen nie, wann Sie für Klingonisch internationalisieren müssen. Deshalb sollten Sie sich jetzt darum kümmern, da die Nachrüstung viel Arbeit erfordert und Klingonen nicht für ihre Geduld bekannt sind.
quelle
You never know when you'll have to internationalize for Klingon
. Aus diesem Grund sollten Sie einfach ein übergebenCalendar
und den Clientcode entscheiden lassen, ob er einGregorianCalendar
oder ein senden möchteKlingonCalendar
(ich wette, einige haben bereits eines gesendet). Duh. :-pStarDate sdStart
undStarDate sdEnd
? Wir können die Föderation schließlich nicht vergessen ...Date
!HebrewDate start
undHebrewDate end
.Aus der Perspektive der Softwareentwicklung glaube ich, dass die richtige Lösung für diese Art von Problemen im Builder-Muster liegt. Dies ist definitiv ein Link von 'Guru'-Autoren für Ihren Kollegen http://en.wikipedia.org/wiki/Builder_pattern .
Im Builder-Muster erstellt der Benutzer ein Objekt, das die Parameter enthält. Dieser Parametercontainer wird dann an die Methode übergeben. Dadurch werden die Parameter, die Ihr Kollege in Zukunft benötigt, nicht mehr erweitert und überlastet, und das Ganze wird sehr stabil, wenn Änderungen vorgenommen werden müssen.
Ihr Beispiel wird:
quelle
IEventGetter
zu zu verschiebenISearchFootRequest
. Ich würde stattdessen so etwas wiepublic IFooFilter
mit member vorschlagen,public bool include(FooType item)
das zurückgibt, ob der Artikel enthalten sein soll oder nicht. Anschließend können einzelne Schnittstellenimplementierungen entscheiden, wie diese Filterung durchgeführt wirdSie brauchen es jetzt nicht, also fügen Sie es nicht hinzu. Wenn Sie es später benötigen, erweitern Sie die Schnittstelle:
quelle
Da kein Konstruktionsprinzip absolut ist, stimme ich den anderen Antworten größtenteils zu, dachte aber, ich würde Teufelsanwalt sein und einige Bedingungen diskutieren, unter denen ich die Lösung Ihres Kollegen akzeptieren würde:
Now()
, wird durch Hinzufügen eines Parameters ein Nebeneffekt beseitigt, der sich positiv auf Caching und Komponententests auswirkt. Vielleicht ermöglicht es eine einfachere Implementierung. Oder vielleicht ist es konsistenter mit anderen APIs in Ihrem Code.Allerdings ist meiner Erfahrung nach die größte Folge von YAGNI YDKWFYN: Sie wissen nicht, welche Form Sie benötigen (ja, ich habe mir gerade dieses Akronym ausgedacht). Auch wenn die Verwendung eines Grenzwertparameters relativ vorhersehbar ist, kann dies in Form eines Seitengrenzwerts, einer Anzahl von Tagen oder eines Booleschen Werts erfolgen, der angibt, dass das Enddatum aus einer Benutzervoreinstellungstabelle oder einer beliebigen Anzahl von Dingen verwendet werden soll.
Da Sie die Anforderung noch nicht haben, wissen Sie nicht, welcher Typ dieser Parameter sein soll. Oft haben Sie entweder eine umständliche Benutzeroberfläche, die nicht ganz Ihren Anforderungen entspricht, oder Sie müssen sie ohnehin ändern.
quelle
Es gibt nicht genügend Informationen, um diese Frage zu beantworten. Es kommt darauf an, was
getFooList
genau und wie es funktioniert.Hier ist ein naheliegendes Beispiel für eine Methode, die einen zusätzlichen Parameter unterstützen soll, der verwendet wird oder nicht.
Das Implementieren einer Methode für eine Sammlung, bei der Sie den Anfang, aber nicht das Ende der Sammlung angeben können, ist oft albern.
Sie müssen sich wirklich das Problem selbst ansehen und fragen, ob der Parameter im Kontext der gesamten Schnittstelle unsinnig ist und wie viel Belastung der zusätzliche Parameter tatsächlich mit sich bringt.
quelle
Ich fürchte, Ihr Kollege hat vielleicht tatsächlich einen sehr gültigen Punkt. Obwohl seine Lösung eigentlich nicht die beste ist.
Aus seiner vorgeschlagenen Schnittstelle geht klar hervor, dass
gibt Instanzen zurück, die innerhalb eines bestimmten Zeitintervalls gefunden wurden. Wenn Clients derzeit den End-Parameter nicht verwenden, ändert dies nichts an der Tatsache, dass sie Instanzen erwarten, die innerhalb eines bestimmten Zeitintervalls gefunden wurden. Dies bedeutet nur, dass derzeit alle Clients endlose Intervalle verwenden (von Anfang bis Ewigkeit).
Eine bessere Schnittstelle wäre also:
Wenn Sie das Intervall mit einer statischen Factory-Methode angeben:
Dann haben die Kunden nicht einmal das Gefühl, eine Endzeit angeben zu müssen.
Gleichzeitig vermittelt Ihr Interface korrekter, was es tut, da
getFooList(String, Date)
nicht mitteilt, dass es sich um ein Intervall handelt.Beachten Sie, dass mein Vorschlag von dem ausgeht, was die Methode derzeit tut, und nicht von dem, was sie in Zukunft tun sollte oder könnte, und daher das YAGNI-Prinzip (das in der Tat sehr gültig ist) hier nicht gilt.
quelle
Das Hinzufügen eines nicht verwendeten Parameters ist verwirrend. Die Leute könnten diese Methode aufrufen, vorausgesetzt, diese Funktion wird funktionieren.
Ich würde es nicht hinzufügen. Es ist trivial, es später mit einem Refactoring hinzuzufügen und die Anrufstellen mechanisch zu reparieren. In einer statisch getippten Sprache ist dies einfach zu tun. Es ist nicht notwendig, es eifrig hinzuzufügen.
Wenn es ist ein Grund , dass zu haben Parameter Sie die Verwirrung verhindern: eine Assertion bei der Umsetzung dieser Schnittstelle hinzufügen zu erzwingen , dass dieser Parameter als Standardwert übergeben werden. Wenn jemand zumindest diesen Parameter versehentlich verwendet, merkt er beim Testen sofort, dass diese Funktion nicht implementiert ist. Dies verringert die Gefahr, dass ein Fehler in die Produktion gerät.
quelle