Ist es ein Codegeruch, wenn eine private Methode eine öffentliche Methode aufruft?

25

Ist es ein Codegeruch, eine öffentliche Methode in einer privaten Methode derselben Objektinstanz aufzurufen?

Eimantas
quelle
AAMOI hast du ein konkretes Beispiel?
ocodo
Nein, momentan nicht. Ich erinnere mich an einen Fall, den ich mit meinen Kollegen besprochen habe. Wollte hier auch ein paar Meinungen bekommen.
Eimantas
5
Normalerweise kann ich ein Akronym anhand des Kontexts herausfinden, aber AAMOI Ich musste definitiv nachschlagen
Carson Myers
@Carson - hast du was gefunden?
Eimantas
4
Aus Gründen des Interesses
Carson Myers

Antworten:

33

Nein, kein schlechter Geruch. Dies könnte erforderlich sein. Warum vermuten Sie, dass es falsch ist? Eine Methode auf atomarer Ebene ist eine unabhängige Einheit, die eine Aufgabe ausführt. Solange eine Aufgabe erledigt wird, kann jeder, der Zugriff darauf hat, diese aufrufen, um die Aufgabe zu erledigen.

Aussenseiter
quelle
Genau. Einige Methoden bieten Funktionen, die sowohl für interne als auch für externe Anrufer nützlich sind. Eine rote Fahne könnte sein, wenn die öffentliche Methode sehr spezifisch für die interne Implementierung war, aber selbst dann ist nicht jede Klasse dazu gedacht, ihre Interna zu verbergen. Ich habe zum Beispiel oft eine Datenstruktur-Tool-Ebene unter einer Container-Abstract-Typ-Ebene - auf diese Weise kann ich einen Teil des Datenstrukturcodes für andere Datenstrukturen wiederverwenden, die anderen Containern zugrunde liegen.
Steve314
20

Code riechen? Ja, nicht wirklich schlecht, aber ein guter Indikator dafür, dass die Klasse möglicherweise zu viele Verantwortlichkeiten hat.

Nehmen Sie es als Zeichen dafür, dass die Klasse möglicherweise in verschiedene Objekte aufgeteilt werden muss. Private Methoden sollten nicht unbedingt öffentliche Methoden desselben Objekts aufrufen müssen, jedenfalls nicht in einem sauberen OO-Design.

Wenn Sie die Klasse überprüft haben und die Gründe für den Methodenaufruf klar sind, kann dies natürlich durchaus sinnvoll sein. Im Allgemeinen würden Sie erwarten, dass Dienstprogrammmethoden für die Klasse privat sind, aber wenn eine nützlich genug ist Wenn sie öffentlich sind und von anderen Methoden verwendet werden, würde ich allgemein erwarten, dass diese Methoden auch öffentlich sind.

Wie bei allen Code-Gerüchen ist dies eine Motivation für weitere Code-Inspektion, Rationalisierung und vielleicht Umgestaltung, aber kein Grund zur Beunruhigung.

ocodo
quelle
5
+1 für 'kein Grund zur Besorgnis'. Zu oft sehen wir einen "Geruch" und gehen sofort in den Refactor-Modus, ohne nachzudenken.
Michael K
+1 für SRP. Ich bin gerade auf einen Fall gestoßen, in dem ein Dekorateur nicht arbeitete, weil die dekorierte Klasse ihre eigene öffentliche Funktion aufrief und den Dekorateur umging. Die Lösung: Brechen Sie die Klasse in zwei Teile und injizieren Sie die dekorierte Abhängigkeit.
Jon Hulka
18

Es kann zu unangenehmen Überraschungen führen, wenn jemand, der den Quellcode dieser Klasse nicht gelesen hat, versucht, eine Unterklasse zu erstellen, und die öffentliche Methode überschreibt. Ob das wirklich ein Problem ist, hängt natürlich von Ihrer Situation ab. Vielleicht solltest du überlegen, die öffentliche Methode oder sogar die Klasse endgültig zu machen.

