Erfüllt OOP das Versprechen der Wiederverwendung von Code? Welche Alternativen gibt es, um die Wiederverwendung von Code zu erreichen?


56

Das vielleicht größte Versprechen bei der Verwendung eines objektorientierten Paradigmas ist die Wiederverwendung von Code. Einige bestreiten, dass dies erreicht wurde. Warum wurde es (nicht) erreicht?

Wird Code nach OOP wiederverwendet, um die Produktivität von Projekten zu steigern?

Oder überschaubarer? Oder einfacher zu warten? Oder mit mehr Qualität?

Wahrscheinlich sind wir uns alle einig, dass die Wiederverwendung von Code eine gute Sache ist, aber es gibt mehrere Möglichkeiten, um dieses Ziel zu erreichen. Die Frage betrifft die von OOP angebotene Methode zur Wiederverwendung von Code. War es eine gute Sache? Gibt es bessere Methoden zur Wiederverwendung von Code als Objektorientierung, Unterklassifizierung, Polymorphismus usw.? Welche Wege sind besser? Warum ?

Teilen Sie uns Ihre Erfahrungen mit der Wiederverwendung von OOP oder anderen Paradigmen mit.



7
Es ist komplementär, nicht exakt dupliziert. Ich habe es umformuliert, um den Unterschied besser zu verstehen.
Maniero

Wenn Sie abstimmen können und denken, dass dies eine nützliche Frage ist, oder wenn Sie unten nützliche Antworten haben, stimmen Sie ab. StackExchange-Sites benötigen Stimmen, um eine gute Community aufzubauen. Sie können 30 Stimmen pro Tag abgeben, verschwenden Sie sie nicht. Speziell Anwender mit hohem Ansehen und niedriger Auszählung der Stimmen gegeben lesen Sie bitte: meta.programmers.stackexchange.com/questions/393/...
Maniero


2
@j_random_hacker: lies die Kommentare.
Maniero

Antworten:


34

Die Wiederverwendung von Code ist eine ziemlich gute Idee. Kein großer .

Ich habe eine Perspektive aus ungefähr 30 Jahren Softwareentwicklung, die versucht, "wiederzuverwenden".

Ich begann in den 80er Jahren, die Wiederverwendung von Code als Forschungsthema zu untersuchen, nachdem ich herausgefunden hatte, dass ich das Design eines Betriebssystems, das ich in den frühen 70er Jahren gebaut hatte, für ein anderes Betriebssystem, das ich in den späten 70er Jahren gebaut hatte, wiederverwendet hatte.

Der gute Teil der Wiederverwendung von Code ist die Möglichkeit, manchmal ehrlichen Code wiederzuverwenden. Aber die Welt ist voller Code. Wie finden Sie, was Sie wollen? Folgendes nenne ich den Fluch der Wiederverwendung :

Ich bin der Weihnachtsmann (ok Open Source) und habe eine Tüte mit 1 Milliarde Softwarekomponenten. Sie können einen von ihnen haben.

Viel Glück bei der Auswahl.

Um das Wiederverwendungsproblem gut zu lösen:

  • Der Wiederverwender muss irgendwie spezifizieren, was er benötigt (Funktionalität, Leistung, Zielsprache, Umgebungsannahmen, ...)
  • Es muss eine Bibliothek mit "wiederverwendbarem" Code geben, die auf verschiedene Weise nach diesen potenziellen Kriterien indiziert wurde
  • Es muss einen Mechanismus geben, mit dem Kandidatenelemente ausgewählt werden können (bei einer Milliarde Elementen kann man nicht alle persönlich betrachten).
  • Es muss eine Möglichkeit geben, zu charakterisieren, wie weit die ausgewählten Kandidaten von der Spezifikation entfernt sind
  • Es sollte einen regulären Prozess geben, der es dem Wiederverwender ermöglicht, den ausgewählten wiederverwendbaren Code zu ändern (hier ist der größte Beitrag von OOP: Sie können eine vorhandene Komponente / ein Objekt bearbeiten, indem Sie die Slots überschreiben. OOP bietet keine andere Hilfe.)
  • All dies muss natürlich billiger sein, als es einfach neu zu codieren

Im Laufe der Jahre wurde vor allem festgestellt, dass Code für die Wiederverwendung zu diesem Zweck entwickelt werden muss oder zu viele implizite Annahmen enthält. Die erfolgreichsten Bibliotheken zur Wiederverwendung von Code waren tatsächlich recht klein. Bibliotheken und Frameworks sind vermutlich "wiederverwendbarer" Code und äußerst erfolgreich. Java und C # sind nicht deshalb erfolgreich, weil sie ziemlich gute Computersprachen sind, sondern weil sie über riesige, gut gestaltete, implementierte und dokumentierte Bibliotheken verfügen. Aber die Leute schauen sich den Quellcode in den Bibliotheken nicht an. Sie rufen einfach eine gut dokumentierte API auf (die allgemein verwendbar ist).

Was die Wiederverwendung von Code nicht getan hat (weder OOP noch OOP), ist die Verbesserung unserer Fähigkeit, Systeme zu codieren.

Ich denke, der Hauptfehler ist, dass jede Art der Wiederverwendung von Code grundsätzlich eingeschränkt ist, da in Code zu viele Annahmen eingebaut sind . Wenn Sie den Code winzig machen, minimieren Sie die Annahmen, aber die Kosten für das Erstellen von Grund auf sind nicht sehr hoch und die Wiederverwendungsgewinne sind nicht effektiv. Wenn Sie die Codestücke groß machen, sind sie in einem neuen Kontext so gut wie unbrauchbar. Wie Gulliver sind sie mit einer Million winziger Schnüre an den Strand gebunden, und Sie können es sich einfach nicht leisten, sie alle zu schneiden.

