Neue Themen als SAP Entwickler

Getting started ... Alles für einen gelungenen Start.
138 Beiträge • Vorherige Seite 2 von 10 (current) Nächste
138 Beiträge Vorherige Seite 2 von 10 (current) Nächste

Re: Neue Themen als SAP Entwickler

Beitrag von ralf.wenzel (Top Expert / 3863 / 197 / 276 ) »
DeathAndPain hat geschrieben:
04.09.2024 11:22
die globalen Variablen der Funktionsgruppe sind die Attribute. Womit einmal mehr das deutlich wird, was ich immer wieder gerne betone: Attribute sind nichts anderes als globale Variablen mit all ihren Nachteilen
Au, bitter, jetzt fangen wir aber eine Diskussion an. Ein Attribut ist von Haus aus semantisch etwas vollkommen anderes (spezifischeres) als eine Variable.

Beispiel: Ein Objekt bildet einen Beleg ab. Dann ist der Zustand des Beleges (gebucht, vorerfasst, storniert) durch Attribute festgelegt. Unter der Gruppe der in der Klasse verwendeten Variablen ist die Untergruppe der Attribute die, die den Zustand des Objektes beschreibt.

Das kann ein Funktionsbaustein gar nicht leisten, weil ich dann nur einen Beleg in meinem Programm abbilden könnte (wer macht das schon?), darum hat eine Funktionsgruppe auch keinen Zustand in diesem Sinne. Darum hat eine Funktionsgruppe globale Variablen, was etwas vollkommen anderes ist als eine Zustandsbeschreibung durch Attribute eines Objekts.

Ein Beispiel siehst du in den Applikationslogs. Fast jeder Kunde kapselt das in Klassen, um pro Applikationslog eine Instanz bilden zu können. Weil die Funktionsgruppe das nicht leisten kann, da gibt es immer nur EIN Applikationslog. Die Funktionsgruppe ist zustandslos, was du daran merkst, dass du die Lognummer immer mitgeben musst.

Welchen Nachteil hat das? Die Verwaltung der Applikationslogs muss der Aufrufer übernehmen. Das ist aber keine Kapselung. Kapselung heißt: Der Aufrufer sagt, was er will und das Objekt kümmert sich selbst um die Verwaltung.

Wenn man natürlich nur nicht nicht-instanziierbaren Klassen arbeitet, dann kann man sich das auch schenken, da hast du recht. Aber das ist ja nicht das, was man unter OO versteht. Objektorientierte Programmierung ohne Objekte ist irgendwie sinnfrei, das ist wie Autofahren ohne Auto.
DeathAndPain hat geschrieben:
04.09.2024 11:22
Durch die Attribute ist das Verhalten der Methoden nicht mehr durch das definiert, was man den Methoden über ihre Schnittstelle übergibt, und eine Methode kann sich mal so und mal völlig anders verhalten, je nachdem, was eine völlig andere Methode irgendwann früher mal irgendwo in einem Attribut abgelegt hat.
Richtig. Weil das Objekt einen Zustand hat. Man kann auch zustandslos programmieren, aber damit nimmt man ABAP OO eine wichtige Funktionalität.
DeathAndPain hat geschrieben:
04.09.2024 11:22
Vom Leistungsumfang sind Funktionsgruppen und statische Klassen ohne Vererbung also gleich. Wenn man das Detail hinzunimmt, dass Funktionsgruppen eigene Dynpros haben und RFC-tauglich sein können, können sie in bestimmten Hinsichten sogar ein bisschen mehr.
Naja, von den Dynpros wollte man ja eigentlich mal runter bei der SAP, aber das ist ein anderes Thema. Tatsächlich nutze ich Funktionsgruppen nur noch für Dynpros.

Aber von "gleicher Funktionalität" zu sprechen, finde ich schon gewagt. Versuch doch mal bitte eine Funktionsgruppe mit mehr als 99 Funktionsbausteinen anzulegen. Da gehen die Unterschiede doch schon los. Außerdem sind die Namen von Funktionsbausteinen global, das heißt: Ich kann den Funktionsbaustein "SAVE" nicht in drei verschiedenen Funktionsgruppen anzulegen (bei Klassen und Methoden geht das), weil Methodennamen nicht global definiert sind.

Ich könnte dir 20 Minuten Vortrag darüber halten, wo die Nachteile von Funktionsgruppen gegenüber zustandslosen Klassen sind. Und bei der Zustandsbehaftung fängt in meinen Augen OO erst richtig an.

Ralf

Folgende Benutzer bedankten sich beim Autor ralf.wenzel für den Beitrag:
tar

Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

gesponsert
Stellenangebote auf ABAPforum.com schalten
kostenfrei für Ausbildungsberufe und Werksstudenten


Re: Neue Themen als SAP Entwickler

Beitrag von tar (ForumUser / 33 / 8 / 17 ) »
Eine wesentliche Sache ist noch, dass sich Klassen eben auch flink lokal anlegen lassen und man nicht für jeden Fitzelreport das Dictionary zumüllt (zumüllen muss) - höchstens durch einen entsprechenden Include. Da habe ich dann aber lieber diesen 1 Include, der komplexe Logik für ein spezifisches Problem in einer Klasse kapselt als 37 unterschiedliche Dictionary-Objekte, die an nur 1 Stelle genutzt werden.

Folgende Benutzer bedankten sich beim Autor tar für den Beitrag (Insgesamt 2):
ralf.wenzelblack_adept


Re: Neue Themen als SAP Entwickler

Beitrag von black_adept (Top Expert / 4034 / 117 / 921 ) »
ralf.wenzel hat geschrieben:
04.09.2024 11:47
DeathAndPain hat geschrieben:
04.09.2024 11:22
die globalen Variablen der Funktionsgruppe sind die Attribute. Womit einmal mehr das deutlich wird, was ich immer wieder gerne betone: Attribute sind nichts anderes als globale Variablen mit all ihren Nachteilen
Au, bitter, jetzt fangen wir aber eine Diskussion an. Ein Attribut ist von Haus aus semantisch etwas vollkommen anderes (spezifischeres) als eine Variable.
Ralf
Gerade in dem von D&P benannten Ansatz Methoden abstrakter Klassen ( warum eigentlich abstrakt? Die kann auch ganz normal sein solange du nur statische Methode einbaust ) genau so zu verwenden wie Funktionsbausteine ist diese Analogie absolut korrekt.
Du hingegen denkst über die von dir offensichtlich hauptsächlich verwendete Methodik eine Klasse für eine Objektbeschreibung zu verwenden - und da ist ein Attribut tatsächlich mit mehr Informationen behaftet, auch wenn es technisch gesehen de facto trotzdem nur eine Variable ist.
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Neue Themen als SAP Entwickler

Beitrag von black_adept (Top Expert / 4034 / 117 / 921 ) »
DeathAndPain hat geschrieben:
03.09.2024 21:04
Ich zum Beispiel habe zwar Vererbung und Objekte verstanden, brauche aber in der Praxis praktisch nur abstrakte und finale Klassen, weil sich mir in meiner Praxis keine so komplexen Probleme stellen, dass Instanziierungen und Vererbungen mir Vorteile brächten.
Hast du nicht letztens irgendwo geschrieben, dass du Leute die noch IF statt SWITCH schreiben ( so wie ich ) als rückständig ansiehst und dass dir egal ist, ob die Mitarbeiter deine Programme warten können weil sie eventuell noch nicht auf deinem Wissensstand sind. Irgendwie hatte ich so das Gefühl, dass du dich fast diebisch freust, wenn dem so ist.
Aber dann muss ich gestehen dass ich nicht verstehe warum du nicht Richtung Instanziierung von Objekten gehst - das würde diesen Effekt doch noch mal drastisch verstärken.

