Eines der wichtigsten Konzepte in der objektorientierten Programmierung ist die Kapselung. In letzter Zeit scheint sich die Software-Welt jedoch zugunsten anderer Paradigmen wie der funktionalen Programmierung zu neigen.
Ich denke, was ist mit Kapselung und anderen OOP-Grundsätzen? Sind sie falsch?
Wird OOP falsch angewendet? Zum Beispiel wird Alan Kay in der OOPSLA'97-Keynote erwähnt: "Ich habe den Begriff objektorientiert erfunden, und ich kann Ihnen sagen, dass ich nicht an C ++ gedacht habe."
Joe Armstrong - "Objekte binden Funktionen und Datenstrukturen in unteilbaren Einheiten zusammen. Ich denke, dies ist ein grundlegender Fehler, da Funktionen und Datenstrukturen in völlig unterschiedliche Welten gehören."
Antworten:
Ich denke, die Falle, in die Sie hier geraten sind, besteht darin, dass es eine starre Definition jedes Programmierparadigmas gibt (strukturiert, objektorientiert, funktional usw.).
Wenn Sie zwei verschiedene Entwickler fragen, was OOP bedeutet, erhalten Sie zwei verschiedene Antworten. Ja, als Beruf sind wir uns einig, dass es einige gemeinsame Themen wie Kapselung, Verstecken von Daten usw. gibt, die von einem OOP-Kurs für Softwareentwicklung im College behandelt werden.
In der realen Welt sind die Dinge jedoch nicht ganz so trocken und trocken, weshalb zwei Entwickler zwei unterschiedliche Antworten geben. Vielleicht sind sie Experten in verschiedenen Sprachen, die OOP-Konzepte unterschiedlich ausdrücken. Sprachparadigmen überschneiden sich tendenziell. Die neueste Wut ab 2013 ist die Integration funktionaler Programmierung in objektorientierte Sprachen durch Verschlüsse oder Lambdas. Ist Java 8 objektorientiert oder funktional? Ich würde es objektorientiert mit einem Schuss Funktion nennen. Jemand anderes könnte es anders beschreiben.
Nein, das Problem ist, dass verschiedene Sprachen Programmierkonzepte unterschiedlich ausdrücken. Vielleicht lässt eine Sprache ein OOP-Konzept aus, und eine andere Sprache enthält es, lässt aber ein anderes OOP-Konzept aus. Sprachen sind in der Regel für einen Zweck konzipiert: eine bestimmte Art von Aufgabe zu vereinfachen, auf Kosten anderer Aufgaben. Das ist weder richtig noch falsch, es ist einfach ein realer Kompromiss, der nicht zu vermeiden ist.
Die reale Welt ist nicht das Klassenzimmer. Wir müssen entweder konzeptionelle Programmierparadigmen auf abstrakter Ebene diskutieren oder wir müssen echte Programmiersprachen diskutieren, die gezwungen sind, Kompromisse einzugehen, um nützlich zu sein. Solange eine Programmiersprache hauptsächlich durch eine abstrakte Definition von OOP definiert ist, können wir sie in diesen Bucket aufnehmen.
quelle
Das ist umstritten. Erstens sehe ich außer OOP und funktionaler Programmierung keine anderen Paradigmen, die so ausführlich diskutiert werden. Ich denke, wir können den Satz "andere Paradigmen wie" vergessen. Lassen Sie uns über FP sprechen, sonst nichts.
Die Gründe, warum funktionale Programmierung in den letzten Jahren so populär wurde, wurden in anderen Fragen hier ausführlich diskutiert. Ich werde dies nicht wiederholen (siehe hier oder hier zum Beispiel). Meiner Meinung nach liegt dies jedoch nicht daran, dass "OOP ein großer Fehler war" oder "Functional vs. OOP schließen sich gegenseitig aus", sondern eher daran, dass Leute ihre Toolbox erweitern und versuchen, das Beste aus beiden Welten herauszuholen. Ok, es gibt sicherlich Experten, die Hardliner sind, die einander vorziehen, aber Sie werden diese Leute auf beiden Seiten finden.
Verkapselung hat viele verschiedene Geschmacksrichtungen. Funktionale Programmiersprachen und Sprachkonstrukte bieten bestimmte Formen der Kapselung, andere objektorientierte. Wenn Sie nach Beispielen für die Kapselung mit funktionalen Mitteln suchen, beginnen Sie mit Verschlüssen .
In Bezug auf "andere Grundsätze": Nein, sie sind nicht falsch, aber für bestimmte Szenarien wie die Parallelisierung in großem Maßstab lassen sich funktionale Ansätze wahrscheinlich besser skalieren. Für andere Szenarien, wie das Erstellen gut gestalteter UI-Frameworks, lassen sich OOP-Ansätze wahrscheinlich besser skalieren (YMMV, ich habe nicht nur ein besseres Beispiel zur Hand). Darüber hinaus bin ich mir sicher, dass es für die meisten realen Szenarien vom Wissen und der Erfahrung des Teams mit seinem bevorzugten Programmierparadigma abhängt, wie gut ein bestimmtes System skaliert.
Sicherlich wird OOP von vielen Menschen oft falsch angewendet, aber ich bin sicher, dass dies auch für FP gilt. Und ich würde mich wundern, wenn John Mc Carthy (Designer von Lisp) so etwas wie Javascript im Sinn hätte, wenn er über funktionale Programmierung nachdachte (Gnade für mich, flamme mich nicht zu sehr für diesen Vergleich ;-)
Ich denke, der Erfinder von Erlang hat einige gute Argumente, aber er hat auch seinen eigenen Standpunkt. Lassen Sie ihn also seine Meinung sagen und bauen Sie Ihre eigene auf. Es gibt viele andere Experten, die eine andere Vorstellung davon haben.
quelle
Natürlich:
Ich weiß, was Sie sagen werden: "Aber das verkörpert nicht auch das Verhalten!" Nun, ich bin mit Joe Armstrong in dieser Sache: Sie können ganze Programme oder Betriebssysteme schreiben, ohne jemals erstklassige Objekte zu benötigen. Linux beweist das.
Javascript-Programmierer kapseln routinemäßig Status und Verhalten in Funktionen und Abschlüssen, nicht in Klassen.
quelle
Das Hauptproblem hierbei ist, dass die Kapselung weder ein fest definiertes Konzept ist noch warum sie nützlich ist. Einige Untersuchungen zeigen, dass die Art und Weise, wie Menschen die Verkapselung sehen, eine hohe Meinung hat und dass viele Menschen sie mit Abstraktion verwechseln.
Die erste Definition, die Sie finden werden, ist
Wenn dies Ihre Definition ist, können die meisten Sprachen Daten und Funktionen, die mit diesen Daten arbeiten, in Klassen, Module, Bibliotheken, Namespaces usw. gruppieren.
Aber ich würde argumentieren, dass dies nicht der Hauptzweck der Kapselung ist, da diese Definition weitergeht:
Wikipedia stimmt auch darin überein :
Jetzt müssen wir uns fragen, was unter "Interferenz und Missbrauch" zu verstehen ist und warum der direkte Zugriff auf die Daten eingeschränkt werden sollte. Ich glaube, es gibt zwei Gründe.
Erstens liegt es im Interesse des Entwicklers, den Umfang zu beschränken, in dem Daten mutiert werden können. Viel zu oft muss vor dem Einstellen des Werts eine Logik vorhanden sein. Und nur eine begrenzte Anzahl von Stellen zu haben, an denen Wert festgelegt werden kann, ist äußerst wertvoll. In OOP-Sprachen kann dies mithilfe von Klassen erfolgen. In "veränderlichen" funktionalen Sprachen dienen Verschlüsse demselben Zweck. Und weil wir wissen, dass Klassen = Schließungen sind , ist es sogar fraglich, ob veränderbare funktionale Sprachen ein anderes "Paradigma" als OOP sind.
Aber was ist mit unveränderlichen Sprachen? Es hat kein Problem, Variablen zu mutieren. Hier kommt das zweite Problem ins Spiel: Durch Bindungsfunktionen und Daten können diese Daten in einem gültigen Zustand gehalten werden. Stellen Sie sich vor, Sie haben eine unveränderliche Struktur für
Email
. Diese Struktur hat ein einzelnesstring
Feld. Wir haben Anforderungen, dass, wenn Sie einen Wert vom Typ haben,Email
dieses Feld eine gültige Adresse enthält. In der OOP-Kapselung kann dies leicht erreicht werden, indem dieses Feld deklariertprivate
wird, nur dieGet
Methode bereitgestellt wird undconstructor method
Dies ist nur erfolgreich, wenn die als Zeichenfolge übergebene Adresse gültig ist. Ähnliches gilt für Verschlüsse. Für eine unveränderliche Sprache müsste man sagen, dass die Struktur nur durch eine bestimmte Funktion initialisiert werden kann und eine solche Funktion fehlschlagen kann. Und mir ist keine Sprache bekannt, die diesen Kriterien entspricht (vielleicht kann mich jemand in Kommentaren aufklären).Letzte Ausgabe ist, was unter Sprache "Unterstützung" der Kapselung zu verstehen ist. Auf der einen Seite gibt es Sprachen, mit denen die Kapselung erzwungen werden kann, sodass der Code nicht kompiliert wird, wenn die Kapselung unterbrochen wird. Auf der anderen Seite bietet die Sprache möglicherweise eine Möglichkeit zur Kapselung, erzwingt sie jedoch nicht, sodass der Entwickler sie selbst erzwingen kann. Im zweiten Fall kann jede Sprache mit Strukturen und Funktionen funktionieren. Dynamische Sprachen und Haskell kommen mir in den Sinn. Und ich würde sagen, dass es nicht viele Sprachen gibt, die auf die andere Seite des Spektrums fallen. Sogar C #, das wirklich gut darin ist, die Kapselung für seine Objekte zu erzwingen, kann mithilfe von Reflexion umgangen werden. Aber zu sehen, dass in C # als massiver Code-Geruch angesehen wird, und kein vernünftiger C # -Entwickler würde dies bereitwillig tun.
quelle