Woran wir arbeiten sollten, ist die Wiederverwendung von Wissen, um Code zu konstruieren . Wenn wir dies tun können, können wir dieses Wissen anwenden, um den Code zu konstruieren, den wir benötigen, und dabei die aktuellen Annahmen berücksichtigen.

Dazu benötigt man immer noch die gleiche Spezifikationsfähigkeit, um Softwarekomponenten zu charakterisieren (man muss immer noch sagen, was man will!). Aber dann wenden Sie dieses Konstruktionswissen auf die Spezifikationen an, um den gewünschten Code zu generieren .

Als Community sind wir noch nicht sehr gut darin. Aber die Leute machen es die ganze Zeit; warum können wir es nicht automatisieren? Es gibt viel Forschung, und dies zeigt, dass dies unter vielen Umständen möglich ist.

Ein Schlüsselelement hierfür sind mechanische Werkzeuge zur Aufnahme von "Komponentenbeschreibungen" (dies sind nur formale Dokumente, die wie Programmiersprachen analysiert werden können) und zur Anwendung von Programmtransformationen auf diese.

Compiler machen das bereits: -} Und sie sind wirklich gut in der Klasse von Problemen, die sie angehen.

UML-Modelle mit Codegenerierung sind ein Versuch, dies zu tun. Kein sehr guter Versuch; In den meisten UML-Modellen heißt es so ziemlich "Ich habe Daten, die so aussehen". Ziemlich schwer, ein echtes Programm zu generieren, wenn die Funktionalität weggelassen wird.

Ich versuche, praktische Programmtransformationssysteme zu erstellen, ein Tool namens DMS . Wir waren ziemlich abgelenkt, als wir Programmtransformationen nicht so sehr auf abstrakte Spezifikationen angewendet haben, um Code zu generieren, sondern auf Legacy-Code, um ihn zu bereinigen. (Dies sind die gleichen Probleme in der Zusammenfassung!). (Solche Werkzeuge zu bauen kostet viel Zeit; ich mache das seit 15 Jahren und in der Zwischenzeit muss man essen).

DMS verfügt jedoch über die beiden oben beschriebenen Schlüsseleigenschaften: Die Fähigkeit, beliebige formale Spezifikationen zu verarbeiten und das Wissen über die Codegenerierung als Transformation zu erfassen und bei Bedarf anzuwenden. Und bemerkenswerterweise generieren wir in einigen speziellen Fällen einen interessanten Code aus Spezifikationen. DMS wird größtenteils aus sich selbst erstellt, um seine Implementierung zu generieren. Das hat für uns zumindest das Versprechen der (Wissens-) Wiederverwendung erfüllt: äußerst signifikante Produktivitätssteigerungen. Ich habe ein Team von ungefähr 7 technischen Leuten; Wir haben wahrscheinlich 1-2 MSLOC "Spezifikationen" für DMS geschrieben, haben aber 10MSLOC generierten Code.

Zusammenfassung: Die Wiederverwendung von Generationswissen ist der Gewinn, nicht die Wiederverwendung von Code .


4
IMHO, die beste Antwort. Das Wichtigste ist die Wiederverwendung von Kenntnissen / Ideen, nicht der Code.
Kravemir

4
Mostly what has been discovered over the years is that for code to be reusable, it sort of has to be designed for that purpose, or it contains too many implicit assumptions.Ich bin zu einem ähnlichen Schluss gekommen, konnte es aber nicht so prägnant ausdrücken.
biziclop

36

Die Wiederverwendung von Code erfolgt in OOP, aber auch in der funktionalen Programmierung. Jedes Mal, wenn Sie einen Codeblock nehmen und ihn für den Rest Ihres Codes aufrufbar machen, sodass Sie diese Funktionalität an anderer Stelle verwenden können, wird der Code wiederverwendet.

Diese Art der Wiederverwendung von Code macht den Code auch einfacher zu verwalten, da durch das Ändern dieses einen aufrufbaren Blocks alle Stellen geändert werden, an denen er aufgerufen wird. Ich würde sagen, dass dieses Ergebnis auch die Qualität und Lesbarkeit erhöht.

Ich bin nicht sicher, ob OOP einfach da ist, um die Wiederverwendung von Code zu ermöglichen. Ich betrachte OOP eher als eine Möglichkeit, mit Objekten zu interagieren und die Details der Datenstruktur zu abstrahieren.

Aus Wikpedia:

Objektorientierte Programmierung hat Wurzeln, die bis in die 1960er Jahre zurückreichen. Da Hard- und Software immer komplexer wurden, wurde die Verwaltbarkeit häufig zu einem Problem. Die Forscher untersuchten Möglichkeiten zur Aufrechterhaltung der Softwarequalität und entwickelten eine objektorientierte Programmierung, um häufig auftretende Probleme zu lösen, indem sie diskrete, wiederverwendbare Einheiten der Programmierlogik stark betonten. Die Technologie konzentriert sich eher auf Daten als auf Prozesse, wobei Programme aus autarken Modulen ("Klassen") bestehen, von denen jede Instanz ("Objekte") alle Informationen enthält, die zur Manipulation ihrer eigenen Datenstruktur ("Mitglieder") erforderlich sind. Dies steht im Gegensatz zu der seit vielen Jahren vorherrschenden modularen Programmierung, bei der die Funktion eines Moduls im Vordergrund stand und nicht nur die Daten, sondern auch die Wiederverwendung von Code. und autarke wiederverwendbare Einheiten der Programmierlogik, die die Zusammenarbeit durch die Verwendung verknüpfter Module (Subroutinen) ermöglichen. Dieser konventionellere Ansatz, der immer noch besteht, tendiert dazu, Daten und Verhalten getrennt zu betrachten.