Kim
quelle
Warum? Wenn eine überschriebene öffentliche Methode zu unangenehmen Überraschungen führt, ist es dann wirklich wichtig, wer die Methode aufgerufen hat?
user281377
4
Ja tut es. Wenn das Überschreiben einer öffentlichen Methode eine andere öffentliche Methode unterbricht, kann ich auch diese andere Methode überschreiben. Wenn es eine private Methode bricht, kann ich ....?
Kim
5
Eine unangenehme Überraschung, die sich aus dem Überschreiben einer öffentlichen Methode ergibt, ist ein Code-Geruch an sich. Eigentlich ein Code-Gestank.
Larry Coleman
Kim: Wenn die Methode öffentlich ist, müssen Sie davon ausgehen, dass andere Klassen diese Methode genauso gut
aufrufen
@ Larry: Genau! Eine private Methode (die normalerweise implementierungsspezifische Annahmen enthält), die eine öffentliche Methode aufruft, erhöht die Wahrscheinlichkeit, dass das Überschreiben der öffentlichen Methode zu Problemen führt.
Kim
5

Ich glaube nicht, dass wir genaralisieren können.

Es hängt alles sehr stark vom Kontext ab.

Ich könnte zum Beispiel eine öffentliche Utility-Methode in einer Klasse haben, die von anderen Klassen verwendet wird, und auch eine private Methode in derselben Klasse.

Nivas
quelle
5

Was sollte in diesem Fall noch getan werden? Machen Sie die private Methode öffentlich oder die öffentliche Methode privat? Kopieren Sie den Code aus der öffentlichen Methode in die private Methode.

user281377
quelle
Oder lassen Sie die öffentliche Methode an eine (neue) private Methode delegieren, die von der anderen privaten Methode aufgerufen wird. Aber warum sich die Mühe machen?
Lawrence Dol
4

NEIN , kein übler Geruch hier.

Wenn wir die Schnittstelle einer Warteschlange mit List implementieren, ist es ein schlechter Geruch, nur die richtigen List-Funktionen aufzurufen, um die Implementierung der Warteschlange einfach zu erreichen?

Wenn Sie etwas haben und es in etwas anderes umwandeln möchten (wie einen Wrapper), dann ist es kein schlechter Geruch. Die Wiederverwendbarkeit des Codes mit dem Entwurfsmuster erfolgt auf Funktionsebene. (Ist eine Funktion ein Objekt?)

Anzeigename
quelle
2

Ich weiß, dass dies ein alter Beitrag ist, aber darüber habe ich bei der Arbeit diskutiert. Ich halte dies für einen Codegeruch und kann nicht verstehen, warum Sie dies jemals tun möchten. Wenn eine private Methode eine öffentliche Methode aufrufen muss, sollte der Inhalt der öffentlichen Methode entnommen und in eine private Methode gestellt werden, die dann beide Methoden aufrufen können. Warum?

  1. Die öffentliche Methode enthält möglicherweise Tests, die nicht mehr erforderlich sind, wenn Sie Code intern ausführen. Möglicherweise wird ein UserObj empfangen, und Sie möchten beispielsweise die Benutzerberechtigungen testen.

  2. Nach einem öffentlichen Aufruf müssen Sie das Objekt möglicherweise sperren, wenn Sie Threading verwenden. Sie möchten also intern nicht zu einer öffentlichen Methode zurückkehren.

  3. Meiner Meinung nach ist es wahrscheinlicher, Zirkelfehler und Endlosschleifen sowie Ausnahmen einzuführen.

  4. Schlicht und einfach, schlechtes Design und "faul". Öffentliche Methoden ermöglichen den Zugang zur Außenwelt. Es gibt keinen Grund, wieder nach draußen zu gehen, wenn Sie schon drinnen sind.

