Ich bin auf Code gestoßen (C #, wenn es darauf ankommt), der Klassen hat, die denselben Namen haben, sich aber in ihren Namespaces unterscheiden. Sie alle neigen dazu, dasselbe logische Ding darzustellen, sind aber oft unterschiedliche "Ansichten" desselben Objekts. Die verschiedenen Namespaces sind manchmal Teil derselben Lösung und sogar derselben DLL.
Ich habe meine Gedanken, konnte aber nichts Bestimmtes über diese Praxis finden, das als kluger Einsatz der verfügbaren Werkzeuge oder als zu vermeidendes Muster angesehen werden könnte.
Diese Frage zur Schlumpfbenennung berührt dies, aber aus der anderen Richtung. Die eindeutige Bezeichnung der Namen würde wahrscheinlich ein willkürliches und allgegenwärtiges Präfix erfordern, das mit dieser Frage beseitigt werden sollte.
Was sind die Richtlinien für diese Praxis?
FooAdapter
,FooViewer
,FooCalculator
etc. , aber sicherlich das Gleiche nicht genannt. Ohne weitere Informationen zu den spezifischen Klassen, über die Sie sprechen, ist es jedoch schwierig, eine Antwort zu geben.Employee
als Beispiel betrachten. Es gibt einen Mitarbeiter, der für andere Mitarbeiter bestimmt ist, einen für die Personalabteilung und einen für die externe Exposition. Sie heißen alle "Mitarbeiter" und haben verschiedene Helfer (EmployeeRepository, EmployeeView usw.). Sie befinden sich alle in derselben DLL und haben zwar einige gemeinsame Eigenschaften (Name, Titel), unterscheiden sich jedoch alle (Telefonnummer, Gehalt).Employee
Sie mehrmals mit Systemen gearbeitet haben, die ein Modell haben, klingt dies so, als ob Sie ein Modell mit der Vereinigung aller Attribute benötigen und eintype
oderdepartment
-Attribut einschließen . Andernfalls wird der Code unnötig dupliziert.Antworten:
Ich werde versuchen, eine Antwort gegen eine solche Verwendung zu geben, nachdem ich dies auch in einem meiner Projekte gesehen und daran gearbeitet habe.
Lesbarkeit des Codes
Bedenken Sie zunächst, dass die Lesbarkeit des Codes wichtig ist und diese Vorgehensweise dem widerspricht. Jemand liest einen Code und sagt einfach, dass er eine Funktion hat
doSomething(Employee e)
. Dies ist nicht mehr lesbar, da Sie aufgrund von 10 verschiedenenEmployee
Klassen in verschiedenen Paketen zuerst auf die Importdeklaration zurückgreifen müssen, um herauszufinden, was Ihre Eingabe wirklich ist.Dies ist jedoch eine Ansicht auf hoher Ebene, und wir haben oft scheinbar zufällige Namenskonflikte, die niemanden interessieren oder gar finden, da die Bedeutung aus dem verbleibenden Code abgeleitet werden kann und in welchem Paket Sie sich befinden. Man könnte also sogar argumentieren dass es vor Ort kein Problem gibt, denn wenn Sie
Employee
in einemhr
Paket sehen, müssen Sie natürlich wissen, dass es sich um eine HR-Sicht des Mitarbeiters handelt.Die Dinge brechen jedoch auseinander, sobald Sie diese Pakete verlassen. Sobald Sie in einem anderen Modul / Paket / usw. arbeiten und mit einem Mitarbeiter zusammenarbeiten müssen, beeinträchtigen Sie bereits die Lesbarkeit, wenn Sie den Typ nicht vollständig qualifizieren. Wenn Sie 10 verschiedene
Employee
Klassen haben, funktioniert die automatische Vervollständigung Ihrer IDE nicht mehr und Sie müssen manuell aus dem Mitarbeitertyp auswählen.Codeduplizierung
Aufgrund der Natur jeder dieser Klassen, die miteinander in Beziehung stehen, wird sich Ihr Code aufgrund vieler Duplikate zwangsläufig verschlechtern. In den meisten Fällen haben Sie so etwas wie den Namen eines Mitarbeiters oder eine Identifikationsnummer, die jede Klasse implementieren muss. Auch wenn jede Klasse ihre eigene Ansicht hinzufügt, werden Sie eine große Menge nutzlosen, aber kostspieligen Codes erhalten, wenn sie die zugrunde liegenden Mitarbeiterdaten nicht gemeinsam nutzen.
Code-Komplexität
Was kann so komplex sein? Schließlich kann jede Klasse es so einfach halten, wie sie will. Was wirklich zu einem Problem wird, ist, wie Sie Änderungen verbreiten. In einer einigermaßen funktionsreichen Software können Sie möglicherweise Mitarbeiterdaten ändern - und das möchten Sie überall widerspiegeln. Sagen Sie, dass eine Dame gerade verheiratet , und Sie müssen sie umbenennen von
X
zuY
aus diesem Grund. Schwer genug, dies überall richtig zu machen, aber noch schwieriger, wenn Sie all diese unterschiedlichen Klassen haben. Abhängig von Ihren anderen Entwurfsoptionen kann dies leicht bedeuten, dass jede der Klassen einen eigenen Listener oder einen solchen Listener implementieren muss, um über Änderungen informiert zu werden. Dies bedeutet im Grunde, dass ein Faktor auf die Anzahl der Klassen angewendet wird, mit denen Sie sich befassen müssen . Und natürlich mehr Codeduplizierung und weniger Lesbarkeit des Codes. Faktoren wie diese sind in der Komplexitätsanalyse möglicherweise nicht zu erkennen, aber sie sind sicher ärgerlich, wenn sie auf die Größe Ihrer Codebasis angewendet werden.Code-Kommunikation
Abgesehen von den oben genannten Problemen mit der Codekomplexität, die auch mit Entwurfsentscheidungen zusammenhängen, verringern Sie auch Ihre übergeordnete Entwurfsklarheit und verlieren die Fähigkeit, ordnungsgemäß mit Domain-Experten zu kommunizieren. Wenn Sie über Architektur, Designs oder Anforderungen sprechen, können Sie keine einfachen Aussagen mehr treffen wie
given an employee, you can do ...
. Ein Entwickler wirdemployee
zu diesem Zeitpunkt nicht mehr wissen, was wirklich bedeutet. Obwohl ein Domain-Experte es natürlich wissen wird. Das machen wir alle. irgendwie. In Bezug auf die Software ist die Kommunikation jedoch nicht mehr so einfach.Wie man das Problem loswird
Nachdem er sich dessen bewusst und wenn Ihr Team stimmt zu, dass es ein Problem groß genug ist, in Angriff zu nehmen , dann werden Sie zur Arbeit einen Weg mit ihm zu tun haben. Normalerweise können Sie Ihren Manager nicht bitten, dem gesamten Team eine Woche frei zu geben, damit es den Müll rausbringen kann. Im Wesentlichen müssen Sie also einen Weg finden, um diese Klassen nacheinander teilweise zu eliminieren. Das Wichtigste dabei ist, mit dem gesamten Team zu entscheiden, was ein
Employee
wirklich ist. Integrieren Sie nicht alle einzelnen Attribute in einen Gott-Mitarbeiter. Denken Sie mehr an einen Hauptmitarbeiter und entscheiden Sie vor allem, wo dieseEmployee
Klasse wohnen wird.Wenn Sie Codeüberprüfungen durchführen, ist es besonders einfach sicherzustellen, dass das Problem zumindest nicht weiter zunimmt, dh alle auf der Strecke zu halten, wenn sie erneut ein neues hinzufügen möchten
Employee
. Achten Sie auch darauf, dass neue Subsysteme die vereinbarten einhaltenEmployee
und nicht auf die alten Versionen zugreifen dürfen.Abhängig von Ihrer Programmiersprache möchten Sie möglicherweise auch die Klassen markieren, die eventuell eliminiert werden
@Deprecated
, um Ihrem Team zu helfen, sofort zu erkennen, dass sie mit etwas arbeiten, das geändert werden muss.Um die veralteten Mitarbeiterklassen loszuwerden, können Sie für jeden Einzelfall entscheiden, wie sie am besten beseitigt werden sollen, oder sich einfach auf ein gemeinsames Muster einigen. Sie können den Klassennamen anbringen und um den tatsächlichen Mitarbeiter wickeln, Sie können Muster verwenden (Dekorator oder Adapter kommen in den Sinn) oder oder oder oder.
Um es kurz zu machen: Diese "Praxis" ist technisch einwandfrei, aber voller versteckter Kosten, die erst später anfallen werden. Während Sie das Problem möglicherweise nicht sofort beseitigen können, können Sie sofort damit beginnen, die schädlichen Auswirkungen einzudämmen.
quelle
Das Scala Collection Framework ist ein gutes Beispiel dafür. Es gibt veränderbare und unveränderliche Sammlungen sowie serielle und parallele (und in Zukunft möglicherweise auch verteilte) Sammlungen. So gibt es zum Beispiel vier
Map
Merkmale:plus drei
ParMap
s:Noch interessanter:
So
ParMap
erstrecktParMap
sich erstreckt sichMap
undMap
erstreckt sichMap
erweitertMap
.Aber seien wir ehrlich: Wie würden Sie sie sonst nennen? Das macht durchaus Sinn. Dafür sind Namespaces da!
quelle
Dies ist eine wirklich interessante Frage, bei der die beiden im Wesentlichen gegensätzlichen Antworten richtig sind. Hier ist ein reales Beispiel für diese Diskussion, die wir über ein Projekt von mir führen.
Ich denke, es gibt bisher zwei sehr wichtige Überlegungen, die Sie dazu bringen würden, in die eine oder andere Richtung zu gehen, wobei Sie sich auf die beiden Antworten von @Jorg und @Frank stützen:
hr.Employee
aber gleichzeitig die Berechtigungen über prüfen müssensecurity.Employee
, wird es sehr schnell nervig.Map
Klassen dieselbe Schnittstelle implementieren oder Unterklassen voneinander sind. In diesem Fall kann die Mehrdeutigkeit oder "Verwirrung" wohl als eine gute Sache bezeichnet werden, da der Benutzer alle Implementierungen der Klasse oder Schnittstelle zu Recht gleich behandeln kann ... das ist der Punkt von Schnittstellen und Unterklassen.quelle