9
+1 Funktionsprogrammierung kann der Weg für die Wiederverwendung von Code sein.
Jonas

1
@ Matthieu M .: Nun, wie wiederverwendbar ist double sqrt (double x)? Reine Funktionen sind der Archetyp der Wiederverwendbarkeit.
Joonas Pulakka

3
@Joonas: double sqrt(double x), float sqrt(float x), int sqrt(int x)können Sie eine Menge von ihnen, während sie mit einer generischen Programmiersprache definieren Sie müßten Number sqrt(Number x)und mit ihr geschehen.
Matthieu M.

1
@Matthieu M .: In der Tat reduzieren Generika die Codereplikation, so dass sie "wiederverwendbarer" ist, ja. Ich denke jedoch, der wahre Schlüssel zur Wiederverwendbarkeit besteht darin, einfache, kleine, vernünftige und reine Funktionen zu definieren (dies ist die "funktionale Programmierrichtung") und sie weiterzugeben, was in C möglich ist. Es geht mehr um den allgemeinen Programmierstil als darum über die Fähigkeiten der Sprache selbst.
Joonas Pulakka

1
@Joonas: Ah, ich hatte das reine Wort verpasst , Sie haben Recht, kleine reine Funktionen zu komponieren ist einfach großartig, und sogar C bietet Zeiger auf Funktionen dafür.
Matthieu M.

15

Ja und nein

Die Wiederverwendung von Code ist ein Sammelbegriff für viele verschiedene Aktivitäten.

  1. Wiederverwendung von Code in einem einzelnen Projekt. OO ist dafür perfekt geeignet. Eine gut gestaltete Anwendung hat die Beziehungen der modellierten Welt genau abgebildet, wodurch doppelter Code so weit wie möglich und ratsam beseitigt wird. Sie können jedoch argumentieren, dass Pre-OO-Technologien dasselbe erreichen könnten, was wahr ist, aber OO ist in vielerlei Hinsicht praktischer.
  2. Bibliotheken von Drittanbietern Dies scheint mit oder ohne OO gleich gut zu funktionieren.
  3. Wiederverwendung von Code für verschiedene Zwecke Das größte Versprechen von OO für die Wiederverwendung von Code war, dass Code, der einmal für eine Anwendung geschrieben wurde, später für eine andere Anwendung wiederverwendet werden kann, für die er nicht speziell entwickelt wurde. Dies war der letzte Schrei, als der Begriff des OO durch die Türen höherer Verwaltungsbüros drang und OO ihn überhaupt nicht erreichte. Es stellte sich heraus, dass dieser Zweck ein entscheidender Aspekt des OO-Designs war (und möglicherweise der gesamte Verfahrenscode, aber das ist nur meine Theorie), und Versuche, Code neu zu verwenden, endeten mit Wartungskatastrophen. (Die bekannten Antimuster eines alten Frameworks, das niemand zu modifizieren wagt, und sein Freund, die leicht unterschiedlichen Frameworks für jede App, stammen normalerweise von hier.)

13

Ich würde eine lange Antwort posten, aber warum? Udi Dahan erklärt es viel besser als ich.

http://www.udidahan.com/2009/06/07/the-fallacy-of-reuse/

Hier ist der Beginn des Beitrags:

Diese Branche beschäftigt sich mit der Wiederverwendung.

Es gibt die Überzeugung, dass alles besser wäre, wenn wir einfach mehr Code wiederverwenden würden.

Einige gehen sogar so weit zu behaupten, dass der ganze Punkt der Objektorientierung die Wiederverwendung war - es war nicht so, die Verkapselung war die große Sache. Nach dieser Komponentenorientierung sollte die Wiederverwendung stattfinden. Anscheinend hat das auch nicht so gut geklappt, denn hier setzen wir jetzt wieder auf Serviceorientierung.

Es wurden ganze Musterbücher darüber geschrieben, wie mit der Orientierung des Tages eine Wiederverwendung erreicht werden kann. Um dies zu erreichen, wurden Dienste in jeder Hinsicht klassifiziert, von Entitätsdiensten und Aktivitätsdiensten bis hin zu Prozessdiensten und Orchestrierungsdiensten. Das Erstellen von Diensten wurde als Schlüssel zur Wiederverwendung und zum Erstellen wiederverwendbarer Dienste angepriesen.

Ich könnte Sie genauso gut in das schmutzige kleine Geheimnis einweihen:

Wiederverwendung ist ein Irrtum


4
-1. Herr Dahan ist mit Strohmännern beschäftigt; Niemand verwendet nicht generischen Code ernsthaft wieder, wie er dies impliziert, und wenn Sie dieses Argument aus seinem Artikel entfernen, ist er in der Tat dafür oder verwendet Code entsprechend wieder .
Steven A. Lowe