Davon mal abgesehen muss ich dir völlig recht geben. Klassen als Utililtyklassen oder als ausgelagerte Modularisierung eines Programms ist eigentlich der Normalfall. Klar - es gibt manchmal die Notwendigkeit tatsächlich Richtung Vererbung zu gehen - aber die Häufigkeit dessen ist doch überschaubar wenn man es mit dem (meinem) Normalfall vergleicht.
Und bloß weil man etwas beherrscht heißt das noch lange nicht, dass es immer die beste Lösung ist. Hier verstehe ich z.B. Ralf nicht - ich habe immer das Gefühl als ob bei ihm DesignPatterns und Vererbung der Hammer sind und er dann all seine Probleme als Nägel ansieht. Ich gehe davon aus dass sich in seiner Werkzeugbank auch Zangen und Schraubendreher befinden, die inzwischen aber Spinnenweben ansetzen, weil er sich weigert über den OO-Tellerrand hinauszuschauen.
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Neue Themen als SAP Entwickler

Beitrag von ralf.wenzel (Top Expert / 3863 / 197 / 276 ) »
black_adept hat geschrieben:
04.09.2024 17:16
Hier verstehe ich z.B. Ralf nicht - ich habe immer das Gefühl als ob bei ihm DesignPatterns und Vererbung der Hammer sind und er dann all seine Probleme als Nägel ansieht. Ich gehe davon aus dass sich in seiner Werkzeugbank auch Zangen und Schraubendreher befinden, die inzwischen aber Spinnenweben ansetzen, weil er sich weigert über den OO-Tellerrand hinauszuschauen.
Nein, es gibt auch Zangen (Interfaces) und viele andere Werkzeuge. Das Wort "Vererbung" habe ich in diesem Thread nicht verwendet und ich benutze sie auch so oft gar nicht.

Entwurfsmuster hingegen gehören zum OO-Handwerkszeug, das ist für mich nicht verhandelbar. Schreib doch mal einen einfachen Unit-Test ohne Wrapper oder Interfaces.


Ralf
Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Re: Neue Themen als SAP Entwickler

Beitrag von DeathAndPain (Top Expert / 1868 / 238 / 404 ) »
Ralf hat geschrieben:Ein Attribut ist von Haus aus semantisch etwas vollkommen anderes (spezifischeres) als eine Variable.

Beispiel: Ein Objekt bildet einen Beleg ab. Dann ist der Zustand des Beleges (gebucht, vorerfasst, storniert) durch Attribute festgelegt. Unter der Gruppe der in der Klasse verwendeten Variablen ist die Untergruppe der Attribute die, die den Zustand des Objektes beschreibt.
Wie von black_adept schon eingewendet habe ich explizit "abstrakte Klassen" gesagt, also Klassen, die nicht instanziierbar sind. Bei solchen Klassen hast Du nicht mehrere Objekte für mehrere Belege (oder was auch immer). Natürlich kann man mit Instanziierung von Objekten Sachen machen, die über Funktionsgruppen hinausgehen. Das habe ich nie bestritten. Allerdings habe ich auf den Umstand hingewiesen, dass der Löwenanteil der Klassen, die ich von anderen Entwicklern zu sehen bekomme, nur genau einmal instanziiert wird. Dann aber ist die Instanziierung nutzlos und legt nur eine überflüssige Abstraktionsebene drüber, die die Performance senkt und das Programm schlechter lesbar macht.
Ralf hat geschrieben:Wenn man natürlich nur nicht nicht-instanziierbaren Klassen arbeitet, dann kann man sich das auch schenken, da hast du recht. Aber das ist ja nicht das, was man unter OO versteht. Objektorientierte Programmierung ohne Objekte ist irgendwie sinnfrei, das ist wie Autofahren ohne Auto.
Das stimmt nicht so ganz. Von der Lesbarkeit her sind PERFORM-Aufrufe einfach schrecklich, zumal sie bei ihren Parametern keine Formeln und keine Inline-Deklarationen erlauben und nicht funktional nutzbar sind. Allein dafür lohnt es sich schon, stattdessen Methoden zu verwenden. Die Aufteilung in DEFINITION und IMPLEMENTATION-Block halte ich für akademisch und nutzlos; das ist nur Schreibarbeit und erschwert die Lesbarkeit des Programms. Doch sogar diesen Preis bin ich für die um Längen übersichtlicheren Methodenaufrufe bereit zu zahlen. Wobei ich mir aber die Arbeit mache, die Parametrisierung meiner Methoden als Kommentar nochmal dorthin zu übertragen, wo sie meiner Meinung nach hingehört: an den Anfang der IMPLEMENTATION. Des Problems, dass solch Kommentar sich (anders als bei Funktionsbausteinen) nicht automatisch aktualisiert, wenn ich einen Parameter ändere, bin ich mir bewusst.
Ralf hat geschrieben:Man kann auch zustandslos programmieren, aber damit nimmt man ABAP OO eine wichtige Funktionalität.
Wie gesagt, wenn die Zustände sinnvoll genutzt und so gut dokumentiert werden, dass auch ein anderer Entwickler nachvollziehen kann, wofür genau die Attribute stehen und wo ihre Werte herkommen (können) und wann sie gesetzt werden, dann habe ich da keine Einwände. In der von mir erlebten Praxis sehe ich aber fast nur Ein-Objekt-Klassen mit als globalen Variablen (im negativsten Sinne des Wortes) verwendeten "Attributen".
Ralf hat geschrieben: Da gehen die Unterschiede doch schon los. Außerdem sind die Namen von Funktionsbausteinen global, das heißt: Ich kann den Funktionsbaustein "SAVE" nicht in drei verschiedenen Funktionsgruppen anzulegen (bei Klassen und Methoden geht das), weil Methodennamen nicht global definiert sind.
Das ist ein berechtigter Einwand, ebenso wie der Umstand, dass es keine lokalen Funktionsgruppen gibt. Aber ich bitte, sich zu erinnern, was ich eigentlich sagen wollte. Ich habe nie postuliert, dass man anstelle von Klassen besser Funktionsgruppen verwenden solle, sondern wollte nur auf die auffallenden Parallelen zwischen Funktionsgruppen und abstrakten Klassen aufmerksam machen. Das wirft ein Schlaglicht auf das Konzept der "Attribute". Für mich sind "Attribute" nichts anderes als schöngeredete globale Variablen. Die Nachteile sind nämlich genau dieselben: Sie sind nicht Bestandteil des Parameterinterfaces der Methoden, und wenn man das Programm nicht selber geschrieben hat, ist es sauschwer nachzuvollziehen, wo ihre Werte herkommen und wofür sie irgendwann später im Code noch alles verwendet werden (welche Auswirkungen eine Änderung also hat). Theoretisch müsste man das superakkurat dokumentieren. Praktisch habe ich in meinem ganzen Leben noch nicht ein OO-Programm gesehen, dessen Ersteller das gemacht hätte, erst recht nicht dort, wo man solch Doku unter allen Umständen wiederfindet, nämlich direkt in der Klassen- oder Methodendokumentation.
black_adept hat geschrieben:( warum eigentlich abstrakt? Die kann auch ganz normal sein solange du nur statische Methode einbaust )
Klar kann man sich auch bei herkömmlichen Klassen entscheiden, keine instanziierten Methoden einzubauen. Wenn ich aber das Postulat aufstelle, dass Funktionsgruppen weitestgehend äquivalent zu Klassen sind, dann ergibt es Sinn, dies auf abstrakte Klassen einzuschränken, denn Funktionsgruppen sind ja auch nicht instanziierbar. Man könnte auch "final" sagen, aber das bringt nicht viel, denn auch finale Klassen können von oben erben. Deshalb habe ich lieber explizit "ohne Vererbung" gesagt.
black_adept hat geschrieben:Hast du nicht letztens irgendwo geschrieben, dass du Leute die noch IF statt SWITCH schreiben ( so wie ich ) als rückständig ansiehst und dass dir egal ist, ob die Mitarbeiter deine Programme warten können weil sie eventuell noch nicht auf deinem Wissensstand sind. Irgendwie hatte ich so das Gefühl, dass du dich fast diebisch freust, wenn dem so ist.
So weit würde ich nicht gehen. Es geht mir nicht darum, Kollegen zu verarschen, und Code sollte gut lesbar und verständlich sein. Nur bin ich halt nicht bereit, Rücksicht darauf zu nehmen, wenn jemand immer noch nicht Befehle kennt, die vor einer ganzen Reihe von Jahren (mit 7.40) eingeführt worden sind. Wenn man auf solch Befehl stößt, kann man ja auch jederzeit die F1-Hilfe aufrufen und sich durchlesen, wie der Befehl funktioniert. Das finde ich durchaus zumutbar.

