Ist die Klassische OOP gescheitert?

Für Dinge zum Forum, Kritik, Verbesserungsvorschläge, Umfragen und ähnliches.
Antworten
pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Ist die Klassische OOP gescheitert?

Beitrag von pluto »

Es gibt keine allgemeingültige Regel wie und von wem Kreis und Ellipse abgeleitet werden. Es kommt immer auf die praktische Aufgabenstellung an.

Darum geht es doch in der OOP(Gerade bei der Vererbung), dass man von einander Ableitet und Gemeinsamkeiten finden um den Coder nur einmal zu schreiben.

Von daher kann diese akademische Diskussion bis ins Allerletzte diskutiert werden. Für die Praxis in der Softwareentwicklung ist das nicht relevant.

Es mag aber ähnliche Probleme im Alttag geben. Die sich nicht so leicht oder vielleicht gar nicht lösen lassen.

Weil eine Ellipse eben nicht die Sonderform eines Kreises, sondern ein Kreis die Sonderform einer Ellipse ist.

Das ist der Punkt. Ein Auto ist zwar kein Fahrrad, aber beides sind Fahrzeuge. Ein Kreis und eine Ellipse sind beides Figurieren, die durchaus Gemeinsamkeiten haben.
Sie haben z.b. ein X und Y. Die Größe müsste aber schon Dynamisch sein. Weil eine Line z.b. im Prinzip auch nur eine Stärke hat.

Und schwubs habe ich um ein einfaches Viereck zu definieren 4 Vererbungsebenen... Dein Ernst?

Mein Vater sagte mal: Ist doch ganz einfach, per Winkel das ganze zu beschreiben und ein Kreis besteht dann aus sehr vielen Winkeln oder wie?

Nee, gerade dieses akademisch gern verwendete Viereck-Beispiel zeigt doch, wie man sich mit OOP schön selber ins Knie schießen kann und noch stolz drauf ist.

Ich denke, solche Aufgaben kommt bestimmt in irgendeiner Prüfung vor.

Man schießt sich dann mit OOP ins Knie, wenn man ahnungslos drauflosprogrammiert und nicht versteht wie es funktioniert. Aber das ist auch ohne OOP der Fall.

Naja.... Wie möchtest du denn hier Gemeinsamkeiten finden, ohne Zusagen: Das geht nicht. Z.B. wenn der Datentyp Automatisch erkannt würde, wie in etwa bei Rust, könnte man eine Variable wie Größe hinzufügen und das ist dann entweder nur ein Wert z.b. der Radios oder eben es sind zwei werte. Wäre aber auch unschön, da der Name ja "Größe" bzw. "Size" wäre.

Die OOP ist schon verdammt praktisch. Ich kann mir GUI-Programmierung ohne OOP ehrlich gesagt gar nicht vorstellen.

Da stimme ich dir zu. Es gibt einfach Anwendungsfälle, die geht nur sehr schwer ohne die OOP, wenn man es doch versucht, kommt sowas wie WinAPI dabei raus.

Iteriert man nun durch die Liste, wie es in der Procedure "WriteValues" getan wird, dann wird je nach abgeleiteter Klasse eine andere Funktion "GetValue" aufgerufen.

Das ist ja auch gewollt.

An der Stelle im Code wo das geschieht, ist aber nicht sichtbar, welche abgeleiteten Klassen überhaupt im Spiel sind. In Lazarus wird bei Klick auf "GetValue" die Deklaration von GetValue der Basisklasse gezeigt, obwohl die ja von der abgeleiteten Klasse überschrieben wurde. Lazarus kann da nichts dafür, es ist ja erst zur Laufzeit bekannt, welche Instanzen in der Liste sind. Aber es macht die Sache trotzdem recht unübersichtlich, insbesondere, wenn die abgleiteten Klassen in veschiedenen Units verteilt sind.

Das meine ich. Bei sehr Dynamischen Code, ist nicht immer klar, welche Klassen verwendet werden.

Das kann in der Tat verwirren. Passiert mir übrigens nicht, da ich fast immer nur Interfaces benutze.

Bei interfaces stört mich eigentlich, dass man sämtliche Methoden die dort Definiert sind, ebenfalls definieren muss.
Was für Vorteile bringen Interfaces gegenüber Klassen?

Da komme ich dann beim Klick auf die Methode zu gar keiner Implementierung.

Auch eine Lösung.