3
@ Steven A. Lowe Nun, ich wünschte, das wäre wahr. Ich wünschte, ich hätte Ihr Glück gehabt, weil ich die Wiederverwendung von Code in der nicht generischen Form gesehen habe. Es war nicht hübsch.
Tony

1
Ich bin sicher, es war nicht - aber waren sie ernst ? dilbert.com/strips/comic/1996-01-31
Steven A. Lowe

1
Einverstanden ist, dass die Kosten für die Wiederverwendung von Code sehr hoch sind. Sie zahlen sich nur dann aus, wenn Sie sich auf der Skala der Java- oder .NET-Basisklassen bewegen. Siehe youtube.com/watch?v=aAb7hSCtvGw
Andomar

13

Ich stimme Chris zu, funktionale Programmierung ist eine gute Möglichkeit, Code wiederzuverwenden.

Viele Programme haben immer wiederkehrende Codestrukturen. Zu diesem Zweck werden in der OOP-Welt einige Entwurfsmuster verwendet. Dies kann jedoch durch rekursive Funktionen und Mustervergleiche in funktionalen Programmiersprachen erreicht werden. Weitere Informationen hierzu finden Sie im ersten Kapitel der funktionalen Programmierung in der realen Welt .

Ich denke, dass eine tiefe Vererbung von OOP in vielen Fällen irreführend sein kann. Sie haben eine Klasse und viele der eng verwandten Methoden sind in verschiedenen Dateien implementiert. Wie Joe Armstrong über OOP sagte:

Das Problem mit objektorientierten Sprachen ist, dass sie all diese impliziten Umgebungen haben, die sie mit sich herumtragen. Du wolltest eine Banane, aber du hast einen Gorilla bekommen, der die Banane und den gesamten Dschungel hält.

Hohe Auftrag Funktionen sind auch sehr nützlich , wenn es darum geht , die Wiederverwendung zB codieren , mapund foldrdas ist die Grundlage für Googles MapReduce .

Die asynchrone Nachrichtenübermittlung ist auch ein guter Weg, um komplexe Software zu organisieren, und einige Computerwissenschaftler geben an, dass angenommen wurde, dass Objekte asynchron miteinander kommunizieren, wie im Tell, fragen Sie nicht nach dem OOP-Prinzip. Weitere Informationen hierzu finden Sie in Objektorientierte Programmierung: Der falsche Weg? wo Joe Armstrong zitiert wird:

Ich begann mich zu fragen, was objektorientierte Programmierung ist, und ich dachte, Erlang sei nicht objektorientiert, sondern eine funktionierende Programmiersprache. Dann sagte mein Doktorvater: "Aber Sie irren sich, Erlang ist extrem objektorientiert." Er sagte, dass objektorientierte Sprachen nicht objektorientiert sind. Ich könnte denken, obwohl ich nicht ganz sicher bin, ob ich das glaube oder nicht, aber Erlang ist möglicherweise die einzige objektorientierte Sprache, da die drei Grundsätze der objektorientierten Programmierung darin bestehen, dass es auf der Weitergabe von Nachrichten basiert , dass Sie zwischen Objekten und Objekten isoliert sind haben Polymorphismus .

Asynchrone Nachrichtenübermittlung wie in ereignisgesteuerten Systemen und in Erlang ist auch eine sehr gute Möglichkeit, Systeme zu entkoppeln, und lose Kopplung ist in komplexen Systemen wichtig. Mit einem ausreichend entkoppelten System können Sie das System weiterentwickeln, während es ausgeführt wird, möglicherweise auf verschiedenen Knoten. Unibet hielt hierzu eine großartige Präsentation: Domain Event Driven Architecture

Ich denke jedoch, dass der Großteil der Wiederverwendung von Code mithilfe von Bibliotheken und Frameworks erfolgt.


2
Ich liebe dieses Gorilla-Zitat. ^^
gablin

Ich dachte, die Frage betraf die Wiederverwendung von Code, nicht die nette Semantik.
Daniel Lubarov

6

Die bescheidene Unix-Pipe hat mehr für die Wiederverwendung von Code getan als alles andere, was gekommen und gegangen ist. Objekte waren zufällig eine intuitive Art, Code zu strukturieren, als sie kamen, und später begannen die Leute, alles und jedes darauf anzuheften. Im Allgemeinen dienen Objekte zur Kapselung und nicht zur Wiederverwendung von Code. Die Wiederverwendung von Code erfordert etwas mehr und die Klassenvererbungshierarchie ist ein schlechter Ersatz für das, was ein Mechanismus zur Wiederverwendung von Code eigentlich sein sollte.


4

OOP ist nichts Besonderes; Sie können wiederverwendbaren Code mit oder ohne OOP erstellen. Reine Funktionen sind besonders wiederverwendbar : Nimmt zum Beispiel java.lang.math.sqrt(double)eine Zahl ein und gibt eine Zahl aus. Kein OOP, aber definitiv wiederverwendbarer als die meisten anderen Codes.


4

Aus Sicht der funktionalen Programmierung geht es bei OOP hauptsächlich um die Verwaltung des Zustands.

In der funktionalen Programmierung stehen Ihnen Hunderte nützlicher Funktionen für Listen zur Verfügung: http://haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/Data-List.html .

Hätten Sie Hunderte von Methoden in einer List-Klasse? Öffentliche Methoden werden als Schnittstelle zum internen Zustand betrachtet, den Sie klein halten möchten.