Genauso stelle ich mich ja auch nicht hin und sage, dass die Leute keine instanziierten Klassen schreiben sollen, weil ich nicht bereit wäre zu lernen, wie diese funktionieren. Das ist ein Wissen, das man heutzutage einfach haben muss und deswegen habe ich mich, wie gesagt, damit beschäftigt und kann solche Programme verstehen und solche Klassen benutzen. Ich würde sie auch selber schreiben, wenn ich vor einem Problem stehen würde, bei dem ich zu dem Schluss komme, dass sie hierfür der beste Weg und internen Tabellen (anstatt Objekten) überlegen sind. ich sehe aber praktische Vorteile von SWITCH und sogar REDUCE gegenüber "herkömmlichen" Lösungen. Das Programm wird dadurch nicht nur kürzer, sondern auch besser lesbar. (Tatsächlich ist es so, dass der kürzere Code zwar nicht immer, aber doch in den allermeisten Fällen auch der besser lesbare ist.) Und "IF" statt "SWITCH" finde ich schon insofern verwerflich, als da schon unter Release 3.1 "CASE" der bessere Ansatz gewesen wäre.

In meiner beruflichen Praxis hatte ich gerade wieder mit Programmen zu tun, die maximal 2 Jahre alt sind, bei denen mich Eclipse aber bei jeder Generierung mit Warnungen nervt, für die es kein Pragma gibt, weil darin HCM-spezifische Makros verwendet werden, in denen Felder vorkommen, deren Feldname einen Bindestrich enthält. Diese Makros waren (ebenso wie die ganze Programmiertechnologie, in deren Rahmen sie verwendet werden) schon im Jahre 2010 von der SAP als "veraltet" deklariert. Das HCM-Modul ist also nicht schuld; man kann das problemlos auch ordentlich und ohne Warnungen machen. Aber um das zu beheben, müsste ich das ganze Programm aufwendig und mit der Gefahr, neue Bugs einzuschleppen, von Grund auf logisch umbauen. Solchen Code heute noch neu zu programmieren, finde ich eine Frechheit.

Re: Neue Themen als SAP Entwickler

Beitrag von ralf.wenzel (Top Expert / 3863 / 197 / 276 ) »
DeathAndPain hat geschrieben:
03.09.2024 21:04
ralf.wenzel hat geschrieben:
02.09.2024 09:55
Ich bin ja kaum noch hier
Warum eigentlich? 😃
Ich hatte vergessen, wieviel Spaß diese Diskussionen machen - merke ich gerade 😉
DeathAndPain hat geschrieben:
05.09.2024 10:41
der Löwenanteil der Klassen, die ich von anderen Entwicklern zu sehen bekomme, nur genau einmal instanziiert wird. Dann aber ist die Instanziierung nutzlos
Das ist falsch. Ein Objekt ist nicht deshalb nutzlos, weil es das einzige ist.

Mach doch mal eine dependency injektion bei einer Funktionsgruppe. Schreibe einen Wrapper mit einer Funktionsgruppe. Nutze verschiedene Interfaces für eine Funktionsgruppe. Schreibe mal einen Unit-Test mit einer Funktionsgruppe, in der du die Persistenzschicht "weg-mockst".

Der eigentliche Vorteil eines Objektes ist aber, dass ich eine Einheit von Funktion und Variablen übergeben kann. Ich hatte das mal ausführlich anhand eines Buttons beschrieben: Ich habe den Button, sein Aussehen, seinen Namen UND seine Funktion in einem Objekt gespeichert und kann dieses Objekt geschlossen z. B. an einen ALV übergeben; und so dieselben (!) Buttons mit denselben (!) Funktionen in verschiedenen Programmen nutzen. Und dann sage ich "wenn auf einen Button geklickt wird, dann führe bitte die Methode RUN eben dieses Objektes (Buttons) aus, auf das gerade geklickt wurde. Der Aufrufer muss sich um nichts kümmern. Das ist "Kapseln auf Steroiden", viel besser als eine Funktionsgruppe das erlaubt. Schon deshalb, weil ich keine zwei Funktionsbausteine definieren kann, die RUN heißen.

Das alles geht mit einer Funktionsgruppe und auch mit einer statischen Klasse nicht. Und dann verwendet man Objekte, auch wenn man nur eines davon hat.
DeathAndPain hat geschrieben:
05.09.2024 10:41
Die Aufteilung in DEFINITION und IMPLEMENTATION-Block halte ich für akademisch und nutzlos; das ist nur Schreibarbeit und erschwert die Lesbarkeit des Programms.
Sorry, aber das ist falsch. Das trägt dem Umstand Rechnung, dass die Methodenschnittstelle ein Teil der Klassenschnittstelle sind. Eine Funktionsgruppe hat keine Schnittstelle.

DAS ist der Grund, warum die "tiefe Programmprüfung" mit Typprüfung der Parameter so aufwendig im SAP ist: Weil jeder Funktionsbaustein auseinandergenommen werden muss.

Das ist bei Klassen nicht so, weil schon in der Klassendefinition die Methodendefinitionen stehen (und eben auch die Typen der übergebenen Parameter).
DeathAndPain hat geschrieben:
05.09.2024 10:41
Wobei ich mir aber die Arbeit mache, die Parametrisierung meiner Methoden als Kommentar nochmal dorthin zu übertragen, wo sie meiner Meinung nach hingehört: an den Anfang der IMPLEMENTATION.
DeathAndPain hat geschrieben:
05.09.2024 10:41
Des Problems, dass solch Kommentar sich (anders als bei Funktionsbausteinen) nicht automatisch aktualisiert, wenn ich einen Parameter ändere, bin ich mir bewusst.
Und damit erhöhst du den Wartungsaufwand, obwohl die Methodenschnittstelle nur ein Mouseover entfernt ist und in der SAPGUI sogar oben eingeblendet wird.
DeathAndPain hat geschrieben:
05.09.2024 10:41
Wie gesagt, wenn die Zustände sinnvoll genutzt und so gut dokumentiert werden, dass auch ein anderer Entwickler nachvollziehen kann, wofür genau die Attribute stehen und wo ihre Werte herkommen (können) und wann sie gesetzt werden, dann habe ich da keine Einwände. In der von mir erlebten Praxis sehe ich aber fast nur Ein-Objekt-Klassen mit als globalen Variablen (im negativsten Sinne des Wortes) verwendeten "Attributen".
Wenn jemand schlecht programmiert, ist das kein Argument gegen das Paradigma. Ich kenne deutlich mehr schlecht programmierte prozedurale Programme als OO-Anwendungen. Das fängt schon damit an, dass ein Attribut sich durch seinen Namen identifizieren sollte. Ansonsten gibt es den Verwendungsnachweis.
DeathAndPain hat geschrieben:
05.09.2024 10:41
Das wirft ein Schlaglicht auf das Konzept der "Attribute". Für mich sind "Attribute" nichts anderes als schöngeredete globale Variablen.
Ich bleibe dabei: Ein Attribut ist eine im semantischen Kontext enger definierte Variable, weil sie einen Zustand beschreibt (was eine Variable nicht zwingend tut).