Tatsächlich sollte das einen Entwickler auch nicht stören. GetValue wird ja nur in einer Schicht aufgerufen, die über der Klasse liegt in der die Methode implementiert wird. In dieser Schichte sollte aber (sofern alles korrekt getrennt wurde) völlig unerheblich sein, wie diese Implementierung aussieht.

Wenn du einen Fremden Code hast und ihn verstehen möchtest, sind solche Eigenarten aber doch nicht auf einen Blick zu erkennen, ich selbst habe damit im Prinzip kein Problem. Ich finde mich in den meisten fremden Code's sehr gut zu recht. Auch wenn sie etwas komplexer geschrieben sind.

Das ist kein Problem der OOP. Sondern ein Problem der IDE. Und ein Problem jedes Quellcode mit mehr als ein paar 1000 Zeilen. (egal welche Sprache/Konzept)

Ich würde sagen, dass wäre ein Problem der Strukturierung vom Code. Wie erstelle ich guten Code in einem Umfangreichen Projekt ohne die Übersicht zu verlieren?

Die IDE kennt ja alle Möglichkeiten ("Find Identifier References"). Die IDE könnte die zur Wahl anbieten.
Die IDE könnte sich auch merken, wenn man vorher bereits in einer abgeleiteten Klasse war, und weiter navigiert.

Wenn du andere IDE'S wie in etwa Arduino(gut ist keine Wirkliche IDE), verwendest lernst du solche Funktionen zu schätzen. Bei Arduino muss ich immer selbst die passende Datei in einem externen Editor anschauen, wenn ich etwa wissen möchte welche Methoden eine Klasse hat.
Die Code-Vervollständigung, die es jetzt gibt kann man praktisch noch nicht verwenden. Außerdem hat es mich überrascht: Arduino öffnet bei mir über 16.000 Dateien, die scheinbar alle was mit Java zu tun haben, ist mir mal per Zufall aufgefallen :D Google-Chrome Öfffnet ca 600 und Telegramm 300.

In der prozeduralen Programmierung gibt es pointer auf Funktionen. Da kann man auch nicht sehen wo das Programm wirklich hin springen wird.
Und bei anderen Programmierkonzepten gibt es auch solche Punkte.

Ich finde Pointer als sehr unsicher, sind aber auch sehr Mächtig. Damit kann man den Compiler schön durcheinander bringen.
MFG
Michael Springwald

Benutzeravatar
Niesi
Lazarusforum e. V.
Beiträge: 331
Registriert: So 26. Jun 2016, 19:44
OS, Lazarus, FPC: Linux Mint Cinnamon (Windows wenn notwendig), Lazarus 3.0 FPC 3.3.1

Re: Ist die Klassische OOP gescheitert?

Beitrag von Niesi »

pluto hat geschrieben:
m.fuchs hat geschrieben:Es gibt keine allgemeingültige Regel wie und von wem Kreis und Ellipse abgeleitet werden. Es kommt immer auf die praktische Aufgabenstellung an.

Darum geht es doch in der OOP(Gerade bei der Vererbung), dass man von einander Ableitet und Gemeinsamkeiten finden um den Coder nur einmal zu schreiben.


Ganz genau so ist es. Und DU als Programmierender legst fest, wie Du ableitest. Nur DU.

Und das kannst Du so machen, dass es einfach ist oder kompliziert.

Das ist aber kein Problem der Vererbung in der OOP, das ist ein Problem mit der Logik, die wir alle hin und wieder haben.

(Ihr solltet Euch nicht so sehr an Kreis und Ellipse festbeißen - es war nur ein BEISPIEL!)
Wissen ist das einzige Gut, das sich vermehrt, wenn es geteilt wird ...

Benutzeravatar
Niesi
Lazarusforum e. V.
Beiträge: 331
Registriert: So 26. Jun 2016, 19:44
OS, Lazarus, FPC: Linux Mint Cinnamon (Windows wenn notwendig), Lazarus 3.0 FPC 3.3.1

Re: Ist die Klassische OOP gescheitert?

Beitrag von Niesi »

kupferstecher hat geschrieben:Die Realität ist halt kompliziert. Auch mit dem besten Programmierparadigma ist eine Zeile Code nicht genug um jedes Problem zu lösen.
Die OOP ist schon verdammt praktisch. Ich kann mir GUI-Programmierung ohne OOP ehrlich gesagt gar nicht vorstellen.

