Funktionen sind selbst für jemanden ohne Programmiererfahrung, aber mit einem fairen mathematischen Hintergrund leicht zu verstehen. Auf der anderen Seite scheinen Klassen schwieriger zu verstehen zu sein.
Angenommen, ich möchte eine Klasse / Funktion erstellen, die das Alter einer Person anhand ihres Geburtstagsjahres und des aktuellen Jahres berechnet. Soll ich dafür eine Klasse oder eine Funktion erstellen? Oder hängt die Wahl vom Szenario ab?
PS Ich arbeite an Python, aber ich denke, die Frage ist allgemein.
Antworten:
Erstellen Sie eine Funktion. Funktionen machen bestimmte Dinge, Klassen sind bestimmte Dinge.
Klassen haben oft Methoden, die Funktionen sind, die einer bestimmten Klasse zugeordnet sind, und Dinge tun, die mit der Sache verbunden sind, die die Klasse ist - aber wenn Sie nur etwas tun möchten, ist eine Funktion alles, was Sie brauchen.
Im Wesentlichen ist eine Klasse eine Möglichkeit, Funktionen (als Methoden) und Daten (als Eigenschaften) in einer logischen Einheit zu gruppieren, die sich um eine bestimmte Art von Dingen dreht. Wenn Sie diese Gruppierung nicht benötigen, müssen Sie keine Klasse erstellen.
quelle
class
gruppiert Funktionen und Daten. Dies hat unter keinen Umständen Vorteile. Wir haben Funktionen, Datentypen und Module, um sie zu gruppieren. Selbst wenn Sie einen Ad-hoc-Funktionspolymorphismus benötigen: verschiedene Funktionsimplementierungen für verschiedene Datentypen, gibt es viel bessere Lösungen als OOP-Klassen; Betrachten Sie Typklassen im Haskell-Stil, die letztendlich sprachunabhängig sind.Wie das, was Amber in ihrer Antwort sagt : Erstellen Sie eine Funktion. In der Tat, wenn Sie keinen Unterricht machen müssen, wenn Sie etwas haben wie:
Hier haben Sie nur eine Funktion, die in einer Klasse gekapselt ist. Dies macht den Code nur weniger lesbar und weniger effizient. Tatsächlich kann die Funktion
compute
einfach so geschrieben werden:Sie sollten Klassen nur verwenden, wenn Sie mehr als eine Funktion haben und wenn das Beibehalten eines internen Status (mit Attributen) sinnvoll ist. Wenn Sie andernfalls Funktionen neu gruppieren möchten, erstellen Sie einfach ein Modul in einer neuen
.py
Datei.Sie könnten dieses Video (Youtube, ca. 30 Minuten) ansehen , das meinen Standpunkt erklärt. Jack Diederich zeigt, warum Klassen in diesem Fall böse sind und warum es so ein schlechtes Design ist, besonders in Sachen API.
Es ist ein ziemlich langes Video, aber es ist ein Muss.
quelle
Das hängt vom Szenario ab. Wenn Sie nur das Alter einer Person berechnen möchten, verwenden Sie eine Funktion, da Sie ein einzelnes bestimmtes Verhalten implementieren möchten .
Wenn Sie jedoch ein Objekt erstellen möchten, das das Geburtsdatum einer Person (und möglicherweise andere Daten) enthält, es ändern kann, kann die Berechnung des Alters eine von vielen Operationen sein, die sich auf die Person beziehen, und es wäre sinnvoll, dies zu tun Verwenden Sie stattdessen eine Klasse.
Klassen bieten eine Möglichkeit, einige Daten und verwandte Vorgänge zusammenzuführen. Wenn Sie nur eine Operation für die Daten ausführen und dann eine Funktion verwenden und die Daten als Argument übergeben, erhalten Sie ein äquivalentes Verhalten mit weniger komplexem Code.
Beachten Sie, dass eine Klasse der Art:
ist nicht wirklich eine Klasse, es ist nur eine (komplizierte) Funktion. Eine legitime Klasse sollte immer mindestens zwei Methoden haben (ohne zu zählen
__init__
).quelle
Klassen (oder vielmehr ihre Instanzen) dienen zur Darstellung von Dingen. Klassen werden verwendet, um die Operationen zu definieren, die von einer bestimmten Klasse von Objekten (ihren Instanzen) unterstützt werden. Wenn Ihre Anwendung den Überblick behalten muss,
Person
handelt es sich wahrscheinlich um eine Klasse. Die Instanzen dieser Klasse repräsentieren bestimmte Personen, die Sie verfolgen.Funktionen dienen zur Berechnung von Dingen. Sie empfangen Eingaben und erzeugen eine Ausgabe und / oder haben Auswirkungen.
Klassen und Funktionen sind keine wirklichen Alternativen, da sie nicht für die gleichen Dinge sind. Es ist nicht wirklich sinnvoll, eine Klasse zu bilden, um "das Alter einer Person anhand ihres Geburtstagsjahres und des aktuellen Jahres zu berechnen". Sie können oder nicht Klassen zu einem der Begriffe darstellen
Person
,Age
,Year
und / oderBirthday
. Aber selbst wennAge
es sich um eine Klasse handelt, sollte man nicht daran denken, das Alter einer Person zu berechnen. Vielmehr führt die Berechnung des Alters einer Person zu einer Instanz derAge
Klasse.Wenn Sie Personen in Ihrer Anwendung modellieren und eine
Person
Klasse haben, kann es sinnvoll sein, die Altersberechnung als Methode derPerson
Klasse zu verwenden. Eine Methode ist im Grunde eine Funktion, die als Teil einer Klasse definiert ist. Auf diese Weise definieren Sie "die Operationen, die von einer bestimmten Klasse von Objekten unterstützt werden", wie bereits erwähnt.Sie können also für Ihre Personenklasse eine Methode zur Berechnung des Alters der Person erstellen (wahrscheinlich wird das Geburtstagsjahr aus dem Personenobjekt abgerufen und das aktuelle Jahr als Parameter empfangen). Die Berechnung wird jedoch weiterhin von einer Funktion durchgeführt (nur eine Funktion, die zufällig eine Methode für eine Klasse ist).
Oder Sie können einfach eine eigenständige Funktion erstellen, die Argumente empfängt (entweder ein Personenobjekt, aus dem ein Geburtsjahr abgerufen werden soll, oder einfach das Geburtsjahr selbst). Wie Sie bemerken, ist dies viel einfacher, wenn Sie noch keine Klasse haben, zu der diese Methode natürlich gehört! Sie sollten niemals eine Klasse erstellen, nur um eine Operation durchzuführen. Wenn das alles ist, was die Klasse zu bieten hat, sollte die Operation nur eine eigenständige Funktion sein.
quelle
Person
als definierennamedtuple
und schreiben, welche Funktionen Sie benötigen.Ich weiß, dass es ein kontroverses Thema ist, und wahrscheinlich werde ich jetzt verbrannt. aber hier sind meine Gedanken.
Für mich selbst dachte ich, dass es am besten ist, den Unterricht so lange wie möglich zu vermeiden. Wenn ich einen komplexen Datentyp benötige, verwende ich einfache Struktur (C / C ++), Diktat (Python), JSON (js) oder ähnliches, dh keinen Konstruktor, keine Klassenmethoden, keine Überladung von Operatoren, keine Vererbung usw. Bei Verwendung von class, Sie können sich von OOP selbst (Welches Designmuster, was sollte privat sein, bla bla) mitreißen lassen und sich nicht mehr auf das Wesentliche konzentrieren, das Sie zuerst codieren wollten.
Wenn Ihr Projekt groß und chaotisch wird, macht OOP Sinn, da eine Art Systemarchitektur mit Hubschrauberansicht erforderlich ist. "Funktion gegen Klasse" hängt auch von der vor Ihnen liegenden Aufgabe ab.
Funktion
struct / dict / json / etc (anstelle von class)
Klasse (wenn es sich um einen neuen Datentyp handelt)
Array / Vektor / Liste (um viele Daten zu speichern)
Aufzählung (Aufzählungsklasse)
quelle
Bevor Sie Ihre Frage beantworten:
Wenn Sie keine
Person
Klasse haben, müssen Sie zunächst überlegen, ob Sie einePerson
Klasse erstellen möchten . Planen Sie, das Konzept einesPerson
sehr oft wiederzuverwenden ? In diesem Fall sollten Sie einePerson
Klasse erstellen . (Sie haben Zugriff auf diese Daten in Form einer übergebenen Variablen und es ist Ihnen egal, ob Sie chaotisch oder schlampig sind.)Zur Beantwortung Ihrer Frage:
Sie haben Zugriff auf ihr Geburtsjahr. In diesem Fall haben Sie wahrscheinlich eine
Person
Klasse mit einemsomeperson.birthdate
Feld. In diesem Fall müssen Sie sich fragen, obsomeperson.age
ein Wert wiederverwendbar ist.Die Antwort ist ja. Das Alter ist uns oft wichtiger als das Geburtsdatum. Wenn das Geburtsdatum also ein Feld ist, sollte das Alter definitiv ein abgeleitetes Feld sein. (Ein Fall, in dem wir dies nicht tun würden: Wenn wir Werte wie
someperson.chanceIsFemale
odersomeperson.positionToDisplayInGrid
andere irrelevante Werte berechnen würden, würden wir diePerson
Klasse nicht erweitern . Sie fragen sich nur: "Würde sich ein anderes Programm um die Felder kümmern, mit denen ich die Klasse erweitern möchte? ? "Die Antwort auf diese Frage bestimmt, ob Sie die ursprüngliche Klasse erweitern oder eine Funktion (oder eine eigene Klasse wiePersonAnalysisData
oder so) erstellen.)quelle
Erstelle niemals Klassen. Zumindest die OOP-Klassen in Python werden diskutiert.
Betrachten Sie diese vereinfachende Klasse:
gegen diese NamedTuple-Version:
Der Namedtuple-Ansatz ist besser, weil:
inheritance
fügt Komplexität hinzu und verbirgt Komplexität.Ich sehe keinen einzigen Vorteil bei der Verwendung von OOP-Klassen. Wenn Sie an OOP gewöhnt sind oder mit Code arbeiten müssen, für den Klassen wie Django erforderlich sind.
Übrigens haben die meisten anderen Sprachen einige Datensatztypen wie namedtuples. Scala hat zum Beispiel Fallklassen. Diese Logik gilt dort gleichermaßen.
quelle
namedtuple
Ansatz, den Sie befürworten, scheint keine Methodenkapselung oder Verstecken von Daten zu bieten (es sei denn, ich vermisse etwas). Dies sind zwei Hauptvorteile eines echten OO-Ansatzes: Sie können Daten zusammen mit den Funktionen, die darauf einwirken, verpacken und den privaten Status in einem Objekt beibehalten. Wenn Sie das nicht tun, erfinden Sie OOP nur schlecht neu, und es ist schwieriger, mit dem Code zu arbeiten, nicht einfacher.Ich werde mich in diesem Fall von der Herde lösen und einen alternativen Standpunkt vertreten:
Erstelle niemals Klassen.
Die Abhängigkeit von Klassen führt in erheblichem Maße dazu, dass Codierer aufgeblähten und langsamen Code erstellen. Klassen, die herumgereicht werden (da sie Objekte sind), benötigen viel mehr Rechenleistung als das Aufrufen einer Funktion und das Übergeben von ein oder zwei Zeichenfolgen. Richtige Namenskonventionen für Funktionen können so ziemlich alles, was das Erstellen einer Klasse kann, und das mit nur einem Bruchteil des Overheads und einer besseren Lesbarkeit des Codes.
Das heißt aber nicht, dass Sie nicht lernen sollten, Klassen zu verstehen. Wenn Sie mit anderen programmieren, werden diese ständig verwendet, und Sie müssen wissen, wie Sie diese Klassen unter einen Hut bringen. Wenn Sie Ihren Code so schreiben, dass er sich auf Funktionen stützt, ist der Code kleiner, schneller und besser lesbar. Ich habe riesige Sites gesehen, die nur mit Funktionen geschrieben wurden, die schnell und schnell waren, und ich habe winzige Sites gesehen, die nur minimale Funktionen hatten, die stark auf Klassen beruhten und ständig kaputt gingen. (Wenn Sie Klassen haben, die Klassen erweitern, die Klassen als Teil ihrer Klassen enthalten, wissen Sie, dass Sie den Anschein einer einfachen Wartbarkeit verloren haben.)
Wenn es darauf ankommt, können alle Daten, die Sie übergeben möchten, problemlos von den vorhandenen Datentypen verarbeitet werden.
Klassen wurden als mentale Krücke erstellt und bieten keine wirklichen zusätzlichen Funktionen, und der übermäßig komplizierte Code, den sie tendenziell erzeugen, besiegt auf lange Sicht den Punkt dieser Krücke.
quelle