Leider duplizieren manche Leute die Funktionalität, anstatt viele kleine Funktionen (erneut) zu verwenden. Für mich liegt das daran, dass OOP die Wiederverwendung von Code nicht so sehr fördert wie die funktionale Programmierung.


1
Deine Schlussfolgerungen sind alle falsch, @ Lenny222. Es gibt nichts an OOP, für das Klassen erforderlich sind, um den Status beizubehalten. Dies ist eine Frage der Architektur, unabhängig davon, ob der Status intern gespeichert oder wie die Integer-Klassen von Smalltalk neue Objekte mit einem neuen Status instanziiert wird.
Huperniketes

1
Es tut mir leid, dass ich mich nicht in einer Weise ausgedrückt habe, die dieses Missverständnis verhindert hat: Ich meinte, dass der Unterschied zwischen OOP und FP nicht darin besteht, dass OOP die Wiederverwendung von Code mehr fördert als FP (was die Überschrift impliziert). Ich habe mit FP eine viel bessere Wiederverwendung von Code erlebt. Wenn Sie nur unveränderliche Klassen haben, emulieren Sie FP, warum machen Sie OOP überhaupt? In meinem POV geht es um ein imperatives Staatsmanagement.
LennyProgrammers

3

Für mich ja, aber nicht die ganze Zeit, und es hätte auch anders gemacht werden können.

Meistens durch Erstellen einer abstrakten Basisklasse und Erstellen konkreter Implementierungen dieser Klasse.

Viele Frameworks verwenden Vererbung, um die Wiederverwendung von Code zu ermöglichen (Delphi, Java, .Net sind nur einige, die einem sofort in den Sinn kommen).

Das heißt nicht, dass viele Dienstprogrammbibliotheken und Code-Schnipsel diese Aufgabe nicht erledigt hätten, aber eine gut gestaltete Objekthierarchie hat etwas Angenehmes.


3

Meiner Erfahrung nach war es erfolgreicher, "wiederverwendbaren" Code durch generische Programmierfunktionen (wie C ++ - Vorlagen) zu nutzen, als OOP-Prinzipien wie Vererbungshierarchien zu verwenden.


2

OOP ist zu offen für eine effektive Wiederverwendung.

Es gibt zu viele Möglichkeiten zur Wiederverwendung. Jede öffentliche Klasse fragt: "Mach eine neue Instanz von mir!" Jede öffentliche Methode sagt: "Ruf mich an!" ergibt jede geschützte Methode: "Überschreibe mich!" - und alle diese Arten der Wiederverwendung sind unterschiedlich , sie haben unterschiedliche Parameter, sie erscheinen in unterschiedlichem Kontext, alle haben unterschiedliche Regeln, wie sie aufgerufen / erweitert / überschrieben werden.

API ist besser, es ist eine strenge Untermenge von OOP-Punkten (oder Nicht-OOP-Punkten), aber im wirklichen Leben sind APIs überfordert und wachsen ständig, es gibt immer noch zu viele Verbindungspunkte. Außerdem kann eine gute API das Leben erleichtern. Dies ist der beste Weg, eine Schnittstelle für OOP bereitzustellen.


Das Datadlow-Paradigma bietet eine strenge Schnittstelle für Komponenten. Sie haben Ports der folgenden Typen:

  • Verbraucher (Eingänge) und
  • Produzenten (Outputs).

Abhängig von der Domäne gibt es einige Pakettypen, sodass Verbraucher und Hersteller verbunden werden können, wenn sie dieselben (oder kompatiblen) Ports haben. Das Schönste daran ist, dass es visuell möglich ist, da es keine Parameter oder andere Änderungen an den Verbindungen gibt, sondern nur einen Verbraucher und einen Produzenten miteinander verbindet.

Ich war ein bisschen unklar, vielleicht sehen Sie sich das "dataflow" -Tag auf StackOverflow oder Wikipedia "datafow programming" oder Wikipedia "flow-based programming" an .

(Außerdem habe ich ein Datenflusssystem in C ++ geschrieben. OOP und DF sind also keine Feinde, DF ist eine übergeordnete Organisationsmethode.)


2

In CommonLisp gibt es viele Möglichkeiten, die Wiederverwendung zu erreichen:

  • Dynamische Eingabe, wobei Ihr Code standardmäßig generisch ist

  • imperative Abstraktionen, dh Unterprogramme

  • Objektorientierung mit Mehrfachvererbung und Mehrfachversand

  • Syntax-Abstraktion, die Fähigkeit, neue syntaktische Konstrukte zu definieren oder Kessel-Platten-Code abzukürzen

  • funktionale Abstraktionen, Abschlüsse und Funktionen höherer Ordnung

Wenn Sie versuchen , die CommonLisp Erfahrung in anderen Sprachen zu vergleichen , werden Sie sehen , dass die Hauptfunktion , die die Wiederverwendung von Code erleichtert ist das Vorhandensein von sowohl objektorientierten und funktionalen Abstraktionen. Sie sind komplementärer als alternativ: Ohne eine von ihnen müssen Sie die fehlenden Funktionen ungeschickt neu implementieren. Siehe zum Beispiel Funktionsklassen, die als Closures und Pattern Matching verwendet werden, um einen nicht erweiterbaren Methodenversand zu erhalten.


1