Hier aber ein tatsächliches Vererbungsproblem, siehe Code. Bei jedem Anlegen einer Instanz wird diese der Liste "Items" hinzugefügt (nicht Teil des Codes). Iteriert man nun durch die Liste, wie es in der Procedure "WriteValues" getan wird, dann wird je nach abgeleiteter Klasse eine andere Funktion "GetValue" aufgerufen. An der Stelle im Code wo das geschieht, ist aber nicht sichtbar, welche abgeleiteten Klassen überhaupt im Spiel sind. In Lazarus wird bei Klick auf "GetValue" die Deklaration von GetValue der Basisklasse gezeigt, obwohl die ja von der abgeleiteten Klasse überschrieben wurde. Lazarus kann da nichts dafür, es ist ja erst zur Laufzeit bekannt, welche Instanzen in der Liste sind. Aber es macht die Sache trotzdem recht unübersichtlich, insbesondere, wenn die abgleiteten Klassen in veschiedenen Units verteilt sind.


Code: Alles auswählen

Type TEineKlasse = class
    class var Items: TList;
    Procedure WriteValues;
    Function GetValue: Integer; virtual;
  end;
 
Type TEineKlasse2 = class(TEineKlasse)
    Function GetValue: Integer; override;
  end;
 
IMPLEMENTATION
 
procedure TEineKlasse.WriteValues;
var EineKlasse: TEineKlasse;
begin
  for pointer(EineKlasse) in Items
  do writeln(EineKlasse.GetValue);
end;
 
function TEineKlasse.GetValue: Integer;
begin
  Result:= 0;
end;
 
function TEineKlasse2.GetValue: Integer;
begin
  Result:= 2;
end;



Dazu habe ich jetzt mal eine Frage: ich habe mir gerade ein ähnliches Beispiel geschrieben, also Klassen von einer Ur-Klasse abgeleitet, die dann als Ergebnis von GetValue eine jeweils andere Zahl zurückgeben.

Ich arbeite praktisch nie mit Pointern, weil ich auch so zurechtkomme und die nicht mag - wenn ich Instanzen von den unterschiedlichen Klassen abaleite und in einer ObjectList einfüge, dann bekomme ich immer die richtigen Ergebnisse, wenn ich diese ObjectList "abarbeite".

Wieso hast Du da Probleme? Und woher kommen die?
(ist wichtig für mich, weil ich sehr viel mit solchen Objektlisten arbeite ...) :shock:
Wissen ist das einzige Gut, das sich vermehrt, wenn es geteilt wird ...

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Ist die Klassische OOP gescheitert?

Beitrag von pluto »

Ganz genau so ist es. Und DU als Programmierender legst fest, wie Du ableitest. Nur DU.

Ganz so einfach ist das aber nicht, wie diese Diskussion bereits zeigt.

Und das kannst Du so machen, dass es einfach ist oder kompliziert.

In sehr vielen Fällen muss es aber auch einfach Passen. Es muss Richtig sein. Es gibt in sehr vielen Fällen Praktisch nur ein Weg, auch wenn es scheinbar viele Wege gibt.

Das ist aber kein Problem der Vererbung in der OOP, das ist ein Problem mit der Logik, die wir alle hin und wieder haben.

Klar ist das ein Problem der OOP, aber man kann eben nicht alles mit der OOP machen. Wenn ich hier von OOP schreibe, meine ich natürlich die Vererbung. Bitte nicht verwechseln.

(Ihr solltet Euch nicht so sehr an Kreis und Ellipse festbeißen - es war nur ein BEISPIEL!)

Es war aber DAS Beispiel. Es geht bei sowas immer nur um Beispiele.

Ein andere Fall, wäre jetzt z.b.: Wenn wir wollen, dass eine Klasse nur einmal erstellt werden kann, wie machen wir das am besten?

Wieso hast Du da Probleme? Und woher kommen die?
(ist wichtig für mich, weil ich sehr viel mit solchen Objektlisten arbeite ...)

Es geht hier bei: Um Die Übersicht. Du weiß erst zur Laufzeit, welche Klasse wirklich verwendet wird. Es mag kein Problem sein, zunächst, jedoch bei sehr vielen unterschiedlichen Klassen kann das schon ein Problem beim Debuggen werden, weil du nicht nicht sofort weiß. welche Methode jetzt wirklich aufgerufen wird und welche nicht.
MFG
Michael Springwald

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Ist die Klassische OOP gescheitert?

