Reicht es aus, Methoden nur nach dem Argumentnamen (nicht nach dem Typ) zu unterscheiden, oder ist es besser, ihn expliziter zu benennen?
Zum Beispiel T Find<T>(int id)
vs T FindById<T>(int id)
.
Gibt es einen guten Grund, es expliziter zu benennen (dh hinzuzufügen ById
), anstatt nur den Argumentnamen beizubehalten?
Ein Grund, an den ich denken kann, ist, dass die Signaturen der Methoden gleich sind, aber eine andere Bedeutung haben.
FindByFirstName(string name)
und FindByLastName(string name)
T Find<T>(string name)
oder(int size)
wie planen Sie, die unvermeidlichen Probleme zu lösen?ID
Objekt sein und nicht nur einint
. Auf diese Weise überprüfen Sie während der Kompilierung, ob Sie in einem Teil Ihres Codes eine ID für ein int oder umgekehrt verwenden. Und damit kannst dufind(int value)
und habenfind(ID id)
.Antworten:
Sicher gibt es einen guten Grund, es expliziter zu nennen.
Es ist nicht in erster Linie die Methode Definition , die selbsterklärend sein sollte, aber die Methode verwenden . Und während
findById(string id)
undfind(string id)
beide selbsterklärend sind, gibt es einen großen Unterschied zwischenfindById("BOB")
undfind("BOB")
. Im ersteren Fall wissen Sie, dass das zufällige Literal tatsächlich eine ID ist. Im letzteren Fall sind Sie sich nicht sicher - es könnte sich tatsächlich um einen Vornamen oder etwas ganz anderes handeln.quelle
findById(id)
vsfind(id)
. Sie können so oder so vorgehen.double Divide(int numerator, int denominator)
in einem Verfahren verwendet werden:double murdersPerCapita = Divide(murderCount, citizenCount)
. Sie können sich nicht auf zwei Methoden verlassen, die denselben Variablennamen verwenden, da es viele Fälle gibt, in denen dies nicht der Fall ist (oder wenn dies der Fall ist, ist es eine falsche Benennung)Vorteile von FindById () .
Zukunftssicherheit : Wenn Sie mit beginnen
Find(int)
, und später anderen Methoden hinzufügen müssen (FindByName(string)
,FindByLegacyId(int)
,FindByCustomerId(int)
,FindByOrderId(int)
usw.), Leute wie ich sind in der Regel im Alter zu verbringen suchenFindById(int)
. Nicht wirklich ein Problem , wenn Sie können und wird sich ändernFind(int)
zu ,FindById(int)
sobald es notwendig wird - Zukunftssicherheit ist über diese , wenn s.Einfacher zu lesen .
Find
ist vollkommen in Ordnung, wenn der Anruf so aussieht. Ist jedoch etwas einfacher zu lesen, wenn dies derrecord = Find(customerId);
FallFindById
istrecord = FindById(AFunction());
.Konsistenz . Sie können das Muster
FindByX(int)
/FindByY(int)
überall konsistent anwenden ,Find(int X)
/Find(int Y)
ist jedoch nicht möglich, da Konflikte auftreten.Vorteile von Find ()
Find
ist einfach und unkompliziert und nebenbeioperator[]
einer der 2 am meisten erwarteten Funktionsnamen in diesem Zusammenhang. (Einige beliebte Alternativen sindget
,lookup
oderfetch
, je nach Kontext).FindById(int id)
, können wir Redundanzen leicht entfernen, indem wir sie auf ändernFind(int id)
, aber es gibt einen Kompromiss - wir verlieren etwas Klarheit.Alternativ können Sie die Vorteile von beiden nutzen, indem Sie stark typisierte IDs verwenden:
Implementierung von
Id<>
: Starke Eingabe von ID-Werten in C #Die Kommentare hier und im obigen Link haben zu mehreren Bedenken geführt, auf
Id<Customer>
die ich eingehen möchte:CustomerId
undOrderID
sind verschiedene Typen (customerId1 = customerId2;
=> gut,customerId1 = orderId1;
=> schlecht), aber ihre Implementierung ist nahezu identisch, sodass wir sie entweder mit Copy Paste oder mit Metaprogramm implementieren können. Während in einer Diskussion Wert darauf gelegt wird, das Generikum entweder freizulegen oder zu verbergen, ist Metaprogrammierung das, wofür Generika gedacht sind.DoSomething(int customerId, int orderId, int productId)
. Stark eingegebene IDs verhindern auch andere Probleme, einschließlich desjenigen, nach dem OP gefragt wurde.int aVariable
. Es ist leicht zu erkennen, dass eine ID gespeichert istId<Customer> aVariable
, und wir können sogar feststellen, dass es sich um eine Kunden-ID handelt.String
ist nur ein Wrapper herumbyte[]
. Das Umschließen oder Einkapseln steht nicht im Widerspruch zu starker Typisierung.operator==
undoperator!=
auch, wenn Sie sich nicht ausschließlich auf Folgendes verlassen möchtenEquals
:.
quelle
Eine andere Art, darüber nachzudenken, besteht darin, die Typensicherheit der Sprache zu verwenden.
Sie können eine Methode wie die folgenden implementieren:
Wobei FirstName ein einfaches Objekt ist, das eine Zeichenfolge umschließt, die den Vornamen enthält und bedeutet, dass es keine Verwirrung darüber geben kann, was die Methode tut und mit welchen Argumenten sie aufgerufen wird.
quelle
string name = "Smith"; findById(name);
Machen, die möglich sind, wenn Sie nicht beschreibende allgemeine Typen verwenden.DWORD
LPCSTR
Klone usw. an und denken, "es ist ein int / string / etc.", es kommt zu dem Punkt, an dem Sie mehr Zeit damit verbringen, Ihre Werkzeuge zu stützen, als Sie tatsächlich Code entwerfen .int
s häufig summiert, multipliziert usw., was für IDs bedeutungslos ist. also würde ich michID
unterscheiden vonint
. Dies kann eine API vereinfachen, indem eingegrenzt wird, was wir mit einem bestimmten Wert tun können (z. B. wenn wir einen habenID
, funktioniert dies nur mitfind
, nicht z . B.age
oderhighscore
). Wenn wir dagegen feststellen, dass wir viel konvertieren oder dieselbe Funktion / Methode (z. B.find
) für mehrere Typen schreiben , ist dies ein Zeichen dafür, dass unsere Unterscheidungen zu fein sindIch werde für eine explizite Erklärung wie FindByID stimmen. Software sollte für den Wandel gebaut werden. Es sollte offen und geschlossen sein (SOLID). Die Klasse ist also offen, ähnliche Suchmethoden wie FindByName usw. hinzuzufügen.
FindByID ist jedoch geschlossen und seine Implementierung ist Unit-getestet.
Ich werde keine Methoden mit Prädikaten vorschlagen, die sind gut im Allgemeinen. Was ist, wenn Sie basierend auf dem Feld (ByID) unterschiedliche Methoden anwenden.
quelle
Ich bin überrascht, dass niemand vorgeschlagen hat, ein Prädikat wie das folgende zu verwenden:
Mit diesem Ansatz reduzieren Sie nicht nur die Oberfläche Ihrer API, sondern geben dem Benutzer, der sie verwendet, auch mehr Kontrolle.
Wenn das nicht ausreicht, können Sie es jederzeit nach Ihren Wünschen erweitern.
quelle