Ein Motorrad ist ein spezialisiertes Zweirad, aber nicht jedes Zweirad ein Motorrad.
DeathAndPain hat geschrieben:
05.09.2024 10:41
Die Nachteile sind nämlich genau dieselben: Sie sind nicht Bestandteil des Parameterinterfaces der Methoden, und wenn man das Programm nicht selber geschrieben hat, ist es sauschwer nachzuvollziehen, wo ihre Werte herkommen und wofür sie irgendwann später im Code noch alles verwendet werden (welche Auswirkungen eine Änderung also hat).
Das ist bei schlecht geschriebenem Coding immer so. Das liegt im Ermessen des Entwicklers, das so eindeutig zu machen, dass man sich eben nicht einen Wolf sucht.

Ralf
Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Re: Neue Themen als SAP Entwickler

Beitrag von black_adept (Top Expert / 4034 / 117 / 921 ) »
DeathAndPain hat geschrieben:
05.09.2024 10:41
Und "IF" statt "SWITCH" finde ich schon insofern verwerflich, als da schon unter Release 3.1 "CASE" der bessere Ansatz gewesen wäre.
CASE testet gegen Fixwerte, IF, ELSEIF, ELSE gegen boolsche Ausdrücke. Das ist wesentlich unterschiedlich und vergleichbar eher mit dem Unterschied zwischen SWITCH und COND. Alles hat seine Daseinsberechtigung und ich verwendet tatsächlich jeden dieser 4 Befehle immer dort wo es mir am sinnvollsten erscheint. Aber wenn ich die gleichberechtigte Wahl zwischen IF und SWITCH habe entscheide ich mich halt am häufigsten für IF. Und ich wette auch du verwendest IF noch bei IF <bedingung> {codeblock} ENDIF

Folgende Benutzer bedankten sich beim Autor black_adept für den Beitrag:
ralf.wenzel

live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Neue Themen als SAP Entwickler

Beitrag von DeathAndPain (Top Expert / 1868 / 238 / 404 ) »
Ralf hat geschrieben:Ich hatte vergessen, wieviel Spaß diese Diskussionen machen
Hoffentlich zieht Du auch die entsprechenden Konsequenzen. 😁
Ralf hat geschrieben:Mach doch mal eine dependency injektion bei einer Funktionsgruppe.
Wikipedia definiert eine Dependency Injection als "Entwurfsmuster, welches die Abhängigkeiten eines Objekts zur Laufzeit reglementiert". Es ist absurd, im Rahmen einer abstrakten Klasse von "Abhängigkeiten eines Objektes" zu sprechen, da abstrakte Klassen keine Objekte haben.
Ralf hat geschrieben:Schreibe einen Wrapper mit einer Funktionsgruppe. Nutze verschiedene Interfaces für eine Funktionsgruppe. Schreibe mal einen Unit-Test mit einer Funktionsgruppe
Mit einer abstrakten Klasse sollte das alles kein Problem sein. Dass dies syntaktisch bei Funktionsgruppen nicht vorgesehen ist, ändert nichts an den konzeptuellen Parallelen zwischen Funktionsgruppen und abstrakten Klassen. Wie gesagt, ich habe nie gefordert, Funktionsgruppen anstelle abstrakter Klassen zu verwenden.
Ralf hat geschrieben:Der eigentliche Vorteil eines Objektes ist aber, dass ich eine Einheit von Funktion und Variablen übergeben kann. Ich hatte das mal ausführlich anhand eines Buttons beschrieben: Ich habe den Button, sein Aussehen, seinen Namen UND seine Funktion in einem Objekt gespeichert und kann dieses Objekt geschlossen z. B. an einen ALV übergeben; und so dieselben (!) Buttons mit denselben (!) Funktionen in verschiedenen Programmen nutzen. Und dann sage ich "wenn auf einen Button geklickt wird, dann führe bitte die Methode RUN eben dieses Objektes (Buttons) aus, auf das gerade geklickt wurde. Der Aufrufer muss sich um nichts kümmern.
Das halte ich für einen komplett legitimen Einsatzzweck echter Objekte. Ich habe ja auch nie gesagt, dass es solche Einsatzzwecke nicht gibt, sondern nur, dass man sie in den Programmen, die ich typischerweise zu sehen bekomme, praktisch nicht zu Gesicht bekommt.
Ralf hat geschrieben:Das alles geht mit einer Funktionsgruppe und auch mit einer statischen Klasse nicht. Und dann verwendet man Objekte, auch wenn man nur eines davon hat.
Wenn Du ein OO-Programm schreibst, dann ergibt sich daraus praktisch zwingend das Vorhandensein mindestens einer lokalen Klasse. Die ist es, was Dein Programm ausmacht. Und jegliche lokalen Klassen und Methoden haben keinen Wiederverwendungswert für andere Programme.

Klar, was sich wiederverwenden lässt, gehört ins DDIC. Im Regelfall wirst Du aber kaum ein Programm schreiben können, das sich ausschließlich aus wiederverwendbaren Algorithmen speist und daher ganz ohne lokale Unterroutinen auskommt. Und wenn Du bei denen nicht auf das olle PERFORM zurückfallen möchtest, musst Du eine lokale Klasse verwenden. Die freilich in aller Regel abstrakt sein kann. Im START-OF-SELECTION ein Objekt zu erzeugen und dann (für den Rest des Programms) in dessen MAIN-Methode abzuspringen, finde ich idiotisch. Da reicht locker eine statische Klasse mit einem Absprung LC=>MAIN( ). Kürzer und besser lesbar.
Ralf hat geschrieben:
DeathAndPain hat geschrieben:Die Aufteilung in DEFINITION und IMPLEMENTATION-Block halte ich für akademisch und nutzlos; das ist nur Schreibarbeit und erschwert die Lesbarkeit des Programms.
Sorry, aber das ist falsch. Das trägt dem Umstand Rechnung, dass die Methodenschnittstelle ein Teil der Klassenschnittstelle sind. Eine Funktionsgruppe hat keine Schnittstelle.
Das meinte ich mit "akademisch". Was Du sagst, ist formal richtig, für die Praxis aber ohne Bedeutung. Interfaces benutzt Du für Deine Methodenparametrisierung. Auch der Implementation-Block der Klasse ist durch CLASS...ENDCLASS eingeschlossen. Es wäre völlig ausreichend, nur diesen Block zu haben, ihn in PUBLIC/PROTECTED/PRIVATE-Sektionen zu untgergliedern und am Beginn jeder Methode deren Parameter mit anzugeben. Dabei könnte man dann auch gleich die bescheuerte Regel beseitigen, dass Klassen bzw. ihre Methoden erst dann gefunden werden, wenn der Compiler sie erreicht hat. Das kann jede antike Formroutine besser; bei der ist es egal, wo im Code sie steht. Dann würde man auch die DEFINITION DEFERRED-Krücke nicht mehr brauchen.
Ralf hat geschrieben:Und damit erhöhst du den Wartungsaufwand, obwohl die Methodenschnittstelle nur ein Mouseover entfernt ist und in der SAPGUI sogar oben eingeblendet wird.
Ja, wie gesagt, den Preis des erhöhten Wartungsaufwands zahle ich für die bessere Lesbarkeit. Bei meinem Eclipse kommt nichts, wenn ich den Mauscursor über einen Methodennamen halte, da muss ich während des Mouseovers schon F2 drücken. Im SAPGui wird bei lokalen Klassen überhaupt nichts oben eingeblendet (und auch globale Klassen programmiere ich nicht in der SE24, weil mir ein schmaler Fensterschlitz für den Code nicht ausreicht. Diese Fenstergestaltung ist eine erkennbare Konzession an die fehlende Schnittstellenangabe in der Implementierung. Aber da ist Eclipse um Längen komfortabler. Da ist sogar die SE37 mit ihrem automatisch aktualisierten Kommentartext am Codebeginn komfortabler.).
Ralf hat geschrieben:Wenn jemand schlecht programmiert, ist das kein Argument gegen das Paradigma.
Wenn die Praxis jedoch zeigt, dass alle es tun (die SAP eingeschlossen), dann ist das ein sehr gewichtiges Argument dagegen.
Ralf hat geschrieben:Ich kenne deutlich mehr schlecht programmierte prozedurale Programme als OO-Anwendungen.
Ich nicht. Vor allem aber kann man sich bei schlecht programmierten prozeduralen Programmen meist noch erheblich besser mit dem Debugger retten und sich die Funktionsweise des Programms erarbeiten als bei einem mies programmierten OO-Programm. Im Debugger ist eine Struktur oder interne Tabelle allemal leichter zu verstehen als ein Objekt, das man nicht kennt.
Ralf hat geschrieben:Ich bleibe dabei: Ein Attribut ist eine im semantischen Kontext enger definierte Variable, weil sie einen Zustand beschreibt (was eine Variable nicht zwingend tut)
Und ich bleibe auch dabei: Dein Standpunkt hat hohen universitären Wert, ist vom praktischen Blickwinkel aus freilich anders zu bewerten. 😉
black_adept hat geschrieben:CASE testet gegen Fixwerte, IF, ELSEIF, ELSE gegen boolsche Ausdrücke.
Und die Rede war von SWITCH vs IF. Da SWITCH auch nur gegen Fixwerte testet, ist CASE eine hundertprozentige Alternative. Mehr habe ich nicht gesagt. Dass es auch COND gibt und dabei andere Verhältnisse vorliegen, ist unbestritten.