Beitrag von m.fuchs »

pluto hat geschrieben:
Ganz genau so ist es. Und DU als Programmierender legst fest, wie Du ableitest. Nur DU.

Ganz so einfach ist das aber nicht, wie diese Diskussion bereits zeigt.

Doch es ist ganz so einfach: der Entwickler entscheidet bei der Entwicklung. Es gibt keine allgemeingültigen Regeln, es kommt auf die Aufgabenstellung an.
Solange man das aber nicht versteht, wird man bei komplexen Projekten früher oder später vor einem unübersichtlichen Haufen stehen.

pluto hat geschrieben:Wenn ich hier von OOP schreibe, meine ich natürlich die Vererbung. Bitte nicht verwechseln.

Das ist übrigens eines deiner Probleme. Du schreibst etwas und meinst etwas anderes. Das ist tödlich in der Softwareentwicklung.

pluto hat geschrieben:
(Ihr solltet Euch nicht so sehr an Kreis und Ellipse festbeißen - es war nur ein BEISPIEL!)

Es war aber DAS Beispiel. Es geht bei sowas immer nur um Beispiele.

Es ist kein Beispiel, ich frage dich (seit Wochen übrigens in diesem Thread) nach einem praktischen Beispiel, ich habe auch mehrmals erklärt warum das Kreis-Ellipse-Problem keine allgemeingültige Lösung hat und dass es auf das tatsächliche Praxisszenario ankommt. Du schaffst es aber mit der Beharrlichkeit eines Trolls immer wieder das gleiche "Problem" vorzulegen.

pluto hat geschrieben:Ein andere Fall, wäre jetzt z.b.: Wenn wir wollen, dass eine Klasse nur einmal erstellt werden kann, wie machen wir das am besten?

Singleton Pattern ist die grundsätzliche Antwort. Ich würde natürlich erst einmal die Frage stellen: Warum? Aber die Frage scheinen sich viele Entwickler nicht zu stellen.

Du weiß erst zur Laufzeit, welche Klasse wirklich verwendet wird. Es mag kein Problem sein, zunächst, jedoch bei sehr vielen unterschiedlichen Klassen kann das schon ein Problem beim Debuggen werden, weil du nicht nicht sofort weiß. welche Methode jetzt wirklich aufgerufen wird und welche nicht.

Beim Debuggen springt man in die richtige Methode. Das erfolgt nämlich zur Laufzeit.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Ist die Klassische OOP gescheitert?

Beitrag von m.fuchs »

pluto hat geschrieben:Ein Kreis und eine Ellipse sind beides Figurieren, die durchaus Gemeinsamkeiten haben.

Nur weil zwei Klassen Gemeinsamkeiten müssen sie nicht voneinander ableiten. Wenn du das denkst, sind da vermutlich deine Probleme mit Vererbung zu finden.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: Ist die Klassische OOP gescheitert?

Beitrag von kupferstecher »

martin_frb hat geschrieben:Das ist kein Problem der OOP. Sondern ein Problem der IDE. Und ein Problem jedes Quellcode mit mehr als ein paar 1000 Zeilen. (egal welche Sprache/Konzept)

Was ich als "Problem" bezeichnet habe, ist ja sogar ein Feature der Vererbung, also dass man Prozeduren von abgeleiteten Klassen über die Variable/den Typ einer übergeordneten Klasse rufen kann (Intern tatsächlich über Art Funktionspointer gelöst?).
Mit diesem Feature ist man aber zwangsläufig untertypisiert unterwegs. Wenn man durch den Code scrollt ist nicht ersichtlich, dass abgeleitete Klassen überhaupt mit im Spiel sind.
Mir scheint, dass man dieses Problem programmiersprachlich zumindest in manchen Szenarien durchaus verbessern könnte, bspw. indem man einen "Sammeltyp" definiert, der alle abgeleiteten Klassen vereint.
Bspw:
Type TAlleWinControls = TButton, TPanel, TCheckBox;
Wenn man einer Variable vom Typ TAlleWinControls dann ein TRadioButton (der ja nicht im "Sammeltyp" definiert wurde) zuweisen würde, würde der Compiler meckern. Im Gegensatz dazu ist eine Zuweisung zu einer Variable vom Typ TWinControl ja implizit möglich.