Es gibt wirklich keine "Wiederverwendung", wie die Leute es beschreiben. Wiederverwendung ist ein zufälliges Eigentum von allem. Es ist schwer zu planen. Was die meisten Leute meinen, wenn sie über "Wiederverwendung" sprechen, ist "Verwendung". Es ist ein weit weniger attraktiver und aufregender Begriff. Wenn Sie eine Bibliothek verwenden, verwenden Sie sie normalerweise für das, wofür sie bestimmt war. Sie werden es nicht wiederverwenden, es sei denn, Sie machen etwas wirklich Verrücktes damit.

In diesem Sinne geht es bei der Wiederverwendung in der realen Welt darum, Dinge neu zu definieren. Ich kann diese Sitze hier wiederverwenden und sie neu anordnen, um ... ein Bett zu bilden! Kein sehr bequemes Bett, aber das kann ich. Das ist nicht ihre primäre Verwendung. Ich verwende sie außerhalb ihres ursprünglichen Geltungsbereichs weiter. [...] Morgen fliege ich zurück nach Großbritannien. Ich werde das Flugzeug nicht wiederverwenden. Ich werde es nur für den Zweck verwenden, für den es gedacht war, daran ist nichts Besonderes oder Aufregendes.

- Kevlin Henney


3
Die Leute werden alles glauben, was sie im Druck sehen. Kevlin Henney ist falsch und begründet seine Argumentation mit einem Mangel an historischem Kontext und einer schlechten semantischen Interpretation. Die Wiederverwendung von Code war seit den Tagen der Vakuumröhrencomputer von UNIVAC und IBM ein grundlegendes Programmierprinzip. Bei der Wiederverwendung von Code ging es nicht darum, ihn für eine andere Funktionalität als die vorgesehene zu verwenden . Sie haben Ihre Unterprogramme geschrieben und zusammengestellt (später wurde sie kompiliert), um Objektcode zu erzeugen, der dann in Ihr Programm eingebunden wurde. Wiederverwendung bedeutet wirklich das, was heute in der Branche allgemein üblich ist.
Huperniketes

Wenn Sie zwei Funktionen schreiben, die genau dasselbe tun, haben Sie den Code NICHT wiederverwendet, unabhängig davon, wie oft Sie sie verwendet haben.
JeffO

Die Stuhlanalogie ist schön und das alles nur ein Wort: Lego.
Biziclop

1

Ich werde Spott riskieren und gestehen, ich habe OOP erst vor kurzem benutzt. Es kommt nicht automatisch zu mir. Der Großteil meiner Erfahrung bezieht sich auf relationale Datenbanken, daher denke ich in Tabellen und Joins. Es gibt Behauptungen, dass es besser ist, es von Anfang an zu lernen, damit Sie beim Programmieren nicht umdenken müssen. Ich habe diesen Luxus nicht und lehne es ab, meine Karriere wegen irgendeiner Elfenbeinturmtheorie aufzugeben. Wie alles andere werde ich es herausfinden.

Zuerst dachte ich, dass das ganze Konzept keinen Sinn ergibt. Es schien nur unnötig und zu viel Mühe. Ich weiß, das ist verrücktes Gerede. Offensichtlich ist ein gewisses Maß an Verständnis erforderlich, bevor Sie die Vorteile von etwas einschätzen oder es für bessere Methoden ablehnen können.

Die Wiederverwendung von Code erfordert die Bereitschaft, Code nicht zu wiederholen, ein Verständnis dafür, wie dies erreicht werden kann und eine Vorausplanung. Sollten Sie die Wiederverwendung von Code vermeiden, wenn Sie sich für einen Fall entschieden haben, in dem es sich einfach nicht lohnt? Und keine Sprache ist so streng OO, dass sie einen Fehler auslöst, wenn sie denkt, dass Sie Code von einer anderen Klasse geerbt haben sollten. Bestenfalls bieten sie eine Umgebung, die der Implementierung förderlich ist.

Ich denke, der größte Vorteil von OOP ist die allgemeine Akzeptanz, wie Code organisiert werden sollte. Alles andere ist Soße. Ein Team von Programmierern ist sich vielleicht nicht ganz einig, wie alle Klassen strukturiert sein sollen, aber sie sollten in der Lage sein, den Code zu finden.

Ich habe genug Prozedurcode gesehen, um zu wissen, dass er überall sein kann, und manchmal ist er überall.


"Und keine Sprache ist so streng OO, dass sie einen Fehler auslöst, wenn sie denkt, dass Sie Code von einer anderen Klasse geerbt haben sollten" - jedenfalls noch nicht!
Steven A. Lowe

1

OOP bietet Ihnen mehr Möglichkeiten, Code wiederzuverwenden. Das ist alles.


OOP fördert auch die Wiederverwendung von Schnittstellen und die Wiederverwendung von Designs.
rwong

Es gibt mir viel weniger Möglichkeiten, einen generischen, wiederverwendbaren, sehr abstrakten Code zu schreiben als die anderen Paradigmen wie funktionale Programmierung (Mind Currying, Kombinationsbibliotheken usw.) und Metaprogrammierung. Tatsächlich scheint OOP eine Abstraktionsstufe zu haben, wenn die Alternativen überhaupt nicht begrenzt sind.
SK-logic

@ SK-Logik: orthogonal.
Steven A. Lowe

1

Horizontale Wiederverwendung: Aspekte, Merkmale, Transplantate

In Classic OO wird die Wiederverwendung von Code manchmal nicht ausreichend unterstützt, insbesondere dann, wenn die Vererbung aus Mangel an einer besseren Möglichkeit, die tatsächliche Funktionalität zwischen Klassen zu teilen, völlig verrückt wird. Für dieses Problem wurden horizontale Wiederverwendungsmechanismen wie AOP, Merkmale und Transplantate geschaffen.