Mark Graham
quelle
1
Was ist, wenn die vorhandene öffentliche Methode von vielen anderen Klassen aufgerufen wird? Wenn du es privat machst, wird das kaputt gehen. Denken Sie daran, dass öffentliche Methoden aus anderen Gründen von anderen Klassen aufgerufen werden, nicht nur von dieser Klasse. irgendwie, warum öffentliche Methoden existieren.
Michael Durrant
Ich erklärte, dass 'der Inhalt der öffentlichen Methode genommen und in eine private Methode gestellt werden sollte ...' Die öffentliche Methode bleibt bestehen, ruft aber die neue private Methode auf. Wie alle anderen privaten Methoden, die dieselbe Funktionalität wiederverwenden müssen.
Mark Graham
Sie fügen also aus keinem anderen Grund eine andere Methode hinzu als - nun, weil Sie dies als "Code-Geruch" deklariert haben. Sinnlose Methoden sind ein schlechterer Codegeruch.
gnasher729
Tut mir leid, aber habe ich oben nicht nur einige Gründe aufgeführt. Ein Großteil des Codes, den ich schreibe, ist für Geschäftssysteme bestimmt. Viele Klassen sind auf Benutzer beschränkt, die auf Rollen basieren. Viele öffentliche Methoden testen Benutzerberechtigungen und -parameter. Warum in aller Welt sollte ich dieselbe öffentliche Methode erneut aufrufen, um ihre Funktionalität wiederzuverwenden und die Benutzerberechtigungen erneut zu testen?
Mark Graham
Ich habe in meinem Leben noch nie eine öffentliche Methode von einer privaten Methode aufrufen müssen. Es scheint und fühlt sich für mich einfach sehr falsch an. Ich bin wirklich überrascht, dass die meisten Leute denken, dass es in Ordnung ist.
Falle
2

Stellen Sie sich das Gegenteil vor. Sie befinden sich in einer privaten Methode und benötigen Funktionen in einer öffentlichen Methode. Was wäre, wenn Sie diese öffentliche Methode nicht von der privaten Methode aus aufrufen könnten ? Was würdest du tun?

  • Eine doppelte private Methode erstellen? Nein
  • Eine spezielle öffentliche Methode für den Anlass erstellen? Nein
  • Eine spezielle private Methode aufrufen, die öffentliche Methoden aufrufen kann? Nein
  • Irgendeine Art von Super, die das kann? Nein

Die Antwort ist eindeutig, dass Sie, wenn Sie die Funktionalität in einer öffentlichen Methode wünschen, diese Methode aus Methoden dieser Klasse oder aus anderen Klassen aufrufen können sollten.

Michael Durrant
quelle
1

In meinem Code erstelle ich häufig verzögerte Ladevorgänge, dh, das Objekt wird beim ersten Anfordern initialisiert und verwendet anschließend dasselbe instanziierte Objekt erneut. Ein Objekt, das mit einer verzögerten Last instanziiert wird, impliziert jedoch, dass es nicht unbedingt an einem bestimmten Punkt instanziiert werden muss. Anstatt mich mit der Sequenz von Aufrufen zu beschäftigen, sodass ich weiß, dass dieses Objekt bereits instanziiert ist, oder den gleichen Code einer verzögerten Ladung innerhalb einer anderen Methode zu wiederholen, rufe ich einfach den verzögerten Lader auf, wann immer ich das Objekt benötige.

So wie Sie öffentliche Methoden intelligent einsetzen können, können Sie sie auch falsch anwenden. Ein Beispiel hierfür ist eine öffentliche Methode, die ihre Parameter verarbeitet, bevor eine andere private Methode aufgerufen wird. Es wäre ein Fehler, diese öffentliche Methode nur deshalb beiläufig aufzurufen, weil Sie dieselben Parameter haben. Der Fehler ist subtil, aber er ist mehr als alles andere ein Entwurfsfehler und erfordert, dass Sie lernen, mit den Parametern der internen Methode und nicht mit den Parametern der öffentlichen Methode umzugehen.

Um Ihre Frage zu beantworten, ist es sicherlich kein schlechter Code, wenn Sie ihn richtig verwenden.

Neil
quelle
1

Die Frage, die Sie sich stellen müssen, ist, warum Ihre Klasse dieselben Bedürfnisse hat wie die Kunden Ihrer Klasse. Normalerweise hat eine Klasse ganz andere Bedürfnisse als ihre Kunden. Also ja, das ist ein Hinweis darauf, dass Sie entweder haben

(a) etwas öffentlich zugänglich machen, das privat sein sollte; oder

(b) Das Verhalten der Klasse ist nicht eng genug (Prinzip der Einzelverantwortung).

Brad Thomas
quelle