Hier sieht man aber gleich das Problem, dass das nur bei "geschlossenen" Projekten möglich wäre und nicht bei Frameworks/Bibliotheken, wo von Dritten weiter abgeleitet werden können muss. Vom Zusatzaufwand ganz zu schweigen.
Das über die IDE zu erschlagen scheint mir tatsächlich sinnvoller (und universeller).

Die IDE kennt ja alle Möglichkeiten ("Find Identifier References"). Die IDE könnte die zur Wahl anbieten.

OK, das ist interessant. Das würde die Navigation m.E. wirklich verbessern.

m.fuchs hat geschrieben:Tatsächlich sollte das einen Entwickler auch nicht stören. GetValue wird ja nur in einer Schicht aufgerufen, die über der Klasse liegt in der die Methode implementiert wird. In dieser Schichte sollte aber (sofern alles korrekt getrennt wurde) völlig unerheblich sein, wie diese Implementierung aussieht.
Die Abstrahierung ist ja gut. Aber, siehe oben, durch die Untertypisierung werden die involvierten Klassen versteckt.

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Ist die Klassische OOP gescheitert?

Beitrag von pluto »

Doch es ist ganz so einfach: der Entwickler entscheidet bei der Entwicklung. Es gibt keine allgemeingültigen Regeln, es kommt auf die Aufgabenstellung an.
Solange man das aber nicht versteht, wird man bei komplexen Projekten früher oder später vor einem unübersichtlichen Haufen stehen.

Gut, ein Beispiel, was nicht unbedingt was mit der OOP hat, aber vielleicht zeigt was ich meine:

Wir haben uns im Verein gestern mit Tastenmatrix befasst. Im ersten Moment denkt man da, ist ja einfach, wo sind die Probleme?
Es kommt ja immer darauf an, wie man es Programmiert und aufbaut. Problem, dabei ist, nicht die eigentliche Matrix.
Das haben wir auf Register Ebene abgefragt, ohne Arduino Grund Methoden zu verwenden, da sie zu Langsam wären und wohl mehr stören würden als nutzen, jedenfalls in diesen Fall.
Weil die Abfragen hier sehr schnell passieren müssen und auf Register Ebene, können wir mehrer Pins, praktisch gleichzeitig abfragen, was mit Arduino Funktionen nicht Funktioniert.

Das Problem liegt hier, an der Möglichkeit mehrer Tasten gleichzeitig zu drücken. Das muss im Code Berücksichtigt werden, sonst können "komische, nicht definierbare Sachen passieren.
Klar, kann ich hier sage: Mehrer Tasten Gleichzeitig brauche ich nicht, aber was ist wenn der User doch mehrer Tasten gleichzeitig drückt und die Hardware es sogar zulässt, aber auch wenn die Hardware es nicht zulässt solle das beachtet werden.

Das sind Details, die man am Anfang nicht unbedingt beachtet.

Ein weiters Beispiel: Wenn ich mir eine Code-Struktur ausdenke und sie in mehreren "Untis" Auslagern möchte, stoße ich früher oder später über die bekannte Einschränkung der Zirkulären Unit aufrufst. Da bleiben mir Praktisch nur zwei Möglichkeiten über: Entweder alles in einer Datei zu packen oder mit Include Dateien zu Arbeiten.

Ein drittes Beispiel:
Ich habe schon oft eine Editor-Komponente Angefangen, ich habe inzwischen verschiedene Konzepten in Verschiedenen Versionen ausprobiert. Früher oder später, komme ich an den Style-Manager. Der soll sich um die Style-Vorlagen und sowas kümmern. Z.B. ich möchte das Wort X Rot haben und das Wort Y Grün und soweiter. Wie mache ich sowas?
Ich mache es so wie es CSS vormacht: Ich erstell eine Klasse nennen wir sie: TPLStyle. Diese Klasse hat vier Felder: Value und ValueID, Value2 und Value2ID.
ValueID und Value2ID sind ENUM werte. Aber was ist Value?
Ich habe einmal Farbwerte, einmal Strings, einmal ENUM Werte z.b. beim Schrift Gewicht. Um das Dynamisch hinzubekommen, hatte ich eine Version mit Pointern gemacht, eine andere, da hatte ich eine Klassenstruktur.

Value ist in diesen Fall TPLValue und von TPLValue habe ich dann die einzelnen Klassen abgeleitet und so die Datentypen Zuverfügung gestellt:
TPLColorValue, TPLStringValue, TPLIntValue und soweiter.

