Ich schreibe ein Programm in Python, das im Grunde genommen Strings manipuliert, und ich habe mich gefragt, ob ich es mit OOP-Prinzipien machen soll oder nicht. Der Kunde hat mir gesagt, dass ihm der Code egal ist, er möchte nur, dass die Sache erledigt wird .
Ich weiß, dass objektorientierter Code nicht per Definition sauberer ist, und umgekehrt ist Nicht-OO-Code per Definition nicht beschissen. Die Frage, die ich stelle, basiert vielleicht mehr oder weniger auf Meinungen, aber es gibt möglicherweise einige Regeln, die mir nicht bekannt sind.
Noch ein paar Infos darüber, was zu tun ist:
- Analysieren Sie eine
.csv
Datei und verarbeiten Sie die Daten basierend auf einer Konfigurationsdatei (die Spalten können unterschiedlich sein - wie die Anzahl der Spalten oder die Daten, die sie enthalten). - Verwenden Sie die oben verarbeiteten Daten, um neue, benutzerdefiniert formatierte Daten zu erstellen (oder mehrere Dateien, die auf einigen der oben genannten Werte basieren).
- Verwenden Sie die zuletzt formatierten Daten, um eine XML-Datei zu erstellen.
XML
Teilen Sie die XML-Datei anhand ihres Inhalts in mehrere s auf- Die Anwendung sollte CLI-basiert sein
- Es gibt natürlich auch andere Dinge wie: Protokollieren einiger Ereignisse, Analysieren von CLI-Argumenten usw.
Nun, dies ist überhaupt keine große / harte Anwendung, und es ist auch fast fertig, aber während des gesamten Entwicklungsprozesses habe ich mich immer wieder gefragt, ob dies mit OOP geschehen soll oder nicht.
Meine Frage wäre also: Wie wisst ihr, wann OOP in einer Anwendung verwendet werden soll?
quelle
Antworten:
Python ist eine Multiparadigmasprache, dh Sie können das für die Aufgabe am besten geeignete Paradigma auswählen. Einige Sprachen wie Java sind OO mit einem einzigen Paradigma, was bedeutet, dass Sie Kopfschmerzen bekommen, wenn Sie versuchen, ein anderes Paradigma zu verwenden. Plakate mit der Aufschrift "Immer OO verwenden" stammen wahrscheinlich aus einem Umfeld in einer solchen Sprache. Aber zum Glück haben Sie die Wahl!
Ich stelle fest, dass Ihr Programm eine CLI-App ist, die einige Eingaben (CSV- und Konfigurationsdateien) liest und einige Ausgaben (XML-Dateien) erzeugt, aber nicht interaktiv ist und daher keine statusbehaftete GUI oder API hat. Ein solches Programm wird natürlich als eine Funktion von Eingabe zu Ausgabe ausgedrückt, die an andere Funktionen für Unteraufgaben delegiert.
Bei OO hingegen geht es um die Kapselung des veränderlichen Zustands und ist daher besser für interaktive Anwendungen, GUIs und APIs geeignet, die den veränderlichen Zustand offenlegen. Es ist kein Zufall, dass OO parallel zu den ersten GUIs entwickelt wurde.
OO bietet einen weiteren Vorteil, da durch Polymorphismus eine locker gekoppelte Architektur ermöglicht wird, bei der verschiedene Implementierungen derselben Schnittstelle leicht ersetzt werden können. In Kombination mit Dependency Injection kann dies das konfigurationsbasierte Laden von Abhängigkeiten und anderen coolen Dingen ermöglichen. Dies ist jedoch meistens für sehr große Anwendungen geeignet. Für ein Programm von der Größe, die Sie beschreiben, wäre es viel zu viel Aufwand ohne erkennbaren Nutzen.
Abgesehen von den Funktionen, mit denen die Dateien tatsächlich gelesen und geschrieben werden, kann der Großteil Ihrer Logik als nebenwirkungsfreie Funktionen geschrieben werden, für die Eingaben erforderlich sind und andere Ausgaben zurückgegeben werden. Dies ist äußerst einfach zu testen, viel einfacher als das Testen von OO-Einheiten, bei denen Sie Abhängigkeiten und so weiter verspotten müssen.
Fazit: Ich schlage eine Reihe von Funktionen vor, die für die Organisation in Module unterteilt sind, aber keine Objekte.
quelle
Betrachten Sie eine Schaltfläche auf einer GUI. Es hat einen Status (Größe, Farbe, Position, Beschriftung usw.). Es können Dinge passieren (es ist angeklickt, muss neu gezeichnet werden usw.). In solchen Situationen ist es sinnvoll, es als Objekt zu modellieren. Als Objekt kann es seinen Status enthalten, eine Reihe von Aktionen, die darauf ausgeführt werden können (Methoden), und es kann andere Teile der Anwendung darüber informieren, dass ihm etwas passiert ist, indem Ereignisse ausgelöst werden.
OOP ist ein hervorragendes Tool für den Umgang mit GUIs und anderen Situationen, in denen Teile des Systems flüchtige Zustände aufweisen.
Andere Situationen, wie die von Ihnen beschriebene, in denen Daten aus einer Quelle gelesen, verarbeitet und in ein Ziel geschrieben werden, werden durch einen anderen Ansatz gut behandelt: deklarative (oder Funktions-) Programmierung. Deklarativer Code für die Datenverarbeitung ist in der Regel einfacher zu lesen und kürzer als OOP-Lösungen.
So wie Hammer und Säge bei richtiger Anwendung mächtige Werkzeuge sind, so sind auch objektorientierte und deklarative Programmiertechniken. Sie könnten wahrscheinlich mit dem Griff einer Säge einen Nagel in ein Stück Holz schlagen. Ebenso können Sie ein Stück Holz mit einem Hammer halbieren. Ebenso können Sie eine GUI mit nur Funktionen erstellen und Daten mit Objekten verarbeiten. Wenn die Werkzeuge jedoch richtig verwendet werden, sind die Ergebnisse sauberer und einfacher.
Die allgemeine Faustregel lautet, dass ich Objekte verwende, wenn ich viel Status habe oder Benutzerinteraktion benötige. ansonsten verwende ich (möglichst reine und höherwertige) Funktionen.
quelle
Objektorientierte Programmierung erweitert Ihr Arsenal um vier neue Tools :
Sie würden OOP in Ihrer Anwendung verwenden, wenn diese groß genug und komplex genug geworden ist, um von diesen Tools zu profitieren.
quelle
Diese Frage scheint mir ein wenig verwirrt. Wenn Sie es in Python schreiben, sind Sie ziemlich sicher gehen verwenden Objekte. Wenn Sie eine Datei öffnen, wird ein Objekt zurückgegeben. Wenn Sie result ergeben, gibt es ein Iterator-Objekt zurück. Jede von Ihnen erstellte Funktion ist ein Objekt. Den Wert von OO in Python-Anwendungen in Frage zu stellen, scheint gelinde gesagt seltsam.
Basierend auf den Kommentaren hier, ja, unterstützt Python funktionale Paradigmen, aber es ist in erster Linie objektbasiert. Die Sprache selbst und die eingebauten Bibliotheken orientieren sich an Objekten. Ja, es unterstützt Lambda (wie Java und jede andere Anzahl von Sprachen, die normalerweise als OO bezeichnet werden), aber es ist absichtlich simpel im Vergleich zu einer echten funktionalen Sprache.
Vielleicht werden diese Unterscheidungen zwischen OO-Design und funktionalem Design hinfällig. Wenn ich eine polymorphe Funktion für ein von OO entworfenes Objekt * erstelle und einen Zeiger auf diese Funktion für ein Objekt als Parameter für eine funktionell gestaltete Funktion * übergebe, ist das OO oder funktioniert es? Ich denke, es ist beides und auch ein wirklich effektiver Ansatz zur Lösung von Problemen.
Ich denke, die eigentliche Frage ist, wann Sie anfangen sollten, Ihre eigenen Klassen zu entwerfen, anstatt nur ein Modul mit Funktionen zu erstellen. Ich denke, die richtige Antwort ist: Wenn es hilft, die Lösung zu vereinfachen. Ich würde die gleiche grundlegende Antwort für jede objektorientierte Sprache geben.
* Redundanz ist beabsichtigt: Ich möchte hier nicht beschuldigt werden, dass Objekte OO sind oder dass Funktionen funktionsfähig sind.
quelle
Eines der größten Dinge bei der objektorientierten Programmierung ist, dass Sie statt über den Programmfluss über den Zustand nachdenken.
Oft sehe ich das Objekt, ich sehe die Methoden, aber ich sehe auch, dass der treibende Gedanke hinter dem Code Fluss statt Zustand ist.
Und wenn Sie einmal über den Zustand nachgedacht haben, ist es einfach, einen guten OOP-Code zu erstellen, denn sobald Ihr Code zu komplex wird, stellen Sie fest, dass Sie nicht mehr über Ihren Zustand nachdenken können und wissen, dass Sie umgestalten müssen.
Betrachten Sie Ihr Beispiel: Sie möchten eine CSV-Datei analysieren. Woher kommt es: eine Datei auf der Festplatte. Sie laden es und speichern es und analysieren es. Nun kommt Ihr Kunde: Hey, ich möchte auch Dateien aus dem Web analysieren. Sie sind also glücklich, weil Sie eine schöne Oberfläche zum Laden Ihrer Datei erstellt haben und nur den Code erstellen müssen, der sie aus dem Web abruft, und der Rest Ihres Programms bleibt genau gleich.
Und das Schöne ist: Das können Sie testen.
quelle
In den Begriffen des Laien:
Es sind jedoch noch weitere Faktoren zu berücksichtigen:
Verstehen Sie mich nicht falsch: Sie können all das erreichen, ohne OOP zu verwenden, aber mit OOP wird es einfacher.
Aber...
Wenn Ihr Team mit OOP / OOD nicht vertraut ist und keine Fachkenntnisse in diesem Bereich hat, gehen Sie mit den Ressourcen um, über die Sie verfügen.
quelle
Benutze es immer. Sobald Sie es gewohnt sind, werden Sie es für alles verwenden. Auf diese Weise kann eine gute Abstraktion zwischen Funktionen und deren Verwendung sichergestellt werden, was für die Wartung von großem Vorteil ist. Wir verwenden es zum Beispiel für
kleine Datenstrukturobjekte, weil diese so oft polymorph sind, und beispielsweise zwischenliegende Datenstrukturen nach dem Parsen haben oft mehrere kleine Entitäten, die ein gemeinsames Verhalten haben und dennoch auch spezialisiert sind. Dies ist ein großartiger Anwendungsfall für eine gemeinsame Basisklasse oder Schnittstelle mit speziellen Implementierungen und Verhaltensweisen, dh einer Klassenhierarchie (Polymorphismus).
Protokollierung als Beispiel, da es einfach ist, einen anderen Protokollierer zu ersetzen
große Teile der Programmstruktur, weil Sie mehrere gleichzeitig heraufbeschwören und möglicherweise die Vorteile von Multi-CPU-Prozessoren nutzen. Beispielsweise kann ein Webserver aufgrund von Objekten problemlos mehrere gleichzeitige Anforderungshandler verwenden.
Wie bereits erwähnt, erleichtert dies die Umgestaltung und Wiederverwendung und fördert eine gute Abstraktion, was die Wartung erleichtert. OOP sollte die ganze Zeit angenommen und genutzt werden. Eine gute OOP-Programmierung vermeidet statische Methoden und / oder statische Daten und verwendet Objekte für alles.
quelle
Objektorientierte Programmierung bietet Tools zum Erstellen von Frameworks. Diese Werkzeuge sind Encapsulation, Abstraction, Inheritance und Polymorphism. Mithilfe dieser Ideen können Sie Ihr Programm in zwei Abschnitte unterteilen.
Gewusst wie - Dies ist der Frame-Arbeitsteil Ihres Codes, in dem Sie eine Art Abstraktion erstellen, entscheiden, wie Ihre Blöcke im Allgemeinen funktionieren und wie sie mit anderen Blöcken interagieren.
Was zu - In diesem Teil erledigen die Blöcke die eigentliche Arbeit. Hier werden die Klassen von den Basisklassen abgeleitet, die im Abschnitt "Gewusst wie" erstellt wurden.
Man kann sehr von OOPS profitieren
quelle