Re: Neue Themen als SAP Entwickler

Beitrag von ralf.wenzel (Top Expert / 3863 / 197 / 276 ) »
DeathAndPain hat geschrieben:
05.09.2024 12:56
Es ist absurd, im Rahmen einer abstrakten Klasse von "Abhängigkeiten eines Objektes" zu sprechen, da abstrakte Klassen keine Objekte haben.
Richtig, darum braucht man Objekte, auch wenn es einzelne sind.
DeathAndPain hat geschrieben:
05.09.2024 12:56
Ralf hat geschrieben:Der eigentliche Vorteil eines Objektes ist aber, dass ich eine Einheit von Funktion und Variablen übergeben kann.
Das halte ich für einen komplett legitimen Einsatzzweck echter Objekte. Ich habe ja auch nie gesagt, dass es solche Einsatzzwecke nicht gibt, sondern nur, dass man sie in den Programmen, die ich typischerweise zu sehen bekomme, praktisch nicht zu Gesicht bekommt.
Du hast bestritten, dass es sinnfrei ist, ein einzelnes Objekt zu verwenden. Aber gerade wenn ich die Einheit von Coding und Daten übergeben will, kommt man an einem Objekt nicht vorbei.
DeathAndPain hat geschrieben:
05.09.2024 12:56
Wenn Du ein OO-Programm schreibst, dann ergibt sich daraus praktisch zwingend das Vorhandensein mindestens einer lokalen Klasse.
Öhm - nein. Ich kann in einem Programm auch lauter globale Klassen aufrufen. Das ist bei mir in der Tat die Regel.
DeathAndPain hat geschrieben:
05.09.2024 12:56
Klar, was sich wiederverwenden lässt, gehört ins DDIC. Im Regelfall wirst Du aber kaum ein Programm schreiben können, das sich ausschließlich aus wiederverwendbaren Algorithmen speist und daher ganz ohne lokale Unterroutinen auskommt.
Also, ich schreibe fast alles ins DDIC, weil ich immer wieder gestaunt habe, wie viel sich wiederverwenden lässt, wenn man es nur abstrakt genug hält.
DeathAndPain hat geschrieben:
05.09.2024 12:56
Im START-OF-SELECTION ein Objekt zu erzeugen und dann (für den Rest des Programms) in dessen MAIN-Methode abzuspringen, finde ich idiotisch. Da reicht locker eine statische Klasse mit einem Absprung LC=>MAIN( ). Kürzer und besser lesbar.
Wenn man davon ausgeht, dass ein Objekt keine Vorteile bietet, muss man das so sehen, ja.
DeathAndPain hat geschrieben:
05.09.2024 12:56
Das meinte ich mit "akademisch". Was Du sagst, ist formal richtig, für die Praxis aber ohne Bedeutung.
Das bestreite ich. Einen Haufen Laufzeitfehler erzeugt man damit, indem man ein typfalsches Feld an einen Funktionsbaustein übergeben will. Weil kaum einer die "tiefe Prüfung" durchführt. Bei einer Methode fällt das sofort bei der einfachen Syntaxprüfung auf, ohne deren Korrektheit man gar nicht aktivieren kann.
DeathAndPain hat geschrieben:
05.09.2024 12:56
Interfaces benutzt Du für Deine Methodenparametrisierung.
Nein, Interfaces benutze ich, um einer Klasse bestimmte Eigenschaften zu geben.
DeathAndPain hat geschrieben:
05.09.2024 12:56
Auch der Implementation-Block der Klasse ist durch CLASS...ENDCLASS eingeschlossen. Es wäre völlig ausreichend, nur diesen Block zu haben, ihn in PUBLIC/PROTECTED/PRIVATE-Sektionen zu untgergliedern und am Beginn jeder Methode deren Parameter mit anzugeben.
Das würde dazu führen, dass die Syntaxprüfung die Klasse "aufschnüren" müsste wie das bei Funktionsgruppen der Fall ist. Weil man aber einen kleinen Block für die Definition hat und einen (deutlich größeren) für die Implementierung macht es einen erheblichen Vorteil, nur den kleinen Block bei der Prüfung einzubeziehen.

Darum wird die "tiefe Prüfung" bei der Syntaxprüfung von Funktionsgruppen nicht durchlaufen - weil es zu lange dauert, das ganze Paket aufzuschnüren und darin herumzusuchen.
DeathAndPain hat geschrieben:
05.09.2024 12:56
Ja, wie gesagt, den Preis des erhöhten Wartungsaufwands zahle ich für die bessere Lesbarkeit.
Naja, das mit der Lesbarkeit ist so eine Sache. Wenn ich eine lange Methode habe (und die lassen sich teilweise nicht verhindern), muss ich ständig scrollen, weil diese Kommentare nicht im Blick sind. Das Problem hab ich bei Funktionsbausteinen oft. Da ist es mir doch lieber, ich kann die per F2 oder Mouseover nachschlagen.

Dass es Lücken gibt (z. B. bei lokalen Klassen, wie du schon beschreibst) ist richtig.
DeathAndPain hat geschrieben:
05.09.2024 12:56
globale Klassen programmiere ich nicht in der SE24, weil mir ein schmaler Fensterschlitz für den Code nicht ausreicht. Diese Fenstergestaltung ist eine erkennbare Konzession an die fehlende Schnittstellenangabe in der Implementierung. Aber da ist Eclipse um Längen komfortabler.
Der "Schlitz" ist ein Schlitz, weil oben genau das steht, was du forderst: Die Methodensignatur.
DeathAndPain hat geschrieben:
05.09.2024 12:56
Wenn die Praxis jedoch zeigt, dass alle es tun (die SAP eingeschlossen), dann ist das ein sehr gewichtiges Argument dagegen.
Das sehe ich komplett anders. Ich möchte mich nicht einschränken lassen von Leuten, die das Prinzip nicht verstanden haben.

Nur, weil sich tausende jeden Tag mit dem Messer schneiden, lasse ich mir meins doch nicht wegnehmen mit dem Hinweis, Messer seien gefährlich.
DeathAndPain hat geschrieben:
05.09.2024 12:56
Ralf hat geschrieben:Ich kenne deutlich mehr schlecht programmierte prozedurale Programme als OO-Anwendungen.
Ich nicht. Vor allem aber kann man sich bei schlecht programmierten prozeduralen Programmen meist noch erheblich besser mit dem Debugger retten und sich die Funktionsweise des Programms erarbeiten als bei einem mies programmierten OO-Programm. Im Debugger ist eine Struktur oder interne Tabelle allemal leichter zu verstehen als ein Objekt, das man nicht kennt.
Also, das kann ich fast gar nicht glauben, weil in JEDEM System in dem ich bisher gearbeitet habe, ist die Zahl prozeduraler Programm DEUTLICH höher als die Zahl objektorientierter Codingeinheiten. Da wäre es erstaunlich, wenn ein deutlich höherer Prozentsatz prozeduraler Programme signifikant ordentlicher programmiert wären als ihre OO-Pendants.