Aspektorientierte Programmierung

Ich betrachte AOP als das fehlende halbe Orange von OOP. AOP ist nicht wirklich so bekannt, hat es aber zum Seriencode geschafft.

Ich werde es versuchen, um es in einfachen Worten zu erklären: Stellen Sie sich vor, Sie können Funktionen mit einer speziellen Struktur, die als Aspekt bezeichnet wird, einspeisen und filtern. Diese Aspekte haben "Methoden", die definieren, was und wie durch Reflektion beeinflusst wird , aber beim Kompilieren Diesen Vorgang nennt man Weben .

Ein Beispiel wäre ein Aspekt, der besagt, dass für alle Methoden bestimmter Klassen, die mit get beginnen, das Programm die erhaltenen Daten und den Zeitpunkt des Abrufs in eine Protokolldatei schreibt.

Sehen Sie sich diese beiden Vorträge an, wenn Sie AOP besser verstehen möchten:

Traits & Grafts

Merkmale sind ein weiteres Konstrukt zur Definition von wiederverwendbarem Code, das OOP ergänzt. Sie ähneln Mixins , sind aber sauberer.

Anstatt sie zu erklären, gibt es einen großartigen PHP-RFC, der beide erklärt . Traits kommen übrigens zu PHP, sie sind bereits auf Trunk festgelegt.

in Summe

OOP ist meiner Meinung nach immer noch der Schlüssel zur Modularität, und wie wir es heute allgemein kennen, ist OOP immer noch unvollständig .


0

OOP Bietet eine Reihe nützlicher Tools, mit denen Sie Code schreiben können, der an mehr Stellen verwendet werden kann, als Sie ohne diese Tools hätten. Wenn Sie eine PrintItFunktion schreiben , die ein altes Objekt übernimmt und aufruft .toString(), haben Sie diesen Code wieder verwendet, sobald Sie ihn mit mehr als einem Objekttyp aufrufen. Mit diesen Tools leistet jede Codezeile mehr.

Die funktionale Programmierung ist im Moment unter den Hipstern sehr heiß. Es bietet Ihnen eine ganze Reihe von Werkzeugen, mit denen jede Codezeile mehr leisten kann. Es ist wahrscheinlich nicht besser oder funktioniert, bietet aber ein weiteres Tool in der Toolbox.