Natürlich gibt es neben TPLStyle, auch TPLStyleList und TPLStyleContainer.

Ich finde diesen Weg etwas übertrieben. Das ist jetzt aber kein Problem der Vererbung sondern viel mehr ein Problem der Verfügbaren Techniken von der OOP, oder sogar von der verwendenen Sprache. Z.B. Rust, erkennt den Datentyp Automatisch, viele Entwickler schreiben ihn aber wegen der Übersicht da hin. D.H. in Rust würde Value einfach ohne Datentyp sein, solange der Datentyp erkennbar ist. Es gibt, bei der Automatischen Erkennung von Rust, aber auch Einschränkungen, es gibt Fälle, da muss man ein Datentyp hinschreiben, sie sollen aber selten sein.

Aufjedenfall führt dieser weg wieder zu vielen Klassen. Bin mir aber recht sicher, aus OOP Sicht ist das richtig.

Was ich als "Problem" bezeichnet habe, ist ja sogar ein Feature der Vererbung, also dass man Prozeduren von abgeleiteten Klassen über die Variable/den Typ einer übergeordneten Klasse rufen kann (Intern tatsächlich über Art Funktionspointer gelöst?).

Ich würde das als Grund Funktion bezeichnen.

OK, das ist interessant. Das würde die Navigation m.E. wirklich verbessern.

Das ist eine Möglichkeit, die ich oft verwende um Code stellen zu Finden...
MFG
Michael Springwald

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: Ist die Klassische OOP gescheitert?

Beitrag von kupferstecher »

Niesi hat geschrieben:Dazu habe ich jetzt mal eine Frage:
[...]
wenn ich Instanzen von den unterschiedlichen Klassen abaleite und in einer ObjectList einfüge, dann bekomme ich immer die richtigen Ergebnisse, wenn ich diese ObjectList "abarbeite".
Wieso hast Du da Probleme?

Nach meinem letzten Beitrag ist es vielleicht deutlicher geworden. Klar kommen immer die richtigen Ergebnisse, da kann man eigentlich nichts falsch machen. Nur beim Verstehen (des eigenen oder fremden) Codes hatte ich teils Schwierigkeiten.

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Ist die Klassische OOP gescheitert?

Beitrag von pluto »

habe noch ein paar Sachen übersehen:
Es ist kein Beispiel, ich frage dich (seit Wochen übrigens in diesem Thread) nach einem praktischen Beispiel, ich habe auch mehrmals erklärt warum das Kreis-Ellipse-Problem keine allgemeingültige Lösung hat und dass es auf das tatsächliche Praxisszenario ankommt. Du schaffst es aber mit der Beharrlichkeit eines Trolls immer wieder das gleiche "Problem" vorzulegen.

ich hoffe ein paar Beispiele geliefert zu haben.

Singleton Pattern ist die grundsätzliche Antwort. Ich würde natürlich erst einmal die Frage stellen: Warum? Aber die Frage scheinen sich viele Entwickler nicht zu stellen.

Schau dir TApllication an, die möchte man nur einmal haben, oder TScreen.

Beim Debuggen springt man in die richtige Methode. Das erfolgt nämlich zur Laufzeit.

Wenn der Debugger richtig Funktioniert. Ich habe ihn abgeschaltet, da ich damit mehr Probleme hatte, als ein Praktischen nutzen.
Andere scheinen damit keine Probleme zu haben, ich suche den Fehler auf eine andere art und weiße und bin damit sehr erfolgreich.
Bei Arduino habe ich auch kein Debugger und da verwende ich diese Methode ebenfalls.
MFG
Michael Springwald

Benutzeravatar
Niesi
Lazarusforum e. V.
Beiträge: 331
Registriert: So 26. Jun 2016, 19:44
OS, Lazarus, FPC: Linux Mint Cinnamon (Windows wenn notwendig), Lazarus 3.0 FPC 3.3.1

Re: Ist die Klassische OOP gescheitert?

Beitrag von Niesi »

pluto hat geschrieben:
Beim Debuggen springt man in die richtige Methode. Das erfolgt nämlich zur Laufzeit.

Wenn der Debugger richtig Funktioniert. Ich habe ihn abgeschaltet, da ich damit mehr Probleme hatte, als ein Praktischen nutzen.
Andere scheinen damit keine Probleme zu haben, ich suche den Fehler auf eine andere art und weiße und bin damit sehr erfolgreich.
Bei Arduino habe ich auch kein Debugger und da verwende ich diese Methode ebenfalls.