Wie viele 3000 Zeilen-Programme kenne ich, wo ein globales X vom Himmel fällt und alles ändert?

Ralf
Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Re: Neue Themen als SAP Entwickler

Beitrag von ralf.wenzel (Top Expert / 3863 / 197 / 276 ) »
*Huch* Doppelpost - wie geht das denn?
Zuletzt geändert von ralf.wenzel am 05.09.2024 13:20, insgesamt 1-mal geändert.
Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Re: Neue Themen als SAP Entwickler

Beitrag von black_adept (Top Expert / 4034 / 117 / 921 ) »
DeathAndPain hat geschrieben:
05.09.2024 12:56
Das meinte ich mit "akademisch". Was Du sagst, ist formal richtig, für die Praxis aber ohne Bedeutung. Interfaces benutzt Du für Deine Methodenparametrisierung. Auch der Implementation-Block der Klasse ist durch CLASS...ENDCLASS eingeschlossen. Es wäre völlig ausreichend, nur diesen Block zu haben, ihn in PUBLIC/PROTECTED/PRIVATE-Sektionen zu untgergliedern und am Beginn jeder Methode deren Parameter mit anzugeben. Dabei könnte man dann auch gleich die bescheuerte Regel beseitigen, dass Klassen bzw. ihre Methoden erst dann gefunden werden, wenn der Compiler sie erreicht hat. Das kann jede antike Formroutine besser; bei der ist es egal, wo im Code sie steht. Dann würde man auch die DEFINITION DEFERRED-Krücke nicht mehr brauchen.
Der Grund für die Trennung in Definition und Implementierung ist, dass es dadurch möglich ist das Coding in vererbten Methoden auszutauschen.
Und was den Compiler und "Definition Deferred" angeht: Das Problem hat man eigentlich nur bei einem 1-Pass-Compiler und du hast das gleiche Problem auch an anderer Stelle weil du Variablen erst dann im Programm ansprechen kannst, nachdem (später im Code) sie definiert wurden. Und das obwohl sie auch schon im compilierten Programm vorhanden sind, wie man im Debugger sehen bzw da man sie mit einem Dirty Assign auch schon vor der Zeile mit der Definition ändern kann.

Folgende Benutzer bedankten sich beim Autor black_adept für den Beitrag:
ralf.wenzel

live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Neue Themen als SAP Entwickler

Beitrag von tar (ForumUser / 33 / 8 / 17 ) »
DeathAndPain hat geschrieben:
05.09.2024 12:56
Im START-OF-SELECTION ein Objekt zu erzeugen und dann (für den Rest des Programms) in dessen MAIN-Methode abzuspringen, finde ich idiotisch. Da reicht locker eine statische Klasse mit einem Absprung LC=>MAIN( ). Kürzer und besser lesbar.
Wozu braucht man im Report eine zusätzliche Main-Methode? Das ist an sich dubios.

Beispielsweise würde das (vereinfacht) so aussehen:

Code: Alles auswählen.

parameters p_user type xubname.

start-of-selection.
  data(user) = new lcl_user( p_user ).
  data(used_user_passwords) = user->get_password_history( ).
  " ... anzeigen, per Mail senden, Log schreiben, whatever ...
In der Hilfsklasse zum Benutzer gibt's also private Methoden (bspw. zum Selektieren allgemeiner Nutzerdaten und Befüllen der Objekt-Eigenschaften), die direkt (und ggf. einmalig) bereits im Constructor aufgerufen werden. Das Objekt baut sich also selbst anhand dem übergebenen Nutzer-Namen (der hier als ID fungiert) auf.

Mehr sollte hier erstmal überhaupt nicht passieren und für den Entwickler, der dieses Programm verstehen und ggf. anpassen muss, sind die zugehörigen Details soweit auch erstmal uninteressant. Er erkennt sofort: es gibt ein Benutzer-Objekt, was die Passwort-Historie des Nutzers zurückgibt.

Wenn es wg. der Komplexität weiterer Klassen bedarf, kann man dann entweder PUBLIC Properties oder besser GETTER- (hier für die Passwort-Historie) und ggf. auch SETTER-Methoden nutzen (bspw. zum Sperren/Entsperren) und dabei auch direkt Klasse A an den Constructor der Klasse B weiterreichen, usw. Ein derartiger Ansatz reduziert auch notwendige Code-Kommentare, weil der Code sich bereits größtenteils selbsterklärt.

Eine irgendwie gerartete Main()-Methode einer rein statischen Klasse "LC" liefert dementgegen genau gar nichts an Informationsgehalt. Ganz schlecht wird es, wenn dort wie üblich einfach nur prozedural und durchweg mit PUBLIC Properties hantiert wird. Das ist einfach nur schlechtes Coding, faul programmiert, hingeschissen.
DeathAndPain hat geschrieben:
05.09.2024 12:56
Vor allem aber kann man sich bei schlecht programmierten prozeduralen Programmen meist noch erheblich besser mit dem Debugger retten und sich die Funktionsweise des Programms erarbeiten als bei einem mies programmierten OO-Programm. Im Debugger ist eine Struktur oder interne Tabelle allemal leichter zu verstehen als ein Objekt, das man nicht kennt.
Das ist beides gruselig. Unverständliches kommt aber eher daher, dass man eine schlechte Codebasis über Jahre oder Jahrzehnte immer weiter ergänzt, statt zwischendurch mal grundlegend überarbeitet hat.

Allein die SAPMV45A: mehr als 500 Zeilen reine INCLUDES, die meist selbst weitere INCLUDES enthalten. Endlose "globale" Deklarationen und zwischendurch hier und da eine random Klasse. Wie komplex doch so ein Auftrag sein kann. Viel Spaß beim Debuggen.

Auch die ganzen Enhancements, Customer Exits und BAdIs, Makros und das Hantieren mit Kopfzeilen. Dabei könnte man mit OO klare Verantwortlichkeiten zu eindeutig benamten Klassen und Methoden samt generell dynamischer Event-Handler umsetzen, deren Ausprägungen der Kunde an einer zentralen Stelle selbst definieren könnte (statt einzelner, gnädigerweise zur Verfügung gestellter BAdIs). Aber nej: das würde ja umfassende Flexibilität bedeuten und möglicherweise gar die Komplexität verringern. Da bleibt man lieber bei FORMs und checkt darin, ob irgendwann mal die GO_CLASS_AM_ARSCH instanziiert wurde.

Folgende Benutzer bedankten sich beim Autor tar für den Beitrag:
ralf.wenzel


Re: Neue Themen als SAP Entwickler

Beitrag von ralf.wenzel (Top Expert / 3863 / 197 / 276 ) »
Das mache ich jetzt mal ohne Zitat, weil ich das am iPhone diktieren muss:

Reine Setter- und Gettermethoden entsprechen eigentlich nicht im Stand der Technik. Denn hierzu muss man wissen, wofür die einzelnen (oft privaten) Attribute in der Klasse notwendig sind. Das sollte den Aufrufe aber eigentlich schon nicht interessieren.

Der bekommt eine Methode, die den Zustand des Objektes ändert. Dazu ist es nicht notwendig, dass ich als Aufrufer weiß, welches Attribut oder welche Attributskombination diesen Zustand steuert. Genau das ist aber notwendig, wenn ich per Setter-Methode das Attribut direkt manipuliere bzw. per Getter-Methode direkt auslese.

