Ich hatte eine kleine Debatte mit einem Kollegen. Gibt es einen guten Grund, reine Funktionen zu verbergen / zu kapseln?
Mit "rein" meine ich die Wikipedia-Definition :
- Gibt immer die gleichen Ergebnisse von der gleichen Eingabe zurück. (Aus Gründen dieser Diskussion
Foo Create(){ return new Foo(); }
wird es als unrein angesehen, wennFoo
es keine Wertsemantik gibt.) - Verwendet keinen veränderlichen Status (außer lokale Variablen) oder E / A.
- Erzeugt keine Nebenwirkungen.
design
pure-function
Telastyn
quelle
quelle
Antworten:
Eine reine Funktion könnte immer noch ein Implementierungsdetail sein. Obwohl die Funktion keinen Schaden anrichten kann (im Hinblick darauf, wichtige Invarianten / Verträge nicht zu brechen), verlieren sowohl der Autor als auch die Benutzer dieser Klasse / dieses Moduls / Pakets, indem sie sie offenlegen. Der Autor verliert, weil er es jetzt nicht mehr entfernen kann, auch wenn sich die Implementierung ändert und die Funktion für ihn nicht mehr nützlich ist. Die Benutzer verlieren, weil sie zusätzliche Funktionen durchsehen und ignorieren müssen, die für die Verwendung der API nicht relevant sind, um sie zu verstehen.
quelle
Die Frage ist rückwärts.
Sie suchen nicht nach einem Grund, eine Funktion nicht öffentlich zu machen. Es ist eine falsche Einstellung, um mit (meiner Meinung nach) zu beginnen. Die Argumentation sollte in die andere Richtung gehen.
Mit anderen Worten - fragen Sie nicht "warum sollte ich es privat machen?". Fragen Sie: "Warum sollte ich es veröffentlichen?"
Im Zweifelsfall nicht aussetzen. Es ist ein bisschen wie Ockhams Rasiermesser - vermehren Sie nicht die Ansprüche, die über die Notwendigkeit hinausgehen.
BEARBEITEN: Adressierung der von @Telastyn in Kommentaren vorgebrachten Gegenargumente (um eine längere Diskussion dort zu vermeiden):
Ja, es ist manchmal mühsam, wenn eine Klasse zur Vererbung geöffnet ist, aber Sie können einige private Methoden (deren Verhalten Sie ändern möchten) nicht überschreiben.
Aber
protected
würde ausreichen - und es ist immer noch nicht öffentlich.Wenn es problematisch wird, machen Sie es einfach öffentlich! Es gibt die Notwendigkeit, über die ich gesprochen habe :)
Mein Punkt ist, dass Sie es nicht nur für den Fall tun sollten (YAGNI und alle).
Beachten Sie, dass es immer einfacher ist, eine private Funktion öffentlich zu machen, als sie in den Datenschutz zurückzuziehen. Letzteres wird wahrscheinlich den vorhandenen Code beschädigen.
quelle
Ich denke nicht, dass die Entscheidung, eine Funktion zu verbergen / einzukapseln, von ihrer Reinheit abhängen sollte. Nur weil eine Funktion rein ist, heißt das nicht, dass Externe davon wissen müssen. Interessanterweise muss die Funktion, wenn sie rein und öffentlich sein soll, nicht einmal ein Instanzmitglied der Schnittstelle sein, vielleicht ist sie besser als statische Funktion geeignet. Aber auch hier hängt alles von der Absicht des Vertrags und in diesem Fall von der logischen Gruppierung der Funktionalität ab, nicht von der Reinheit der Funktion.
quelle
Der Unterricht sollte nach dem Prinzip der Einzelverantwortung ablaufen . Während eine Klasse möglicherweise andere Funktionen aufrufen muss, um ihre Ziele zu erreichen, sollte sie nur Funktionen offenlegen, die Teil ihrer Einzelverantwortung sind.
Hier ist nur ein Beispiel für einen Fall, in dem die Sichtbarkeit ein Problem verursachen könnte .
Stellen Sie sich eine Klasse vor, die Widgets frobniziert. Vielleicht benötigt es als Teil seines Frobnication-Codes eine Utility-Funktion, die einen String analysiert: Vielleicht muss es den Widget-Namen so umwandeln, dass Standard-String-Funktionen dies nicht unterstützen.
Da dies eine reine Funktion ist (String kommt rein, transformiert es irgendwie, gibt einen neuen String zurück), könnte sie ohne Konsequenz öffentlich oder privat sein. Oder könnte es?
Wenn Sie es veröffentlichen, hat Ihre Klasse jetzt zwei Aufgaben: Widgets frobnizieren und Zeichenfolgen transformieren. Dies verstößt gegen SRP und kann Probleme verursachen, wenn andere Klassen auf die Funktion angewiesen sind. Da dies Ihrer Meinung nach nur klassenintern verwendet wird, ändern Sie möglicherweise die Benutzeroberfläche oder die Sichtbarkeit. Jetzt sind Klassen in anderen Teilen des Systems kaputt.
Wenn Sie die Funktion privat halten, hat niemand die Möglichkeit, sich auf Code zu verlassen, der nicht Teil der alleinigen Verantwortung der Klasse ist.
quelle
StringTransformer
Klasse, um zwei oder drei Codezeilen zu kapseln, die nur an einer Stelle verwendet werden? Ich stimme zu, dass es am besten ist, wenn Code an mehreren Stellen verwendet wird, ihn in eine neue Klasse mit einer Verantwortung zu unterteilen, aber es gibt einen Kompromiss.