Eines Deiner Probleme: Du willst etwas machen (OOP und Vererbung nutzen), machst das auf eine Art und Weise, die Dir nicht gefällt und die Dich nicht zum Erfolg führt.

Daraufhin verkündest Du: die OOP ist gescheitert.

Junge, so geht das nicht. Wenn Du nicht damit klar kommst, dann mach es anders oder ändere Dein Vorgehen.

Die OOP und auch die Vererbing sind nicht gescheitert, ganz im Gegenteil. Genauso wenig wie der Hammer:

Der Hammer ist nicht gescheitert, weil sich manche Leute damit auf den Daumen hauen ...
Wissen ist das einzige Gut, das sich vermehrt, wenn es geteilt wird ...

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Ist die Klassische OOP gescheitert?

Beitrag von pluto »

Eines Deiner Probleme: Du willst etwas machen (OOP und Vererbung nutzen), machst das auf eine Art und Weise, die Dir nicht gefällt und die Dich nicht zum Erfolg führt.

Eins möchte ich klar stellen: Ich habe kein Problem mit der Vererbung und mit der OOP, ich nutzte sie, wie sie sind. Ich wollte nur darüber Diskutieren.
Ich selbst finde die OOP sehr Praktisch, wenn sie richtig eingesetzt wird. Bei der Vererbung treten natürlich hin und wieder Probleme auf, die nicht immer was mit der Struktur sondern viel mehr mit dem Ziel zu tun haben.

Daraufhin verkündest Du: die OOP ist gescheitert.

Der Titel ist vielleicht etwas ungünstig gewählt, gebe ich zu, weil ich ja nicht die GANZE OOP meine, sondern nur die Vererbung.
Das wird wohl gerne überlesen. Ich meine wirklich NUR die Vererbung.

Die OOP und auch die Vererbing sind nicht gescheitert, ganz im Gegenteil. Genauso wenig wie der Hammer:

Die Werkzeuge haben sich auch Weiter Entwickelt, früher gab es mehr Steinwerkzeuge und analoge Werkzeuge, heute gibt bessere Werkzeuge.

Mir geht es darum, dass auch einezlene Konzepte der OOP weiter Entwickeln. Ich habe auch gehört, dass die LCL Techniken nutzt, wie sie in den 90ern Verwendet wurden, ob das nun schlecht oder gut ist, weiß ich nicht. Sie nutzt diese "alten" Techniken na und? Arduino ist auch alt und es gibt durchaus bessere Alternativen, aber mit gewissen nachteilen.
Z.B. STM32. Kostet praktisch in etwa so viel wie ein Arduino z.b. das STM32F303 Discovery Board, kann aber deutlich mehr. Trotzdem nutzte ich weiter hin Arduino warum?
ganz einfach: Arduino ist verbreiterter und man finde schneller Informationen und Beispiele. Im Gegensatz zu STM32

Ich kann es auch noch mal wieder holen: Ich selbst habe mit der OOP und der Vererbung kein Problem, sonst würde ich was anders nutzen, ich wollte nur über dieses Thema Diskutieren, was ja auch zum Teil ganz gut geklappt hat, gerade in den letzten Tagen. So habe ich mir das vorgestellt.

Ob das nun gescheitert ist oder nicht, muss vielleicht jeder selbst entscheiden, solange es keine Prüfungsaufgabe ist und sein Gehalt davon abhängt. Mir Persönlich ist es egal.
Ich verwende auch Lazarus und Arduino, obwohl beides als veraltet angesehen wird und Lazarus nicht gerade verbreitet ist. Ich nutzte es. So wie es ist.
ObjectPascal nutze ich aus verschiedenen Gründen.
MFG
Michael Springwald

Benutzeravatar
Niesi
Lazarusforum e. V.
Beiträge: 331
Registriert: So 26. Jun 2016, 19:44
OS, Lazarus, FPC: Linux Mint Cinnamon (Windows wenn notwendig), Lazarus 3.0 FPC 3.3.1

Re: Ist die Klassische OOP gescheitert?

Beitrag von Niesi »