Um ein eBook in den Zustand „gelesen“ zu setzen, ist es schlüssiger, die Methode „read_ebook( )“ aufzurufen statt eine Methode „set m_flag_read( ), zumal neben dem Setzen des Flags noch weitere Operationen notwendig sein können, um den konsistenten Zustand „gelesen“ zu erreichen und private Attribute von der Namensgebung her nicht immer selbsterklärend sind.

Ralf

Folgende Benutzer bedankten sich beim Autor ralf.wenzel für den Beitrag:
tar

Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Re: Neue Themen als SAP Entwickler

Beitrag von DeathAndPain (Top Expert / 1868 / 238 / 404 ) »
Ralf hat geschrieben:Du hast bestritten, dass es sinnfrei ist, ein einzelnes Objekt zu verwenden. Aber gerade wenn ich die Einheit von Coding und Daten übergeben will, kommt man an einem Objekt nicht vorbei.
Warum soll das eine abstrakte Klasse nicht können? Die hat auch (statische) Attribute und Methoden, in denen Du das Gleiche unterbringen kannst wie in den Attributen einer Objektinstanz. Aber halt nur einmal. Was völlig ausreicht, wenn "nur einmal" genau das ist, was Du brauchst. Man kann eine abstrakte Klasse betrachten wie eine herkömmliche Klasse mit einer impliziten Instanz. Das Einzige, was Du bei einer statischen Klasse naturgemäß nicht hast, ist ein impliziter Konstruktor. Aber den kannst Du ja bei Bedarf leicht durch eine factoryartige Initialisierungsmethode ersetzen.
Ralf hat geschrieben:Also, ich schreibe fast alles ins DDIC, weil ich immer wieder gestaunt habe, wie viel sich wiederverwenden lässt, wenn man es nur abstrakt genug hält.
Ich schreibe auch öfter mal eine globale Klasse, weil ich mir denke "das kann man bestimmt noch mal wieder gebrauchen". Aber wenn ich es ein halbes Jahr später wirklich mal wieder brauche, dann habe ich in vielen Fällen längst vergessen, dass ich solch Klasse mal geschrieben habe. Ich staune immer wieder, was für (von mir selber stammende) nützliche Klassen und Methoden ich immer mal wieder finde und denke mir dann: "Das hättest Du in Programm xy gut gebrauchen können, wenn Du Dich daran erinnert hättest."

Und Du schreibst alles und seinen Hund ins DDIC und behauptest, dass Du da den Überblick behältst und die Methoden alle wiederfindest, wenn Du mal vor einem ähnlichen Problem stehst?!? Das kann ich mir nicht wirklich vorstellen.
Ralf hat geschrieben:Das bestreite ich. Einen Haufen Laufzeitfehler erzeugt man damit, indem man ein typfalsches Feld an einen Funktionsbaustein übergeben will. Weil kaum einer die "tiefe Prüfung" durchführt. Bei einer Methode fällt das sofort bei der einfachen Syntaxprüfung auf, ohne deren Korrektheit man gar nicht aktivieren kann.
Das liegt an der zweifelhaften Entscheidung der SAP, dass bei Funktionsbausteinaufrufen der Name letztlich immer indirekt übergeben wird. Deswegen muss man ihn ja auch immer in Hochkommata stellen. Klar, bei einer indirekten Namensangabe kann keine Syntaxprüfung zum Compile-Zeitpunkt erfolgen. Mit der Funktionalität von Funktionsbausteinen hat das aber nicht viel zu tun.
Ralf hat geschrieben:Nein, Interfaces benutze ich, um einer Klasse bestimmte Eigenschaften zu geben.
Bitte nenne mal ein praktisches Beispiel, damit die Sache konkret wird.
Ralf hat geschrieben:Das würde dazu führen, dass die Syntaxprüfung die Klasse "aufschnüren" müsste wie das bei Funktionsgruppen der Fall ist. Weil man aber einen kleinen Block für die Definition hat und einen (deutlich größeren) für die Implementierung macht es einen erheblichen Vorteil, nur den kleinen Block bei der Prüfung einzubeziehen.
Bei Rechnern im unteren dreistelligen Megahertzbereich, wie sie üblich waren, als es Funktionsgruppen schon gegeben hat, mag das - möglicherweise - mal ein Thema gewesen sein, aber heutige Maschinen lachen sich über die Rechenlast für solch Syntaxprüfung doch schlapp. Eigentlich sind Syntaxprüfungen aber noch nie etwas gewesen, was nennenswert Rechenaufwand erfordert. Deswegen macht Eclipse sie ja sogar in Echtzeit, während Du tippst. Da musst Du noch nicht mal zu kompilieren versuchen.
Ralf hat geschrieben:Darum wird die "tiefe Prüfung" bei der Syntaxprüfung von Funktionsgruppen nicht durchlaufen - weil es zu lange dauert, das ganze Paket aufzuschnüren und darin herumzusuchen.
So richtig habe ich nicht verstanden, welche Syntaxprüfung Du hier genau meinst. Die wenn man die Funktionsgruppe kompiliert? Da wird das Rahmenprogramm kompiliert und auch alle darin enthaltenen Includes geprüft. Oder wenn man sie von irgendwoher aufruft? Da hast Du den indirekten Aufruf, der eine Prüfung zur Compile-Zeit unmöglich macht. Auch wenn die SAP das selber nicht ganz konsequent einhält, wenn man sich überlegt, dass man beim Tippen (sowohl in Eclipse als auch in der SE38) mit Strg+Space eine Eingabeschablone für den FB erhalten kann, nachdem man CALL FUNCTION 'Bausteinname' getippt hat.
Ralf hat geschrieben:Naja, das mit der Lesbarkeit ist so eine Sache. Wenn ich eine lange Methode habe (und die lassen sich teilweise nicht verhindern), muss ich ständig scrollen, weil diese Kommentare nicht im Blick sind. Das Problem hab ich bei Funktionsbausteinen oft. Da ist es mir doch lieber, ich kann die per F2 oder Mouseover nachschlagen.
Ich hingegen empfinde vor allem Medienbrüche als schlimm. Wenn ich rasch eine Parametrisierung nachschauen muss, während ich in der Methode tippe, dann kann ich rasch zweimal die Bild-hoch-Taste drücken, gucken, dann wieder zweimal Bild runter und weitertippen. Das ist kein Zeitaufwand. Der entsteht immer dann, wenn ich zur Maus greifen muss, mich orientieren muss, wo sich mein Mauscursor befindet, dann damit hantieren muss und am Ende wieder die Maushand zur Tastatur zurückbewegen muss.
Ralf hat geschrieben:Das sehe ich komplett anders. Ich möchte mich nicht einschränken lassen von Leuten, die das Prinzip nicht verstanden haben.

Nur, weil sich tausende jeden Tag mit dem Messer schneiden, lasse ich mir meins doch nicht wegnehmen mit dem Hinweis, Messer seien gefährlich.
Der Prozentsatz ist aber durchaus bedeutsam. Wenn man den Leuten allen Pistolen geben würde, dann würden sicherlich auch viele verantwortungsbewusst damit umgehen. Aber doch ein geringerer Prozentsatz als bei Messern. Also verbietet man die Pistolen.