(Es gab eine verrückte Idee für eine ganze zusätzliche Ebene der objektorientierten Wiederverwendung: Die Idee war, dass wir eine einzelne CustomerKlasse definieren und sie in jeder von uns geschriebenen Anwendung verwenden könnten . Dann wären Anwendungen hier und da nur ein kleiner Klebstoff. Dies hat nicht funktioniert, aber das bedeutet nicht, dass der OO fehlgeschlagen ist oder sogar, dass die Wiederverwendung fehlgeschlagen ist.


0

Lesen Sie die obigen Beiträge, ein paar Anmerkungen:

  • Viele denken, dass die Wiederverwendung von Code in OOP eine Vererbung impliziert. Ich stimme nicht zu. Schnittstellen und Verträge sind der Kern für die Wiederverwendung von Code in OOP-Systemen. OOP ist ein Grey-Box-Versuch zur Erstellung einer Komponententechnologie.
  • Der Unterschied zwischen domänenspezifischen und generischen "Frameworks" als Gegenstand der Wiederverwendung halte ich für zu abstrakt. Aus meiner Sicht kann eine Komponente (ein prägnanter, minimaler und wiederverwendbarer Schnittstellenvertrag und die Implementierung dahinter) nur dann ausgeführt werden, wenn das Problem, das darin behandelt wird, gut verstanden wird. Eine domänenspezifische Komponente, die es Nicht-Domain-Experten ermöglicht, ihre Arbeit mit weniger Wissen über die Domain zu erledigen, ist eine (wieder-) nützliche Komponente. Benutzer müssen die Benutzeroberfläche verstehen, weniger die Feinheiten der Problemdomäne.
  • Ebenen der Wiederverwendung, die oft vergessen werden: Wiederverwendung von Ideen, Wiederverwendung von Spezifikationen, Wiederverwendung von Architektur / Design, Wiederverwendung von Schnittstellen, Wiederverwendung von Testfällen. Die Wiederverwendung von Code ist nicht immer günstig. Oft ist es jedoch eine große Zeitersparnis, sich an eine bestimmte Architektur zu halten, um ein neues, ähnliches Produkt in Angriff zu nehmen.
  • Die OOP-Entwurfsmuster (Gamma et al.) Haben in meinen Augen eher taktische Implementierungstechniken herausgearbeitet, als dass sie im Zusammenhang mit der Wiederverwendung von Code in größerem Maßstab von Bedeutung sind. Sie helfen beim Schreiben einer Anwendung mit OOP-Elementen, aber ich würde sie nicht als Lösung für die Frage nach der Wiederverwendung von Code über eine einzelne Anwendung hinaus sehen.
  • Vielleicht ist es nicht fair: 20 Jahre C / C ++ / C # -Erfahrung und 6 Monate funktionale Programmierung (F #). Ein wichtiges Element, um die Wiederverwendung zu ermöglichen, ist: Die Benutzer müssen die "Schnittstelle" leicht finden, studieren, verstehen und dann verwenden können. Reine funktionale Programmierung macht es mir nicht leicht, Strukturen zu erkennen, Kandidaten für die Wiederverwendung oder wo alles beginnt und wo alles endet. Der so gelobte "syntaktische Zucker" ist oft Salz in meinen Augen, was mich daran hindert, leicht zu sehen, was passiert. Daher würde ich weniger wahrscheinlich versuchen, eine Funktion (was ist das - eine Reihe von Funktionen?) Wiederzuverwenden, die möglicherweise versteckte Nebenwirkungen hat, die ich nicht einmal sehen kann (verzögerte Bewertung, Monaden, ...). Versteh mich nicht falsch, funktionale Programmierung hat sehr coole Seiten, aber alle Stärken, die ich verkündet habe, sehe ich mit einem guten Maß an Zweifel.
  • Spezifikation, Design, Implementierung sind gekoppelt, aber nicht einfach zu übermittelnde Sichten auf das "Gleiche". Um die zukünftige Produktivität zu steigern, ist es wesentlich wichtiger als ein neues Programmierparadigma, die Lücke zu schließen und den gegenseitigen Nutzen zwischen diesen Ansichten zu erhöhen (automatisiertes Schließen, Rückverfolgbarkeit). Formalisierte Spezifikationssprachen, standardisierte Testnotationen (z. B. ttcn3) und Programmiersprachen, die die Überprüfung von Schnittstellen und Verträgen gegen Spezifikationen ohne Verfälschung von Kommentaren unterstützen, könnten das dringendste sein.

0

Das Problem ist imho subtiler:

  1. OOP ist eine großartige Methode zum Strukturieren von Code mit veränderlichem Zustand . Indem Sie den Zustand in Objekte einkapseln, wird der Code für einen imperativen Zustand verständlicher, da Sie beispielsweise wissen, dass zumindest dieser bestimmte Zustand nur mit diesen Methoden geändert werden kann , wenn ein Zustand als privates Feld einer Klasse ausgedrückt wird Klasse. (Und Sie können diesen Vorteil leicht durch Missbrauch der Vererbung brechen, übrigens.) Dies ist jetzt genug, aber es ist besser, als nicht einmal dies zu haben.
  2. Code mit veränderlichem Status ist von Natur aus schwer wiederzuverwenden . Viel schwieriger als Code mit unveränderlichen Datenstrukturen.

Also ist OOP an sich nicht schlecht, wenn es darum geht, wiederverwendbaren Code zu erstellen , aber die Arten von Code, die mit OOP geschrieben werden, sind von Natur aus schwer wiederzuverwenden .

Die funktionale Programmierung kann auch zu mehr wiederverwendbarem Code führen . Es ist jedoch möglicherweise nicht machbar, die Abstraktionen so zu gestalten, dass sie bei Einhaltung einer Frist einen vernünftigen Funktionscode schreiben. Und "halb-rechts" -Abstraktionen werden den OOP-Stil leichter ausdrücken. Und es wird nicht dazu führen, dass Code einfacher wiederverwendet werden kann - ein höherer Grad an Abstraktionen bedeutet, dass das Codeverständnis eine höhere Anfangsinvestition der begrenzten kognitiven Kapazität der Programmierer erfordert.

Als praktisches Beispiel: Spielcode beinhaltet viele veränderbare Zustände, da dies die natürliche Art ist, ein Spiel zu codieren, es sei denn, es ist ein sehr rätselhaftes / algorithmisches, so dass es offensichtlich mit OO strukturiert wird. Und natürlich ist es schwer wiederzuverwenden. Aber derselbe Code, der das gleiche Wissen enthält, wäre ohne OOP noch schwieriger wiederzuverwenden . Und das Umschreiben in einen funktionalen Stil erfordert möglicherweise eine grundlegende Änderung der Art und Weise, wie Sie über diesen Code denken, sowie des Wissens, das dahinter steckt. Ja, das resultierende Wissen hinter dem Code wäre nach dem Umschreiben von OO zu FP vielleicht viel klarer ... aber die Kosten könnten riesig sein und es könnte seinDie Art von Kosten, die auch von Leuten bezahlt werden müssten, die den unglaublich intelligenten und gut abstrahierten Code wiederverwenden möchten, mit dem Sie enden. Paradoxerweise würden die Leute den Code nicht wiederverwenden, selbst wenn er technisch wiederverwendbarer ist.

... was zur letzten Subtilität führt: Bei der Wiederverwendung von Code geht es um die People | Code- Oberfläche, nicht nur um den Code. OOP leistet gute Dienste für diese Schnittstelle, da es gut zu erkennen ist, wie viele Leute über viele Arten von Code nachdenken, der heutzutage geschrieben wird. FP ist vielleicht besser für die Wiederverwendung von Code, aber imho nicht für die einfache Wiederverwendung der Art von Code, die die Leute heutzutage tatsächlich schreiben müssen. Dies ändert sich mit der Art des Codes, den wir zum Schreiben von Änderungen benötigen.

PS Und wenn jemand sagen will, dass es sich bei OO nicht um einen veränderlichen Zustand handelt, kann es sich auch um OO mit unveränderlichem Zustand handeln. Ich nenne das "FP mit Klassen als Namespaces". Es ist großartig, wenn es für Sie funktioniert, und es vermeidet einige Mängel der Modulsysteme einiger Sprachen und kann zu mehr wiederverwendbarem Code führen. Aber das ist nicht OO;)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.