pluto hat geschrieben:
Ob das nun gescheitert ist oder nicht, muss vielleicht jeder selbst entscheiden, solange es keine Prüfungsaufgabe ist und sein Gehalt davon abhängt. Mir Persönlich ist es egal.
Ich verwende auch Lazarus und Arduino, obwohl beides als veraltet angesehen wird und Lazarus nicht gerade verbreitet ist. Ich nutzte es. So wie es ist.
ObjectPascal nutze ich aus verschiedenen Gründen.



Wieso wird Lazarus als veraltet angesehen?
Und von wem?

Lazarus 2.0.2 ist topaktuell und dank OOP mit Vererbung "State of the art" ...
Wissen ist das einzige Gut, das sich vermehrt, wenn es geteilt wird ...

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Ist die Klassische OOP gescheitert?

Beitrag von m.fuchs »

kupferstecher hat geschrieben:
m.fuchs hat geschrieben:Tatsächlich sollte das einen Entwickler auch nicht stören. GetValue wird ja nur in einer Schicht aufgerufen, die über der Klasse liegt in der die Methode implementiert wird. In dieser Schichte sollte aber (sofern alles korrekt getrennt wurde) völlig unerheblich sein, wie diese Implementierung aussieht.
Die Abstrahierung ist ja gut. Aber, siehe oben, durch die Untertypisierung werden die involvierten Klassen versteckt.

Also eigentlich will man das ja.

Ein Beispiel: Ich habe ein Brettspiel als Programm umgesetzt. Für die Computergegner gibt es eine (abstrakte) Klasse namens TPlayer mit einer Methode CalculateNextTurn. Von dieser Klasse erben TRandomPlayer (in dessen überschriebener Methode der nächste Zug per Zufall ausgewählt wird), TCheatPlayer (berechnet den nächsten Zug auf Grund von Informationen über den menschlichen Spieler, die er laut Regeln gar nicht haben sollte) und TAggressivePlayer (der versucht immer den menschlichen Spieler zu attackieren, auch wenn ihm das schadet).

Dann stellen wir uns mal zwei Szenarien vor, in denen du als Entwickler an diesem Quellcode arbeitest.

1.) Du möchtest jeden Zug der gemacht wird zusätzlich in eine Logdatei schreiben. Du suchst die Stelle in der CalculateNextTurn aufgerufen wird und schreibst die Daten dort weg. Wie die Implementation in den einzelnen Player-Klassen aussieht ist dir völlig egal.

2.) Du möchtest dass der aggressive Computergegner sich nicht selbst komplett opfert um dem menschlichen Spieler zu schaden. Dann gehst du direkt in die Implementierung von TAggressivePlayer.CalculateNextTurn und änderst diese ab. Was in der darüberliegende Schicht passiert, mit all ihren Aufrufen, ist dir dabei völlig egal. Du änderst ja nicht die Schnittstelle der Methode, nur die Implementierung.

Das alles bedingt natürlich, eine dokumentierte Architektur und dazu gehören auch vernünftige Namen für alle Klassen und Methoden. Denn die sorgen dafür, dass man sich nicht die jeweilige Implementierung ansehen muss um zu wissen was sie tun.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Ist die Klassische OOP gescheitert?

Beitrag von m.fuchs »

pluto hat geschrieben:Ein weiters Beispiel: Wenn ich mir eine Code-Struktur ausdenke und sie in mehreren "Untis" Auslagern möchte, stoße ich früher oder später über die bekannte Einschränkung der Zirkulären Unit aufrufst. Da bleiben mir Praktisch nur zwei Möglichkeiten über: Entweder alles in einer Datei zu packen oder mit Include Dateien zu Arbeiten.

Ich schaue mal in meine Glaskugel und vermute, dass deine Projektarchitektur eher suboptimal ist.

pluto hat geschrieben:Ich habe schon oft eine Editor-Komponente Angefangen,[...]

Nimm es mir nicht übel, aber ich glaube sehr dass das dein Problem ist. Du fängst etwas sehr komplexes an und das ohne Planung.
Ich versuche bei jedem Projekt ab einer gewissen Größe mich mit anderen Entwicklern darüber auszutauschen. Und nach so einem Gespräch schmeiße ich mein erstes Konzept weg und mache ein Neues. Weil immer, und zwar wirklich immer durch so eine Diskussion neue Probleme auftauchen, die ich nicht auf dem Schirm habe.

Und wenn ich eine neue Technologie verwenden will/muss, dann bastele ich mir ersteinmal ein Testprojekt um das Ding ansatzweise zu verstehen. Probier es mal mit diesem Weg.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Antworten