Gleichwohl habe ich ja nicht gesagt, dass ich instanziierte Klassen verbieten möchte. Vielleicht aber wäre es gut, wenn die Pflege der Doku zum Objekt ein Pflichtfeld sein würde. Klar kann man da einfach ein X eintragen und sichern. Ich glaube aber, wenn die Leute gezwungen werden, da was reinzuschreiben, dann werden sie in vielen Fällen doch das eine oder andere hilfreicht Wort zusätzlich schreiben. Das Gleiche gilt auch für Attribute.
Ralf hat geschrieben:Also, das kann ich fast gar nicht glauben, weil in JEDEM System in dem ich bisher gearbeitet habe, ist die Zahl prozeduraler Programm DEUTLICH höher als die Zahl objektorientierter Codingeinheiten.
Damit stellst Du auf absolute Zahlen ab und hast damit recht. Das geht aber nicht in die Richtung, in der Du nach meinem Verständnis eigentlich argumentieren wolltest, nämlich dass prozedurale Programme eher schlampig geschrieben seien als objektorientierte. Bei dem Ansatz musst Du nämlich prozentual vergleichen und nicht in absoluten Zahlen, und dann glaube ich keineswegs, dass die objektorientierten Programme besser dastehen. Bei prozeduralen Programmen hat sich zumindest mal die Verhaltensweise weitgehend durchgesetzt, globale Variablen zu meiden. Dadurch, dass diese in OO zu "Attributen" geadelt worden sind, hat sich nach meiner Erfahrung die diesbezügliche Disziplin bei objektorientierten Programmen dramatisch verschlechtert. Was die Leute da machen, hat mit Zuständen, die das Objekt beschreiben sollen, meist nicht viel zu tun. Es wird einfach aus Bequemlichkeit mit klassenglobalen Feldern gearbeitet und fertig.
black_adept hat geschrieben:Der Grund für die Trennung in Definition und Implementierung ist, dass es dadurch möglich ist das Coding in vererbten Methoden auszutauschen.
Das würde man auch anders hinbekommen. Auch in einer einblöckigen Klasse (anstelle der beiden Blöcke "DEFINITION" und "IMPLEMENTATION") könnte man bei der Klassendefinition eine "INHERITING FROM"-Syntax verwenden. Und dann könnte man einfach sagen, jede Methode der Oberklasse, die in diesem einen Block nicht vorkommt, verwendet den Ursprungscode. Wenn einem das kosmetisch nicht gefällt (weil eine erbende Klasse dadurch Methoden hätte, die in der Klasse selbst nirgendwo sichtbar sind), dann könnte man auch eine Syntax METHOD geerbte_methode INHERITED definieren, die deutlich macht, dass die Methode als geerbter Code zur Verfügung steht. Da müsste man sich überlegen, was am Schönsten ist, aber das sind alles lösbare Probleme.
black_adept hat geschrieben:Und was den Compiler und "Definition Deferred" angeht: Das Problem hat man eigentlich nur bei einem 1-Pass-Compiler und du hast das gleiche Problem auch an anderer Stelle weil du Variablen erst dann im Programm ansprechen kannst, nachdem (später im Code) sie definiert wurden.
Letzteres finde ich auch nicht so schön. Und so "1-Pass" kann der ABAP Compiler gar nicht sein, denn er akzeptiert PERFORM-Aufrufe vor der Form, meckert aber, wenn es die Form gar nicht gibt. Ich verstehe nicht, weshalb das bei Klassen (oder, wie Du richtig sagst, auch Feldern) nicht möglich sein soll.
tar hat geschrieben:Wozu braucht man im Report eine zusätzliche Main-Methode?
Aus zwei Gründen: Erstens kannst Du dann in START-OF-SELECTION lokale Felder definieren, die nicht global und damit in den gerufenen Untermethoden nicht vorhanden sind (saubere Kapselung). Und zweitens brauchst Du dann nicht bei jedem Methodenaufruf den Namen der Klasse davorzuschreiben. Das sieht dann z.B. so aus:

Code: Alles auswählen.

START-OF-SELECTION.

lc=>main( ).

CLASS lc IMPLEMENTATION.
  METHOD lc.
    DATA(nutzdaten) = daten_einlesen( ).
    daten_ausgeben( nutzdaten ).
  ENDMETHOD.

  METHOD daten_einlesen.
  ...
Finde ich sehr hübsch und gut lesbar.
tar hat geschrieben:Beispielsweise würde das (vereinfacht) so aussehen:
Und sowohl Dein eininstanziges Objekt user als auch die interne Tabelle user_used_passwords wären global. Sowas finde ich Mist. Vor allem, wenn dann die Methoden gerufen werden, die den von dir mit "... anzeigen, per Mail senden, Log schreiben, whatever ..." beschriebenen Teil implementieren, ist dann user_used_passwords sicherlich auch nicht Bestandteil der Parameterschnittstelle. Sowas finde ich hässlich und unsauber.
tar hat geschrieben:Eine irgendwie gerartete Main()-Methode einer rein statischen Klasse "LC" liefert dementgegen genau gar nichts an Informationsgehalt. Ganz schlecht wird es, wenn dort wie üblich einfach nur prozedural und durchweg mit PUBLIC Properties hantiert wird. Das ist einfach nur schlechtes Coding, faul programmiert, hingeschissen.
Tatsächlich sind die Methoden meiner obenstehenden LC-Klasse bis auf MAIN alle privat. Ausnahmen gibt es allenfalls dann, wenn durch Dynprotechnologie weitere Aufrufe von außerhalb der Klasse erfolgen müssen (beispielsweise bei einem Doppelklick ins erzeugte ALV, wo dann die Event-Handler-Klasse des ALVs meine lokale Klasse rufen muss).
tar hat geschrieben:Das ist beides gruselig. Unverständliches kommt aber eher daher, dass man eine schlechte Codebasis über Jahre oder Jahrzehnte immer weiter ergänzt, statt zwischendurch mal grundlegend überarbeitet hat.
Ich kann mich an einen OO-ABAP-programmierenden Kollegen erinnern, dessen Methodenschnittstellen waren praktisch immer leer. In der Folge war sein Programm für Außenstehende praktisch nicht wartbar, und wir hatten die größten Probleme, als er das Unternehmen verlassen hat. Nun wirst Du sagen, dass das ein schlechter Mann gewesen ist, und da hast Du auch recht, aber das ist die Realität, wie ich sie erlebe. Viele Leute schreiben schlechten Code, ob es unsereins gefällt oder nicht. Und bei prozeduraler Programmierung hat man da noch eher eine Chance, das Programm reverse zu engineeren und irgendwie doch noch zu begreifen, wie es funktioniert.
Ralf hat geschrieben:Reine Setter- und Gettermethoden entsprechen eigentlich nicht im Stand der Technik. Denn hierzu muss man wissen, wofür die einzelnen (oft privaten) Attribute in der Klasse notwendig sind. Das sollte den Aufrufe aber eigentlich schon nicht interessieren.
Das habe ich mir schon immer gedacht. Insofern Applaus für dieses Statement.

Vergleichbare Themen

0
Antw.
1888
Views
OO-Themen die in anderen Threads OT sind
von black_adept » 23.08.2018 09:01 • Verfasst in ABAP Objects®
10
Antw.
14076
Views
Suche Videotutorials zu folgenden Themen
von Up4Anything » 02.03.2011 14:01 • Verfasst in Tutorials & Cookbooks
2
Antw.
3005
Views
Aktuelle Themen / Forschungstrends im SAP Bereich
von OnkelSAP » 28.03.2011 12:35 • Verfasst in SAP - Allgemeines
18
Antw.
4470
Views
Entwickler vs Berater
von BecomingAnAbapGuru » 05.07.2021 09:21 • Verfasst in Tips + Tricks & FAQs
4
Antw.
9320
Views
SAP-Entwickler Gehalt ?
von Frank59 » 17.12.2006 15:41 • Verfasst in SAP - Allgemeines

Aktuelle Forenbeiträge

Wissensdatenbank
vor 23 Minuten von ewx 15 / 1896
Get und Set
vor 4 Stunden von msfox 17 / 3190
Neue Themen als SAP Entwickler
vor 18 Stunden von ralf.wenzel 138 / 18642

Newsletter Anmeldung

Keine Beiträge verpassen! Wöchentlich versenden wir lesenwerte Beiträge aus unserer Community.
Die letzte Ausgabe findest du hier.
Details zum Versandverfahren und zu Ihren Widerrufsmöglichkeiten findest du in unserer Datenschutzerklärung.

Aktuelle Forenbeiträge

Wissensdatenbank
vor 23 Minuten von ewx 15 / 1896
Get und Set
vor 4 Stunden von msfox 17 / 3190
Neue Themen als SAP Entwickler
vor 18 Stunden von ralf.wenzel 138 / 18642