Man kann oft hören, dass OOP natürlich der Art und Weise entspricht, wie Menschen über die Welt denken. Ich würde dieser Aussage jedoch stark widersprechen: Wir (oder zumindest ich) konzipieren die Welt in Bezug auf Beziehungen zwischen Dingen, denen wir begegnen, aber der Fokus von OOP liegt auf der Gestaltung einzelner Klassen und ihrer Hierarchien.
Beachten Sie, dass im täglichen Leben Beziehungen und Aktionen hauptsächlich zwischen Objekten bestehen, bei denen es sich in OOP um Instanzen nicht verwandter Klassen gehandelt hätte. Beispiele für solche Beziehungen sind: "Mein Bildschirm befindet sich oben auf der Tabelle"; "Ich (ein Mensch) sitze auf einem Stuhl"; "Ein Auto ist unterwegs"; "Ich tippe auf der Tastatur"; "Die Kaffeemaschine kocht Wasser", "der Text wird im Terminalfenster angezeigt."
Wir denken in zweiwertigen (manchmal dreiwertigen, wie zum Beispiel in "Ich gab dir Blumen") Verben, bei denen das Verb die Aktion (Relation) ist, die auf zwei Objekte wirkt, um ein Ergebnis / eine Aktion zu erzielen. Der Fokus liegt auf der Aktion, und die zwei (oder drei) [grammatikalischen] Objekte sind gleich wichtig.
Vergleichen Sie dies mit OOP, bei dem Sie zuerst ein Objekt (Substantiv) finden und es anweisen müssen, eine Aktion für ein anderes Objekt auszuführen. Die Denkweise wird von Aktionen / Verben, die mit Substantiven arbeiten, zu Substantiven, die mit Substantiven arbeiten, verschoben - es ist, als würde alles mit passiver oder reflexiver Stimme gesagt, z. B. "der Text wird im Terminalfenster angezeigt". Oder vielleicht "der Text zeichnet sich selbst im Terminalfenster".
Der Fokus wird nicht nur auf Substantive verlagert, sondern einem der Substantive (nennen wir es grammatikalisches Subjekt) wird eine höhere "Wichtigkeit" beigemessen als dem anderen (grammatikalisches Objekt). Man muss sich also entscheiden, ob man terminalWindow.show (someText) oder someText.show (terminalWindow) sagt. Aber warum Menschen mit so trivialen Entscheidungen ohne operative Konsequenzen belasten, wenn man wirklich Show meint (terminalWindow, someText)? [Konsequenzen sind betrieblich unbedeutend - in beiden Fällen wird der Text im Terminalfenster angezeigt -, können jedoch beim Entwurf von Klassenhierarchien sehr schwerwiegend sein, und eine "falsche" Auswahl kann zu verwickeltem und schwer zu wartendem Code führen.]
Ich würde daher argumentieren, dass die gängige Art, OOP (klassenbasiert, Einzelversand) durchzuführen, schwierig ist, weil sie UNNATURAL ist und nicht der Art entspricht, wie Menschen über die Welt denken. Generische Methoden von CLOS kommen meiner Denkweise näher, aber leider ist dies kein weit verbreiteter Ansatz.
Wie / warum ist es angesichts dieser Probleme dazu gekommen, dass der derzeitige Mainstream-Ansatz der OOP so populär wurde? Und was kann getan werden, um es zu entthronen?
Antworten:
OOP ist für einige Probleme unnatürlich. Also ist verfahrenstechnisch. Also ist funktionsfähig. Ich denke, OOP hat zwei Probleme, die es wirklich schwierig erscheinen lassen.
Einige Leute tun so, als wäre es der einzig wahre Weg zu programmieren, und alle anderen Paradigmen sind falsch. IMHO sollte jeder eine multiparadigmische Sprache verwenden und das beste Paradigma für das Teilproblem auswählen, an dem er gerade arbeitet. Einige Teile Ihres Codes haben einen OO-Stil. Einige werden funktionsfähig sein. Einige werden einen klaren prozeduralen Stil haben. Mit der Erfahrung wird deutlich, welches Paradigma für was am besten ist:
ein. OO ist im Allgemeinen am besten geeignet, wenn Sie Verhaltensweisen haben, die stark an den Zustand gekoppelt sind, in dem sie ausgeführt werden, und die genaue Art des Zustands ein Implementierungsdetail ist, dessen Existenz jedoch nicht ohne Weiteres abstrahiert werden kann. Beispiel: Kollektionsklassen.
b. Prozedural ist am besten geeignet, wenn Sie eine Reihe von Verhaltensweisen haben, die nicht stark an bestimmte Daten gekoppelt sind. Beispielsweise können sie primitive Datentypen verarbeiten. Es ist am einfachsten, sich das Verhalten und die Daten als separate Einheiten vorzustellen. Beispiel: Zahlencode.
c. Funktional ist am besten, wenn Sie etwas haben, das relativ einfach deklarativ zu schreiben ist, so dass das Vorhandensein eines Zustands überhaupt ein Implementierungsdetail ist, das leicht entfernt werden kann. Beispiel: Parallelität abbilden / reduzieren.
OOP zeigt im Allgemeinen seine Nützlichkeit bei großen Projekten, bei denen gut gekapselte Codeteile wirklich erforderlich sind. Dies passiert in Anfängerprojekten nicht zu oft.
quelle
IMHO ist es eine Frage des persönlichen Geschmacks und der Denkweise. Ich habe nicht viel Probleme mit OO.
IMHO ist dies nicht ganz so, obwohl es eine gemeinsame Wahrnehmung sein kann. Alan Kay, der Erfinder des Begriffs OO, betonte immer die zwischen Objekten gesendeten Botschaften und nicht die Objekte selbst. Und die Botschaften bezeichnen, zumindest für mich, Beziehungen.
Wenn es eine Beziehung zwischen Objekten gibt, sind diese per Definition miteinander verbunden. In OO können Sie dies mit einer Assoziations- / Aggregations- / Verwendungsabhängigkeit zwischen zwei Klassen ausdrücken.
Aber sie haben immer noch ihre genau definierten Rollen im Kontext: Subjekt, Objekt, Handlung usw. "Ich habe dir Blumen gegeben" oder "Du hast mir Blumen gegeben" sind nicht dasselbe (ganz zu schweigen von "Blume hat dich mir gegeben"): -)
Ich bin damit nicht einverstanden. IMHO liest sich der englische Satz "Bill, go to hell" im Programmcode natürlicher
bill.moveTo(hell)
alsmove(bill, hell)
. Und ersteres ist in der Tat analoger zu der ursprünglichen aktiven Stimme.Wiederum ist es nicht dasselbe, das Terminal zu bitten, einen Text anzuzeigen, oder den Text zu bitten, das Terminal anzuzeigen. IMHO ist es ziemlich offensichtlich, welches natürlicher ist.
Vielleicht, weil die Mehrheit der OO-Entwickler OO anders sieht als Sie?
quelle
Car
Objektstart()
nur, wenn seine Methode explizit von jemandem aufgerufen wird.Einige Programmierer finden OOD schwierig, weil diese Programmierer gerne darüber nachdenken, wie das Problem für den Computer gelöst werden kann und nicht, wie das Problem gelöst werden sollte.
Darum geht es bei OOD NICHT. Bei OOD geht es darum, herauszufinden, wie sich die Dinge verhalten und wie sie interagieren.
Der Fokus auf OOD liegt immer auf Aktionen, bei denen Aktionen das Verhalten von Objekten sind. Objekte sind nichts ohne ihr Verhalten. Die einzige Objektbeschränkung von OOD ist, dass alles von etwas erledigt werden muss.
Ich sehe den Handelnden nicht als wichtiger an als die Sache, die etwas damit angestellt hat.
Für mich ist das dasselbe mit einer anderen Schreibweise. Sie müssen sich noch entscheiden, wer duscht und wer duscht. Sobald Sie das wissen, gibt es keine Entscheidung in OOD. Windows show text -> Window.Show (Text).
Viele Dinge da draußen (besonders im Bereich der Legacy) sagen, dass es OO ist, wenn es nicht so ist. Zum Beispiel gibt es eine große Menge an C ++ - Code, der keine OOD-Figur implementiert.
OOD ist einfach, wenn Sie die Einstellung verlassen, dass Sie ein Problem für Computer lösen. Sie lösen Probleme für Dinge, die etwas bewirken.
quelle
Vielleicht verstehe ich das nicht, aber:
Als ich das erste Buch über OOP las (Anfang der 90er Jahre, Borlands dünnes Handbuch für Pascal), war ich einfach erstaunt über seine Einfachheit und sein Potenzial. (Vorher hatte ich Cobol, Fortran, Assemblersprache und anderes prähistorisches Zeug benutzt.)
Für mich ist es ziemlich klar: Ein Hund ist ein Tier, ein Tier muss fressen, mein Hund ist ein Hund, also muss er fressen ...
Andererseits ist die Programmierung selbst von Natur aus unnatürlich (dh künstlich). Die menschliche Sprache ist künstlich (beschuldigen Sie mich nicht, wir haben alle unsere Sprachen von anderen gelernt, niemand kennt die Person, die Englisch erfunden hat). Nach Ansicht einiger Wissenschaftler wird der menschliche Geist durch die Sprache geformt, die er zuerst gelernt hat.
Ich gebe zu, einige Konstrukte in modernen OO-Sprachen sind etwas umständlich, aber es ist die Entwicklung.
quelle
Eine Sache, die es mir schwer machte, war zu denken, dass es bei OOP darum ging, die Welt zu modellieren. Ich dachte, wenn ich das nicht richtig verstanden hätte, könnte mir etwas in den Arsch beißen (etwas ist entweder wahr oder nicht wahr). Ich war mir der Probleme sehr bewusst, dass das Vorgeben von allem ein Objekt oder eine Entität ist. Dies machte mich sehr vorsichtig und zuversichtlich in Bezug auf das Programmieren in OOP.
Dann habe ich SICP gelesen und bin zu dem neuen Verständnis gekommen, dass es wirklich um Datentypen und die Kontrolle des Zugriffs darauf geht. Alle Probleme, die ich weggeschmolzen hatte, weil sie auf der falschen Annahme beruhten, dass Sie in OOP die Welt modellieren.
Ich staune immer noch über die immense Schwierigkeit, die diese falsche Prämisse mir bereitet hat (und wie ich mich dazu verpflichten lasse).
quelle
Ja, OOP selbst ist sehr unnatürlich - die reale Welt besteht nicht ausschließlich aus hierarchischen Taxonomien. Einige kleine Teile davon bestehen aus diesem Zeug, und diese Teile sind die einzigen Dinge, die in Bezug auf OO angemessen ausgedrückt werden können. Alles andere lässt sich natürlich nicht in eine so triviale und eingeschränkte Denkweise einordnen. Sehen Sie sich die Naturwissenschaften an und sehen Sie, wie viele verschiedene mathematische Sprachen erfunden wurden, um die Komplexität der realen Welt auf einfachste oder zumindest nachvollziehbare Weise auszudrücken. Und fast keine von ihnen kann leicht in eine Sprache von Objekten und Nachrichten übersetzt werden.
quelle
Sie gehen von einer falschen Prämisse aus (IMO). Die Beziehungen zwischen Objekten sind wohl wichtiger als die Objekte selbst. Es sind die Beziehungen, die eine objektorientierte Programmstruktur ergeben. Vererbung, die Beziehung zwischen Klassen, ist natürlich wichtig, da die Klasse eines Objekts bestimmt, was dieses Objekt tun kann . Es sind jedoch die Beziehungen zwischen einzelnen Objekten, die bestimmen, was ein Objekt innerhalb der von der Klasse definierten Grenzen tatsächlich tut und wie sich das Programm verhält.
Das objektorientierte Paradigma kann zunächst schwierig sein, nicht weil es schwierig ist, sich neue Kategorien von Objekten auszudenken, sondern weil es schwierig ist, sich einen Graphen von Objekten vorzustellen und zu verstehen, wie die Beziehungen zwischen ihnen aussehen sollten, insbesondere wenn Sie keine haben Art und Weise, diese Beziehungen zu beschreiben. Aus diesem Grund sind Entwurfsmuster so nützlich. Bei Entwurfsmustern geht es fast ausschließlich um die Beziehungen zwischen Objekten. Muster geben uns sowohl die Bausteine, mit denen wir Objektbeziehungen auf einer höheren Ebene entwerfen können, als auch eine Sprache, mit der wir diese Beziehungen beschreiben können.
Gleiches gilt für kreative Bereiche, die in der physischen Welt arbeiten. Jeder könnte ein paar Zimmer zusammenwerfen und es ein Gebäude nennen. Die Zimmer sind vielleicht sogar komplett mit den neuesten Ausstattungen ausgestattet, aber das lässt das Gebäude nicht funktionieren. Die Aufgabe eines Architekten besteht darin, die Beziehungen zwischen diesen Räumen in Bezug auf die Anforderungen der Personen, die diese Räume nutzen, und die Umgebung des Gebäudes zu optimieren. Es ist das, was ein Gebäude sowohl aus funktionaler als auch aus ästhetischer Sicht zum Funktionieren bringt.
Wenn Sie Probleme haben, sich an OOP zu gewöhnen, sollten Sie sich überlegen, wie Ihre Objekte zusammenpassen und wie ihre Verantwortlichkeiten angeordnet sind. Wenn Sie dies noch nicht getan haben, lesen Sie über Entwurfsmuster - Sie werden wahrscheinlich feststellen, dass Sie die Muster, über die Sie gelesen haben, bereits gesehen haben. Wälder, Haine, Waldstücke und schließlich Wälder.
quelle
Dies ist nur ein Teil dessen, was mit OOP nicht stimmt.
Im Grunde werden Funktionen zu Bürgern zweiter Klasse, und das ist schlecht.
Moderne Sprachen (Ruby / Python) leiden nicht unter diesem Problem und bieten Funktionen als erstklassige Objekte sowie die Möglichkeit, Programme zu erstellen, ohne eine Klassenhierarchie zu erstellen.
quelle
OOP ist nicht schwer. Was es schwierig macht, gut zu verwenden, ist ein flaches Verständnis dessen, wofür es gut ist, wenn Programmierer zufällige Maximen hören und sie vor sich hin wiederholen, um den Segen der göttlichen Viererbande, des gesegneten Martin Fowler, oder wen auch immer sie sonst gelesen haben.
quelle
BEARBEITET
Zuallererst möchte ich sagen, dass ich OOP nie als schwierig oder schwieriger empfunden habe als andere Programmierparadigmen. Das Programmieren ist von Natur aus schwierig, da es versucht, Probleme aus der realen Welt zu lösen, und die reale Welt ist äußerst komplex. Andererseits, als ich diese Frage las, fragte ich mich: Ist OOP "natürlicher" als andere Paradigmen? Und damit effektiver?
Ich habe einmal einen Artikel über eine vergleichende Studie zwischen imperativer Programmierung (IP) und objektorientierter Programmierung (OOP) gefunden (ich wünschte, ich könnte ihn wiederfinden, um ihn als Referenz zu veröffentlichen). Sie hatten im Grunde genommen die Produktivität professioneller Programmierer gemessen, die IP und OOP in verschiedenen Projekten verwendeten, und das Ergebnis war, dass sie keine großen Unterschiede gesehen hatten. Die Behauptung lautete also, dass es keinen großen Produktivitätsunterschied zwischen den beiden Gruppen gibt und dass Erfahrung wirklich zählt.
Auf der anderen Seite behaupten Befürworter der Objektorientierung, dass während der frühen Entwicklung eines Systems OOP sogar mehr Zeit als nötig in Anspruch nehmen kann, der Code auf lange Sicht aufgrund der engen Integration von Daten und einfacher zu pflegen und zu erweitern ist Operationen.
Ich habe hauptsächlich mit OOP-Sprachen (C ++, Java) gearbeitet, aber ich habe oft das Gefühl, mit Pascal oder Ada so produktiv zu sein, obwohl ich sie nie für große Projekte ausprobiert habe.
[Schnitt]
Als ich diesen letzten Absatz genauer las, verstand ich endlich den Hauptpunkt Ihrer Frage und musste meine Antwort von Grund auf neu schreiben. :-)
Ich kenne andere OO-Vorschläge, bei denen mehrere Objekte eine Nachricht statt nur eines erhalten, dh, mehrere Objekte spielen beim Empfang einer Nachricht eine symmetrische Rolle. JA, dies scheint mir ein allgemeinerer und vielleicht natürlicherer (weniger restriktiver) OOP-Ansatz zu sein.
Andererseits kann "Mehrfachversand" mit "Einzelversand" leicht simuliert werden, und "Einzelversand" ist einfacher zu implementieren. Vielleicht ist dies ein Grund, warum "Mehrfachversand" nicht zum Mainstream geworden ist.
quelle
Hören Sie auf, nach einem exklusiven OOP-Paradigma zu suchen, und probieren Sie JavaScript aus.
Derzeit habe ich ein Schema ausgearbeitet, bei dem meine UI-Objekte unter einer ereignisgesteuerten Schnittstelle ausgeführt werden. Das heißt, ich habe etwas, das wie eine typische öffentliche Methode aussieht, die beim Abfeuern zu einer intern definierten Aktion führt. Aber wenn es ausgelöst wird, ist das, was wirklich passiert, dass ich ein Ereignis für das Objekt selbst auslöse und ein vordefinierter Handler in diesem Objekt reagiert. Dieses Ereignis und das Ereignisobjekt, an das Sie Eigenschaften anhängen können, die an einen anderen Listener übergeben werden, können von allen Benutzern abgehört werden, die das Abhören möchten. Sie können direkt auf das Objekt oder allgemein auf diesen Ereignistyp hören (Ereignisse werden auch für ein generisches Objekt ausgelöst, das von allen werkseitig erstellten Objekten gehört werden kann). Jetzt habe ich zum Beispiel ein Kombinationsfeld, in dem Sie ein neues Element aus der Dropdown-Liste auswählen können.
Wenn Sie möchten (und ich war überrascht, dass ich dies normalerweise nicht möchte - es ist ein Problem der Lesbarkeit, wenn Sie nicht sehen können, woher das Ereignis kommt), können Sie eine vollständige Objektentkopplung durchführen und den Kontext über ein übergebenes Ereignisobjekt herstellen. Unabhängig davon können Sie Single-Dispatch-Vorgängen immer noch ausweichen, indem Sie mehrere Responder registrieren.
Aber ich mache das nicht mit OOP alleine und JS ist nach einigen Definitionen nicht einmal 'richtig' OOP, was ich komisch finde. Richtig, für die höheren Ebenen der App-Entwicklung meiner Meinung nach, ist es die Macht, das Paradigma auf das zu biegen, was für Ihre Situation funktioniert, und wir können Klassen ganz gut emulieren, wenn es uns wichtig ist. Aber in diesem Fall mische ich Aspekte der Funktionalität (Weitergabe von Handlern) mit OOP.
Noch wichtiger ist, was ich habe, fühlt sich ziemlich mächtig an. Ich denke nicht daran, dass ein Objekt auf ein anderes wirkt. Ich entscheide im Grunde genommen, worauf es den Objekten ankommt, gebe ihnen die Werkzeuge, die sie zum Sortieren der Dinge benötigen, lege sie einfach in einen Mixer und lasse sie aufeinander reagieren.
Ich schätze, ich sage Folgendes: Es ist keine switch-Anweisung, sondern ein Problem. Es ist Mix and Match. Das Problem sind Sprachen und Modeerscheinungen, die Sie glauben lassen wollen, dass es eine Sache über alles ist. Wie kann zum Beispiel ein Java-Junior-Entwickler OOP wirklich schätzen, wenn er denkt, dass er es standardmäßig immer richtig macht?
quelle
Die Art, wie es mir erklärt wurde, war mit einem Toaster und einem Auto. Beide haben Federn, du hättest also ein "Feder" -Objekt und sie hätten unterschiedliche Größen, Stärken und was auch immer, aber sie wären beide "Federn" und würden dann diese Metapher auf das Auto übertragen, wenn du viele Räder hättest (Räder natürlich plus Lenkrad, ect) und das ergab sehr viel Sinn.
Sie können sich das Programm dann als eine Liste von Objekten vorstellen, und es ist viel einfacher zu visualisieren als "Es ist eine Liste von Dingen, die Dinge tun, also ist es nicht so wie die Liste von Anweisungen, die Sie zuvor gesehen haben".
Ich denke, das eigentliche Problem bei OOP ist, wie es den Leuten erklärt wird. Oft (in meinen Uni-Klassen) sehe ich, wie es erklärt wird, indem ich sage, "es geht um viele Klassen, die kleine Dinge tun, und man kann daraus Objekte erstellen", und das alles verwirrt viele Leute, weil es verwendet, was im Wesentlichen abstrakt ist Begriffe, um diese Konzepte zu erklären, und nicht konkrete Ideen, die Menschen im Alter von 5 Jahren beim Spielen mit Lego verstanden haben.
quelle
Es ist die natürliche Art, die Welt durch Kategorisierung zu betrachten. Das ist mehr oder weniger das, worum es bei OO geht. OOP ist schwierig, weil das Programmieren schwierig ist.
quelle
it doesn't matter
. Alles, was einen Vor- und Nachnamen hat, ist eine Person in jedem Programm, die sich nur um Menschen kümmert. Für jedes Programm, das keine Kenntnisse von Menschen oder Nicht-Menschen hat, ist es eineIHasNameAndSurname
. Objekte müssen nur das vorliegende Problem lösen.Ich denke, einige der Schwierigkeiten treten auf, wenn Leute versuchen, OOP zu verwenden, um die Realität darzustellen. Jeder weiß, dass ein Auto vier Räder und einen Motor hat. Jeder weiß , dass die Autos können
Start()
,Move()
undSoundHorn()
.Ein Licht ging in meinem Kopf an, als mir klar wurde, dass ich aufhören sollte, dies die ganze Zeit zu versuchen. Ein Objekt ist nicht das, womit es einen Namen teilt. Ein Objekt ist (dh sollte) eine ausreichend detaillierte Partition von Daten, die für den Umfang des Problems relevant sind. Es
ought
muss genau das geben, was die Lösung des Problems braucht, nicht mehr und nicht weniger. Wenn ein Objekt, das für ein bestimmtes Verhalten verantwortlich ist, mehr Codezeilen als dasselbe Verhalten zur Aufgabe eines nebulösen Dritten macht (manche nennen es möglicherweise einen "Poltergeist"), verdient der Poltergeist seine Chips.quelle
Um die Komplexität zu bewältigen, müssen wir die Funktionalität in Module gruppieren, und dies ist im Allgemeinen ein schwieriges Problem. Es ist wie das alte Sprichwort über den Kapitalismus: OOP ist das schlechteste System für die Organisation von Software, abgesehen von allem, was wir bisher versucht haben.
Der Grund, warum wir Interaktionen innerhalb der Substantive gruppieren, obwohl es häufig Unklarheiten darüber gibt, mit welchem der beiden Substantive sie gruppiert werden sollen, ist, dass die Anzahl der Substantive sich zufällig auf handhabbare Klassen auswirkt, während die Gruppierung nach Verben in der Regel zu beidem führt sehr kleine gruppen wie einmalig oder sehr große gruppen für eine funktion wie show . Wiederverwendungskonzepte wie Vererbung funktionieren auch viel einfacher, wenn sie nach Substantiven gruppiert werden.
Auch die Frage, ob die Präsentation mit dem Fenster oder dem Text gezeigt werden soll, ist in der Praxis fast immer viel klarer als in der Theorie. Zum Beispiel fast all GUI - Toolkits Gruppe hinzufügen mit dem Behälter, sondern zeigt mit dem Widget. Wenn Sie versuchen, Code in die andere Richtung zu schreiben, wird der Grund ziemlich schnell offensichtlich, auch wenn die beiden Methoden, wenn Sie abstrakt darüber nachdenken, austauschbar erscheinen.
quelle
Nein . Es gibt verschiedene Möglichkeiten, ein Problem mithilfe der Programmierung zu lösen: funktional, prozedural, logisch, OOP usw.
In der realen Welt verwenden die Menschen manchmal das funktionale Paradigma und manchmal das prozedurale Paradigma und so weiter. Und manchmal haben wir verwechselt. Und schließlich repräsentieren wir sie als einen bestimmten Stil oder ein bestimmtes Paradigma der Programmierung.
Es gibt auch das in LISP verwendete Paradigma "Alles ist eine Liste oder ein Element". Ich möchte etwas anderes erwähnen als funktionale Programmierung . PHP verwendet das in assoziativen Arrays.
OOP- und "Everything is a list or item" -Paradigmen werden als zwei der NATÜRLICHEREN Programmierstile betrachtet, an die ich mich in einigen Klassen der künstlichen Intelligenz erinnere.
Klingt für mich seltsam, "OOP ist nicht natürlich", vielleicht ist die Art und Weise, wie Sie lernen oder wie Sie über OOP unterrichtet wurden, falsch, aber nicht OOP selbst.
quelle
OOP wurde populär, weil es Tools bietet, mit denen Sie Ihr Programm auf einer höheren Abstraktionsebene organisieren können als in den bekannten Verfahrenssprachen, die davor standen. Es war auch relativ einfach, eine Sprache zu erstellen, die innerhalb der Methoden eine prozedurale Struktur und eine sie umgebende objektorientierte Struktur aufwies. So konnten Programmierer, die bereits wissen, wie man prozedural programmiert, nacheinander die OO-Prinzipien aufgreifen. Dies führte auch zu vielen OO-in-Name-Programmen, bei denen es sich um prozedurale Programme handelte, die in eine oder zwei Klassen eingeschlossen waren.
Um OO zu entthronen, erstellen Sie eine Sprache, die es einfach macht, schrittweise von dem, was die meisten Programmierer heute kennen (meistens prozedural, mit ein wenig OO), zu Ihrem bevorzugten Paradigma überzugehen. Stellen Sie sicher, dass es praktische APIs für allgemeine Aufgaben bietet, und fördern Sie es gut. Die Leute werden in Kürze X-in-Name-Programme in Ihrer Sprache erstellen. Dann kann man davon ausgehen, dass es Jahre und Jahre dauert, bis die Leute gut darin sind, tatsächlich X zu machen.
quelle
Ich denke, die OOP- und OOP-Sprachen haben auch Probleme.
Wenn Sie es richtig verstehen, handelt es sich bei OOP um Black Boxes (Objekte), auf denen sich Drucktasten befinden, die gedrückt werden können (Methoden). Klassen sind nur da, um diese Blackboxen zu organisieren.
Ein Problem ist, wenn der Programmierer die Druckknöpfe auf das falsche Objekt legt. Das Terminal kann keinen Text auf sich selbst anzeigen, der Text kann sich nicht auf dem Terminal anzeigen. Die Fenstermanagerkomponente des Betriebssystems, die dies ausführen kann. Terminalfenster und -text sind nur eine passive Einheit. Aber wenn wir so denken, erkennen wir, dass die meisten Entitäten passive Dinge sind und wir nur sehr wenige Objekte haben, die tatsächlich etwas tun (oder einfach nur eines: den Computer ). In der Tat, wenn Sie C verwenden, organisieren Sie es in Module, diese Module repräsentieren die wenigen Objekte.
Ein weiterer Punkt ist, dass der Computer die Anweisungen nur nacheinander ausführt. Nehmen wir an, Sie haben ein
VCR
und einTelevision
Objekt. Wie würden Sie ein Video abspielen? Sie schreiben wahrscheinlich so etwas:Dies wäre so einfach, aber Sie würden mindestens 3 Prozessoren ( oder Prozesse ) dafür benötigen : einer spielt die Rolle von Ihnen, der zweite ist der Videorecorder, der dritte ist der Fernseher. Aber normalerweise hast du nur einen Kern (zumindest nicht genug für alle deine Objekte). Im College haben viele meiner Klassenkameraden nicht verstanden, warum die GUI einfriert, wenn ein Druckknopf eine teure Operation ausführt.
Daher denke ich, dass ein objektorientiertes Design die Welt recht gut beschreibt, aber es ist nicht die beste Abstraktion für den Computer.
quelle
Werfen Sie einen Blick auf DCI (Daten, Kontext und Interaktion), die vom Erfinder des MVC-Musters erfunden wurden.
Das Ziel von DCI ist (aus Wikipedia zitiert):
Hier ist ein guter Artikel der Autoren und hier ist eine kleine Beispielimplementierung (.NET), wenn Sie Code sehen möchten. Es ist viel einfacher als es sich anhört und fühlt sich sehr natürlich an.
quelle
Da es seit Jahrzehnten in Büchern und anderswo evangelisiert wird, bin ich auch nicht damit einverstanden. Trotzdem denke ich, dass Nygaard und Dahl das so ausgedrückt haben, und ich denke, sie haben sich darauf konzentriert, wie einfach es war, Simulationen im Vergleich zu den Alternativen der Zeit zu entwerfen.
Diese Behauptung betritt ein vernünftiges Territorium, da die gängigen Missverständnisse in Bezug auf OOP bestehen und die Definition von OO empfindlich ist. Ich bin seit mehr als zehn Jahren in diesem Bereich tätig und arbeite sowohl in der Industrie als auch in der akademischen Forschung mit Prog. Ich kann Ihnen sagen, dass ich viele Jahre damit verbracht habe, "Mainstream OO" zu verlernen, weil ich bemerkte, wie unterschiedlich (und minderwertig) es von dem ist, was die früheren Schöpfer anstrebten. Für eine moderne, aktuelle Behandlung des Themas verweise ich auf die jüngsten Bemühungen von W. Cook:
"Ein Vorschlag für vereinfachte, moderne Definitionen von" Objekt "und" objektorientiert " http://wcook.blogspot.com.br/2012/07/proposal-for-simplified-modern.html
Vielleicht aus demselben Grund, aus dem QWERTY-Tastaturen populär wurden, oder aus demselben Grund, aus dem das DOS-Betriebssystem populär wurde. Die Dinge werden trotz ihrer Eigenschaften nur mit beliebten Fahrzeugen gefahren und selbst populär. Und manchmal werden ähnliche, aber schlechtere Versionen von etwas als die eigentliche Sache angesehen.
Schreiben Sie ein Programm mit einem überlegenen Ansatz. Schreiben Sie dasselbe Programm mit einem OO-Ansatz. Zeigen Sie, dass Ersteres in jeder Hinsicht bessere Eigenschaften aufweist als Letzteres (sowohl die Eigenschaften des Systems selbst als auch die technischen Eigenschaften). Zeigen Sie, dass das ausgewählte Programm relevant ist und der vorgeschlagene Ansatz die hohe Qualität der Eigenschaften beibehält, wenn er auf andere Arten von Programmen angewendet wird. Seien Sie bei Ihrer Analyse streng und verwenden Sie bei Bedarf präzise und akzeptierte Definitionen.
Teilen Sie uns abschließend Ihre Erkenntnisse mit.
quelle
Nehmen wir Java: Objekte sind eine Art Abstraktionsengpass, die meisten "Dinge" sind entweder reine Unterkomponenten von Objekten oder verwenden Objekte als Unterkomponenten. Objekte müssen für eine ganze Abstraktionsschicht zwischen diesen beiden Arten von Dingen vielseitig genug sein - Mehrzweck bedeutet, dass es keine einzige Metapher gibt, die sie verkörpern. Insbesondere macht Java Objekte (& Klassen) zur einzigen Ebene, über die Sie Code aufrufen / versenden. Diese Menge an Dingen, die Objekte verkörpern, macht sie offen gesagt viel zu komplex. Jede nützliche Beschreibung muss auf eine spezielle oder eingeschränkte Form beschränkt sein.
Die Vererbungs- und Schnittstellenhierarchien sind "Dinge", die Objekte als Unterkomponenten verwenden. Dies ist eine spezielle Methode zur Beschreibung von Objekten, keine Methode, um ein allgemeines Verständnis von Objekten herzuleiten.
Man kann sagen, dass "Objekte" viele Dinge haben oder sein, weil sie eine Mehrzweckabstraktion sind, die in einer "OO-Sprache" mehr oder weniger universell ist. Wenn sie verwendet werden, um einen lokalen veränderlichen Zustand zu enthalten oder auf einen Zustand der Außenwelt zuzugreifen, ähneln sie sehr einem "Nomen".
Im Gegensatz dazu sieht ein Objekt, das einen Prozess darstellt, z. B. "Verschlüsseln" oder "Komprimieren" oder "Sortieren", wie ein "Verb" aus.
Einige Objekte werden für ihre Rolle als Namespace verwendet, z. B. um "statische" Funktionen in Java zu platzieren.
Ich bin geneigt, dem Argument zuzustimmen, dass Java bei Objektmethodenaufrufen mit Dispatch für das Objekt zu umfangreich ist. Dies liegt wahrscheinlich daran, dass ich Haskells Typklassen für die Versandsteuerung bevorzuge. Dies ist eine Versandbeschränkung und eine Funktion von Java, jedoch nicht die meisten Sprachen oder sogar die meisten OO-Sprachen.
quelle
Ich habe viele Online-Debatten über OOP miterlebt und daran teilgenommen. Die Befürworter von OOP wissen normalerweise nicht, wie man richtigen Prozedurcode schreibt. Es ist möglich, sehr modularen Prozedurcode zu schreiben. Es ist möglich, Code und Daten zu trennen und sicherzustellen, dass Funktionen nur in ihren eigenen Datenspeicher schreiben können. Es ist möglich, das Konzept der Vererbung mithilfe von Prozedurcode zu implementieren. Noch wichtiger ist, dass der prozedurale Code schlanker, schneller und einfacher zu debuggen ist.
Wenn Sie Single-File-Module mit strengen Namenskonventionen erstellen, ist der prozedurale Code einfacher zu schreiben und zu pflegen als OO, und das gleiche oder mehr und schneller. Und vergessen Sie nicht, dass die Ausführung Ihrer Anwendung immer prozedural ist, unabhängig davon, wie viele Klassen in Ihrem Skript enthalten sind.
Dann haben Sie das Problem von Sprachen wie PHP, die nicht wirklich objektorientiert sind und sich auf Hacks verlassen, um Dinge wie Mehrfachvererbung zu fälschen. Die großen Schüsse, die die Richtung der Sprache beeinflussen, haben PHP zu einem Flickenteppich inkonsistenter Regeln gemacht, die zu groß für das geworden sind, was es ursprünglich beabsichtigte. Wenn ich sehe, dass Entwickler umfangreiche Vorlagenklassen für eine prozedurale Vorlagensprache schreiben, muss ich lächeln.
Wenn Sie richtig geschriebenen OO-Code mit schlecht geschriebenem Prozedurcode vergleichen, kommen Sie immer zu einer falschen Schlussfolgerung. Sehr wenige Projekte erfordern ein objektorientiertes Design. Wenn Sie IBM sind und ein großes Projekt verwalten, das mehrere Entwickler jahrelang warten müssen, entscheiden Sie sich für objektorientiert. Wenn Sie einen kleinen Blog oder eine Shopping-Website für einen Kunden schreiben, denken Sie zweimal darüber nach.
Zur Beantwortung der ursprünglichen Frage ist OOP schwierig, da es keine realen Programmierprobleme löst, ohne auf Lösungen zurückzugreifen, die hundertmal komplizierter sind, als sie sein sollten. Eine der wirksamsten Lösungen für viele Programmierprobleme ist der umsichtige Umgang mit globalen Daten. Doch die New-Wave-Hochschulabsolventen werden Ihnen sagen, dass es ein großes Nein-Nein ist. Global verfügbare Daten sind nur dann gefährlich, wenn Sie ein ungeschickter Programmierer sind. Wenn Sie über strenge Regeln und korrekte Namenskonventionen verfügen, können Sie es vermeiden, dass alle Ihre Daten global sind.
Es sollte für jeden objektorientierten Programmierer eine obligatorische Anforderung sein, zu wissen, wie eine Schachspielanwendung in Assembler für einen maximal verfügbaren Speicher von 16 KB geschrieben wird. Sie würden dann lernen, wie man das Fett trimmt, die Faulheit schneidet und geniale Lösungen generiert.
quelle