Gehaltsvorstellungen SAP ABAP-Entwickler Thema ist als GELÖST markiert

Getting started ... Alles für einen gelungenen Start.
114 Beiträge Vorherige Seite 4 von 8 (current) Nächste
114 Beiträge Vorherige Seite 4 von 8 (current) Nächste

Re: Gehaltsvorstellungen SAP ABAP-Entwickler

Beitrag von black_adept (Top Expert / 3243 / 54 / 568 ) » 26. Sep 2018 12:42

DeathAndPain hat geschrieben:
ewx hat geschrieben:Aber die Aussage, "dass bei der kleinsten Verwendung von OO-Elementen [...] sofort die ABAP-Performance eklatant einknickt." ist definitiv falsch.
Jein.[...]. Der einzelne Befehl wird mit OO erheblich langsamer.
Vielleicht liegt hier ja insgesamt ein Sprachproblem vor. Nenne doch mal eine (von mir aus auch sehr kurze) Liste aus ein paar Befehlen, die durch OO langsamer werden. ( Und dazu zählt nicht der TRY-CATCH-Block, weil dies ein OO-Konstrukt ist welches natürlich nicht langsamer werden kann [ langsamer als was? ]. Meinst du vielleicht, dass eine Folge von Befehlen aus dem OO-Kontext langsamer ist als eine klassische Befehlsfolge mit anderen Befehlen? )
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de


Re: Gehaltsvorstellungen SAP ABAP-Entwickler

Beitrag von ralf.wenzel (Top Expert / 3416 / 149 / 220 ) » 26. Sep 2018 14:39

DeathAndPain hat geschrieben:
Ralf hat geschrieben:Das ist so nicht richtig, wenn man die Funktionalität dagegen hält.
Du beharrst darauf, nicht beim Thema zu bleiben. Dass OO viele Funktionalitäten bietet, die ohne nicht (bzw. nur auf Umwegen) erreichbar sind, ist unbestritten, hat aber mit der Performance nichts zu tun. Und wenn ich Daten für eine komplizierte Liste bereitstellen muss, bei der ich aus vielen Tabellen mit vielen Iterationen die Ergebniszeilen zusammenbasteln muss, dann nützen mir Kaskaden von Logs nichts, aus denen ich ersehen kann, an welcher Stelle mein Programm wegen Timeouts abgebrochen hat. Dann brauche ich einfach effizienten Code ohne Ballast.
Was meinst du mit "ohne Ballast"? Ok, bei einem READ hast du einen sy-subrc. Und was machst du damit? Irgendwas, was Laufzeit kostet. Klar, du kannst ihn einfach nicht auswerten, aber dann knallt es schnell. Dann dumpt dein Programm immerhin schnell. Keine Logik ist immer schneller als Logik.
DeathAndPain hat geschrieben:
Ralf hat geschrieben:Nein. Außer, dass beide aus ABAP-Coding bestehen, gibt es praktisch keine Parallelen.
Da bin ich anderer Meinung.


Deine Meinung ist völlig irrelevant, weil es auf Fakten ankommt. Jedes Rahmenprogramm kann Teilprogramme beinhalten, die man von außen aufrufen kann (das geht sogar bei FORM-Routinen). Und nein, du kannst keine *Zustände* definieren, sondern *einen Zustand*. Bei den Dokumentationsmöglichkeiten unterscheiden sich Funktionsgruppen kaum von Klassen.
DeathAndPain hat geschrieben:Jein. Ich halte das für eine Blickwinkelfrage. Der einzelne Befehl wird mit OO erheblich langsamer.
Eine solche Behauptung möchtest du belegen.
DeathAndPain hat geschrieben:Wenn ich in meinem Programm mit seinem vielen Iterationen über die internen Tabellen mit den Teilwerten jetzt aber anfangen würde, aus den internen Tabellen Containerobjekte zu machen und - überspitzt formuliert - jeden READ TABLE durch den Aufruf einer GETter-Methode zu ersetzen, die sich dann über diverse Dereferenzierungen den Wert besorgt, dann habe ich keine Zweifel, dass das absolut verheerend für die Programmlaufzeit wäre.
Soso, du bezweifelst und das reicht dir. Wenn man weiß, wie man einen gescheiten Iterator mit Sprungvorhersage baut (das habe ich schon gemacht -- ganz im Gegenteil zu dir), kann der sogar *schneller* sein als ein einfacher READ.
DeathAndPain hat geschrieben:Von daher sind Werkzeuge zur Abstraktion hier eigentlich interessant. Aber wenn ich da mit Objekten und Methoden jongliere, dann geht mir die Performance dermaßen in die Knie, dass das Ganze nicht zu gebrauchen ist.
Was du natürlich weißt, ohne es je mit entsprechenden Patterns ausprobiert zu haben.
black_adept hat geschrieben:Mit dieser Aussage machst du dir weder Ralf noch D&P zum Freund.
Wir sind nicht hier, um Freunde zu finden. Wenn Enno recht hat, hat er recht.
black_adept hat geschrieben:Doch - die beiden haben große Ähnlichkeiten in der Verwendung.
Nein, wenn man über einfache statische Methoden hinausgeht. Ein Beispiel: Ich habe n Buttons, die durch Klassen repräsentiert werden, in denen festgelegt ist, welches Icon das hat, welchen Funktionscode, etc. Außerdem implementieren alle diese Klassen ein Interface, das die Methode RUN enthält, in der die eigentliche Funktion definiert ist. Für einen Button ist das eine Druckfunktion, für einen anderen eine Exportfunktion, ein dritter versendet vielleicht eine Mail. Wird ein Button gedrückt, übergibt der Dialog der Applikation einfach nur dieses Interface, die Applikation weiß, dass es Methode RUN ausführen soll.

Wie mache ich das bitte mit einer Funktionsgruppe?
black_adept hat geschrieben:
ralf.wenzel hat geschrieben: Ich kann (ohne Dirty Assign) nicht von außen auf Attribute einer Funktionsgruppe zugreifen
Wenn ich andere Posts von dir lese stellst du auch all deine Attribute auf privat und arbeitest mit Settern und Gettern, so dass das dann doch wieder ähnliches Verhalten ist
Es GIBT aber öffentliche Attribute und ich bin nicht der Nabel der Welt. Eine Funktionsgruppe hat niemals öffentliche Attribute.
black_adept hat geschrieben:
ralf.wenzel hat geschrieben:Ich kann eine Funktionsgruppe oder einen Funktionsbaustein überhaupt nicht an eine Prozedur übergeben.
Wenn du den Namen der FuGr oder des FuBa übergibst ist das völlig ausreichend um damit i.a. das abzubilden von dem ich glaube, dass du es meinst.
Und beim Übergeben des Namens des Funktionsbausteins wird der Zustand der Funktionsgruppe mit übergeben? Bei Klassen ist das so. Ich kann in einer Funktionsgruppe keinen Materialstamm speichern und eben diesen (mit der für ihn notwendigen Logik UND seinem Zustand, also seinen Attributen) an einen anderen Funktionsbaustein übergeben.


Ralf

Re: Gehaltsvorstellungen SAP ABAP-Entwickler

Beitrag von DeathAndPain (Top Expert / 1052 / 122 / 230 ) » 26. Sep 2018 17:10

black_adept hat geschrieben:
ewx hat geschrieben:Beim Aufruf eines Funktionsbausteins wird übrigens die gesamte Funktionsgruppe in den Speicher geladen, beim Aufruf einer Methode nur der Sourcecode dieser Methode...
Bitte nachreichen, wo diese Information offiziell dokumentiert ist ( falls es überhaupt stimmt, was ich ohne die nachzureichende Doku erst mal bezweifele ).
ewx hat recht. Ich weiß zwar auch nicht mehr genau, wo ich es gelesen habe (ist Jahre her), aber es stand in einer offiziellen SAP-Doku. Ich glaube, das war irgendein Hilfetext. Darin wurde betont, dass man sich gut überlegen solle, welche Funktionsbausteine man alles in eine Funktionsgruppe reinpackt, da beim Aufruf eines einzigen davon die ganze Funktionsgruppe in den Hauptspeicher geladen wird, weswegen man nur Funktionsbausteine, die auch tatsächlich zusammengehören, in dieselbe Gruppe packen soll.

Ist ja auch logisch, denn eine Funktionsgruppe ist ja nichts anderes als ein Rahmenprogramm mit einem Top-Include und dann noch je einem Include pro Funktionsbaustein (optional kann man noch weitere Includes hinzufügen). Technisch gesehen ist es also ein einziges großes Programm mit allen FB's drin, bei dem nur halt der Quelltext in Includes gegliedert ist.

Ich denke aber, dass das noch zu meinen 3.1i-Zeiten war, dass ich das gelesen habe (ist aus irgendeinem Grund in meinem Gedächtnis hängengeblieben). Ich gehe davon aus, dass es heute zwar immer noch so sein wird, heute aber keine Bedeutung mehr hat, da die Hauptspeicherausstattung moderner Maschinen deutlich über dem liegt, was Anfang des Jahrtausends üblich gewesen ist.
black_adept hat geschrieben:
ewx hat geschrieben:von einem SAP-Entwickler erwarte ich, dass er einen guten Kompromiss aus Wartbarkeit und Entwicklungszeit findet
Mit dieser Aussage machst du dir weder Ralf noch D&P zum Freund.
Ich würde die Aussage schon auch unterstützen. Nur muss man beachten, dass die Abstrahierung von OO sich erst ab einer gewissen Projektgröße rechnet. Bei kleineren Projekten ist ohne OO sowohl die Wartbarkeit besser (da man den Quellcode noch lesen, verstehen und debuggen kann) als auch die Entwicklungszeit kürzer (da man sich die vielen formalen Gebilde (z.B. getrennte Definition und Implementation von Unterroutinen) sparen kann und lesbarer Code auch mit weniger Kommentarzeilen auskommt (obwohl ich ein großer Fan umfassend kommentierten Codes bin)). Umgekehrt kommt bei sehr komplexen Projekten Ralf an und sagt zu recht, dass er viel Funktionaliät in hochabstrakten Klassen wiederverwenden kann und eine Menge automatisch läuft, ohne dass er dazu noch einen Programmierfinger krümmen müsste.

Häufig sind Wartbarkeit und Entwicklungszeit mit Blick auf die Frage OO oder nicht OO also keine konkurrierenden, sondern vielmehr komplementäre Ziele. (Hinsichtlich der Laufzeit sieht das schon anders aus *SCNR* )
black_adept hat geschrieben:Vielleicht liegt hier ja insgesamt ein Sprachproblem vor. Nenne doch mal eine (von mir aus auch sehr kurze) Liste aus ein paar Befehlen, die durch OO langsamer werden. ( Und dazu zählt nicht der TRY-CATCH-Block, weil dies ein OO-Konstrukt ist welches natürlich nicht langsamer werden kann [ langsamer als was? ]. Meinst du vielleicht, dass eine Folge von Befehlen aus dem OO-Kontext langsamer ist als eine klassische Befehlsfolge mit anderen Befehlen? )
Ich habe mir bislang nicht die Mühe gemacht, ganze Listen von Befehlen gegen ihre OO-Gegenstücke zu testen. Zum Teil berufe ich mich auf gesunden Menschenverstand und behaupte, dass es schneller geht, einem Feld per Gleichheitszeichen einen Wert zuzuweisen, anstatt eine Getter-Methode aufzurufen, die ihrem Rückgabeparameter dann ein privates Objektattribut zuweist und das ganze dann zurückliefert.

Aber um bei dem Beispiel des TRY-CATCH-Blocks zu bleiben, dem ich gemessen habe und bei dem Dir das Vergleichskonstrukt fehlt: Da habe ich das Lesen eines Wertes aus einer internen Tabelle gemessen (und bin auch relativ sicher, das in einem anderen Thread genau beschrieben zu haben, mit Quelltext und Messwerten, auch wenn ich jetzt zu faul bin, das Forum nach jenem Thread zu durchwühlen). Im Prinzip habe ich gegenübergestellt:

o 7.40-Code mit OO-Komponente in Form einer Ausnahmenklasse:
try.
wert = tabelle[ spalte1 = 4 ]-spalte2. " wert enthält gesuchtes Ergebnis
catch cx_sy_itab_line_not_found.
ergebnis = 'Mist'.
endtry.

o 7.40-Code ohne OO-Komponente:
assign tabelle[ spalte1 = 4 ]-spalte2 to field-symbol(<wert>). " <wert> enthält gesuchtes Ergebnis
if sy-subrc <> 0.
ergebnis = 'Mist'.
endif.

o 7.00-Code
read table tabelle into wa_tabelle with key spalte1 = 4 transporting spalte2. " wa_tabelle-spalte2 enthält gesuchtes Ergebnis
if sy-subrc <> 0.
ergebnis = 'Mist'.
endif.

Der 7.00-Code war am schnellsten, die beiden 7.40-Codes waren aber nur so unwesentlich langsamer (aus der Erinnerung würde ich sagen 3%), dass es den besser lesbaren Code allemal wert war. Nur wenn die gesuchte Tabellenzeile nicht existiert hat - also genau dann, wenn die Ausnahmeklasse gerufen wurde und damit ein OO-Element aktiv wurde - kam ich in der ersten Version reproduzierbar auf in etwa die siebenfache Laufzeit (also +600%). Das dabei erforderliche Auswerten des SY-SUBRC war in der Messung mit drin!
Ralf hat geschrieben:Jedes Rahmenprogramm kann Teilprogramme beinhalten, die man von außen aufrufen kann (das geht sogar bei FORM-Routinen).
Leider (bei Formroutinen). Aber nicht bei jedem Rahmenprogramm ist es der wesentliche Zweck, nichts anderes zu machen, als solche Unterroutinen nach außen anzubieten. Das ist nur bei Klassen, Funktionsgruppen und Subroutinenpools so, wobei ich davon ausgehe, dass unsere Meinung über Subroutinenpools sich nicht wesentlich unterscheidet.
Ralf hat geschrieben:Und nein, du kannst keine *Zustände* definieren, sondern *einen Zustand*.
Ich hätte sagen sollen, "statische Klassen". Verzeih mir diese Ungenauigkeit.

Re: Gehaltsvorstellungen SAP ABAP-Entwickler

Beitrag von ralf.wenzel (Top Expert / 3416 / 149 / 220 ) » 26. Sep 2018 17:29

DeathAndPain hat geschrieben:Häufig sind Wartbarkeit und Entwicklungszeit mit Blick auf die Frage OO oder nicht OO also keine konkurrierenden, sondern vielmehr komplementäre Ziele.


Natürlich ist das so. Wenn ich einen Aufsatz einfach sequentiell runterschreibe, dann geht das schneller als wenn ich mit vorher eine Gliederung mache mit Stichpunkten, etc. mache. Das Ergebnis des zweiten Aufsatzes wird besser sein, schon deshalb, weil die Struktur besser ist. Nun kann ich sagen "dieser Aufsatz ist jetzt nicht so wichtig", aber ich habe schon viele kleine Progrämmchen gesehen, die über die Jahre zu mächtigen Applikationen wachsen und irgendwann ist die Wartbarkeit im Eimer.

DeathAndPain hat geschrieben:Der 7.00-Code war am schnellsten, die beiden 7.40-Codes waren aber nur so unwesentlich langsamer (aus der Erinnerung würde ich sagen 3%), dass es den besser lesbaren Code allemal wert war. Nur wenn die gesuchte Tabellenzeile nicht existiert hat - also genau dann, wenn die Ausnahmeklasse gerufen wurde und damit ein OO-Element aktiv wurde - kam ich in der ersten Version reproduzierbar auf in etwa die siebenfache Laufzeit (also +600%). Das dabei erforderliche Auswerten des SY-SUBRC war in der Messung mit drin!


Natürlich ist das so, und zwar aus dem genau von mir genannten Grund: Weil du keine Funktionalität nutzt. Du machst mit dem sy-subrc ja nichts, du schreibst keinen Protokolleintrag, du machst keine Alternativlogik, nichts. In einem produktiven Coding wirst du ja auf den Fehler irgendwie reagieren MÜSSEN, und diese Logik existiert in deiner Messung nicht. Darum ist deine Messung ziemlich unfair.

Andersrum ist mir nicht bekannt, dass die SAP besonders laufzeitkritische Anwendungen extra prozedural programmiert, weil sie in OO zuviel Zeit fressen. DAS wäre ja die schlüssige Reaktion auf deine Behauptung, würde sie stimmen.

DeathAndPain hat geschrieben:
Ralf hat geschrieben:Und nein, du kannst keine *Zustände* definieren, sondern *einen Zustand*.

Ich hätte sagen sollen, "statische Klassen". Verzeih mir diese Ungenauigkeit.


OK, dann hast das aber mit OO nichts zu tun. Es gibt einen kleinen Sonderfall von Klassen, der ein bisschen Ähnlichkeit mit Funktionsgruppen hat. Eine Funktionsgruppe als evolutionären Vorläufer einer Klasse hinzustellen, halte ich jedoch für gewagt. Eine Klasse ist nämlich schon konzeptionell etwas ganz anderes als eine Funktionsgruppe.


Ralf

Re: Gehaltsvorstellungen SAP ABAP-Entwickler

Beitrag von black_adept (Top Expert / 3243 / 54 / 568 ) » 26. Sep 2018 19:22

DeathAndPain hat geschrieben:
black_adept hat geschrieben:
ewx hat geschrieben:Beim Aufruf eines Funktionsbausteins wird übrigens die gesamte Funktionsgruppe in den Speicher geladen, beim Aufruf einer Methode nur der Sourcecode dieser Methode...
Bitte nachreichen, wo diese Information offiziell dokumentiert ist ( falls es überhaupt stimmt, was ich ohne die nachzureichende Doku erst mal bezweifele ).
ewx hat recht. Ich weiß zwar auch nicht mehr genau, wo ich es gelesen habe (ist Jahre her), aber es stand in einer offiziellen SAP-Doku. Ich glaube, das war irgendein Hilfetext. Darin wurde betont, dass man sich gut überlegen solle, welche Funktionsbausteine man alles in eine Funktionsgruppe reinpackt, da beim Aufruf eines einzigen davon die ganze Funktionsgruppe in den Hauptspeicher geladen wird, weswegen man nur Funktionsbausteine, die auch tatsächlich zusammengehören, in dieselbe Gruppe packen soll.
Der Teil mit dem Laden der vollständigen Funktionsgruppe wird nicht angezweifelt - aber der Teil, dass nur der Sourcecode einer einzigen Methode statt dem Code der gesamten Klasse geladen wird scheint mir doch sehr fragwürdig.
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Gehaltsvorstellungen SAP ABAP-Entwickler

Beitrag von black_adept (Top Expert / 3243 / 54 / 568 ) » 26. Sep 2018 20:23

Wenn ich mir die Argumente von Ralf und D&P über die Vor- und Nachteile bei der Verwendung bzw. Nichtverwendung von OO-Artefakten so durch den Kopf gehen lasse muss ich an das "Blub Paradox" denken und schmunzeln.

Und für Ralf - auch wenn er das bestimmt nur in Maßen lustig findet - ein weiteres Zitat von Paul Graham:
Paul Graham in diesem recht [url=http://www.paulgraham.com/icad.html]lesenswerten Artikel recht weit unten[/url] hat geschrieben:This practice is not only common, but institutionalized. For example, in the OO world you hear a good deal about "patterns". I wonder if these patterns are not sometimes evidence of case (c), the human compiler, at work. When I see patterns in my programs, I consider it a sign of trouble. The shape of a program should reflect only the problem it needs to solve. Any other regularity in the code is a sign, to me at least, that I'm using abstractions that aren't powerful enough-- often that I'm generating by hand the expansions of some macro that I need to write.
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Gehaltsvorstellungen SAP ABAP-Entwickler

Beitrag von ralf.wenzel (Top Expert / 3416 / 149 / 220 ) » 26. Sep 2018 20:50

Die Aussage ist natürlich Quatsch. Patterns sind wiederkehrende Muster für sich wiederholende Probleme. Ich habe vor einer Weile mal mit einem telefoniert, der hat SEHR umständlich das Problem gelöst, dass er nur eine Instanz einer Klasse haben darf. Das hat er mir ganz stolz erklärt, dass er was " erfunden" hat und ich habe mit dem lapidaren Satz geantwortet: Super, du hast das Singleton in kompliziert erfunden".

Ich finde es sehr praktisch, wenn ich einen Lösungsansatz in Form eines Patterns sehe (z. B. einen Iterator), weil ich mir den dann gar nicht mehr genau ansehen muss -- ich weiß ja, wie man das Pattern umsetzt und gehe erstmal davon aus, dass diese Implementierung korrekt ist (weil es eben 08/15 ist).

Das ist wie Standardsoftware: Sie löst Probleme, die man ohne sie gar nicht hätte. Aber es ist eben Standard, was Vorteile mit sich bringt (z. B. bei der Mitarbeiterfindung). Klar kann man sagen "individuelle Lösungen sind besser, weil sie keinen Ballast mit sich herumführen", aber das erkauft man sich mit anderen Nachteilen.


Ralf

Re: Gehaltsvorstellungen SAP ABAP-Entwickler

Beitrag von black_adept (Top Expert / 3243 / 54 / 568 ) » 26. Sep 2018 21:39

ralf.wenzel hat geschrieben:Die Aussage ist natürlich Quatsch
Überlege was du sagst. Der Mann, der das geschrieben hat ist kein Idiot und da er das so geschrieben hat, hat er auch einen Grund dafür. Mag sein, dass du mit ihm nicht übereinstimmst [ wenn du dem Link gefolgt bist und mal seinen nicht ganz kurzen Artikel zur Gänze gelesen hast ]- aber eine andere Aussage grundsätzlich als "Quatsch" abzutun setzt denjenigen, der den "Quatsch" gesagt hat in ein denkbar schlechtes Licht. Das ist sehr schlechter Diskussionsstil.

Folgende Benutzer bedankten sich beim Autor black_adept für den Beitrag (Insgesamt 2):
DanielDeathAndPain

live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Gehaltsvorstellungen SAP ABAP-Entwickler

Beitrag von ralf.wenzel (Top Expert / 3416 / 149 / 220 ) » 26. Sep 2018 21:56

Ich schreibe hier meine Meinung. Und wenn ich etwas für Quatsch halte, sage und begründe ich das. Das ist nicht abwertend gemeint. Aber ich werde jetzt nicht vor jeden Satz schreiben, dass er meine subjektive Meinung enthält.


Ralf



Re: Gehaltsvorstellungen SAP ABAP-Entwickler

Beitrag von ralf.wenzel (Top Expert / 3416 / 149 / 220 ) » 1. Okt 2018 18:51

Eine sehr interessante Meinung. Es gibt aber einen Unterschied, ob ich individuelle Software schreibe oder ein Produkt für noch unbekannte Kunden.

Um ein Beispiel aus dem aktuellen Projekt zu bringen: Wir sind ein halbes Dutzend Entwickler, was auch gut ist, weil mehr für die spätere Wartung auf Kundenseite nicht zur Verfügung ständen. Darum ist es besonders wichtig, eine einfache Wartbarkeit zu erreichen. Man braucht also zwingend in sich streng gekapselte Module, die für sich autonom agieren können und über sauber definierte Schnittstellen miteinander kommunizieren.

Schon bei der Kapselung sind Funktionsgruppen damit „raus“, weil es keine geschützten Funktionsbausteine gibt. Jeder Funktionsbaustein ist von außen aufrufbar, somit muss der Aufrufer wissen, was er aufrufen darf und was nicht (das ist das Gegenteil von „autonom agieren“). Hinzu kommt, dass wir unterschiedliche Arten ähnlicher Objekte haben, deren Varianten wir über Subklassen einer Oberklasse realisieren, so dass wir Gemeinsamkeiten in der Oberklasse gesammelt haben. Wie das mit Funktionsgruppen gehen soll, konnte mir noch niemand erklären.

Zudem entwickeln wir agil. Das bedeutet: Wie das fertige Haus aussehen soll, weiß man erst, wenn tapeziert ist, weil der Kunde ständig neue und geänderte Anforderungen an uns heranträgt, da er erst lernt, welche Möglichkeiten sich ihm bieten. Das ist völlig normal und in diesem Falle der beste Weg. Es gab schon einige Fälle im Projekt, wo wir generischer waren als notwendig, was aber Änderungen am geplanten Anwendungsverhalten deutlich vereinfachte.

Was wir dabei nie vergessen dürfen: Wir entwickeln ein AddOn, das später als Produkt verkauft werden soll. Wir wissen also gar nicht, inwieweit die Prozesse anderer Kunden abweichen. Was wir sicher wissen, ist: Sie werden. Wir müssen also eine ähnliche Einstellbarkeit und Erweiterungsfähigkeit bieten wie die SAP. Das ist etwas vollkommen anderes, als für einen bekannten Kunden etwas zu entwickeln.

Sowas gab es auch bei früheren Kunden, eine Auftragsschnittstelle (prozedural entwickelt) sollte Varianten erhalten. Mein erster Schritt war, die nicht durch IF/THEN/ELSE zu realisieren, sondern durch Subklassen, was dazu führte, dass ich gemeinsames Coding in der Hauptklasse hatte und Individuelles in den Subklassen. Insbesondere bräuchte ich bei keiner der Varianten die schon bestehenden neu zu testen, weil ich die ja gar nicht verändert habe. Das hat einen immensen Testaufwand erspart, denn einen prozeduralen Report hätte man jedesmal komplett neu testen müssen.

Man sieht: Modularisierung dient der Vereinfachung, der Verringerung von Komplexität. Und in meinen Augen gilt das auch für OO, denn: Welche Alternativen habe ich denn? Prozedural wäre unser AddOn nicht weniger, sondern nur anders komplex. Weil die Aufgabe an sich sehr komplex ist, kann die Lösung nicht trivial sein. Wir haben uns dafür entschieden, den höheren Abstraktionsgrad zu wählen, um das Verhalten in Schichten steigender Verallgemeinerung anpassen zu können und dagegen, identisches Coding an X Stellen zu haben (um dann bei einer Verhaltensänderung eine zu vergessen).

Natürlich ist es einfacher und schneller, eine DB-Tabelle aus Feldern zu definieren. Trotzdem definieren wie sie immer aus Strukturen, die einen Gruppennamen erhalten und die Erfahrung zeigt, dass das viele Vorteile bietet. Nicht bei jeder Tabelle, manche ändern sich einfach nicht, aber der Umbauaufwände für die, die geändert werden müssen, rechtfertigen die paar Minuten Mehraufwand. Zumal es auch aus Sicht der Konsistenz nicht vermittelbar wäre, es mal so und mal anders zu machen.

Und noch eines, was im Artikel falsch ist: Design Patterns dienen NICHT der Verringerung von Komplexität! Sie bieten einheitliche Lösungswege für gleiche oder ähnliche Probleme. Das ist etwas ganz anderes.


Ralf

Re: Gehaltsvorstellungen SAP ABAP-Entwickler

Beitrag von deejey (Specialist / 199 / 48 / 16 ) » 2. Okt 2018 02:26

Der Artikel enthält auch einigen Quatsch bzw. kommt mir unausgegoren vor, z.B. erwägt der Heini nicht mal, dass Komplexität vlt. ja auch durch fachliche Anforderungen entstehen könnte :D

Re: Gehaltsvorstellungen SAP ABAP-Entwickler

Beitrag von DeathAndPain (Top Expert / 1052 / 122 / 230 ) » 2. Okt 2018 12:05

@Ralf: Ich finde Deine Stellungnahme zu dem Artikel höchst interessant und bin in weiten Teilen bereit, mich Deiner Meinung anzuschließen.
Schon bei der Kapselung sind Funktionsgruppen damit „raus“, weil es keine geschützten Funktionsbausteine gibt. Jeder Funktionsbaustein ist von außen aufrufbar, somit muss der Aufrufer wissen, was er aufrufen darf und was nicht (das ist das Gegenteil von „autonom agieren“).
Das ist eine Frage der Umsetzung und des guten Willens. Wenn ich das mit Funktionsgruppen machen würde, dann würde ich die "privaten Methoden" als Formroutinen realisieren. Natürlich wäre es technisch möglich, die von extern aufzurufen, aber ich denke, dass jeder, der so etwas täte, wüsste, dass er einen Fehler macht. Sowas macht auch in der Praxis keiner. Ich habe jedenfalls noch nie gesehen, dass jemand quer Formroutinen fremder Modulpools oder gar Reports aufgerufen hätte, ausgenommen solcher, die genau dafür vorgesehen waren (z.B. als Include, das nur Formroutinen enthält wie MPPERS00 oder als dezidierter "Subroutinenpool"). Auch letzteres finde ich furchtbar und bin mir sicher, dabei mit Dir auf einer Linie zu liegen, aber obwohl ich schon so einige Programmierchaoten in meiner Laufbahn getroffen habe, habe ich das noch nie gesehen, dass jemand quer in Formroutinen fremder Programme einspringt, die dafür gar nicht vorgesehen sind. Und nochmal: Du kannst einen Programmierer nicht mit formalen Mitteln dazu zwingen, sauber zu arbeiten, egal wieviel programmtechnische Bürokratie, bis hin zu Wasserköpfen wie der Trennung von Definition und Implementation, die die Lesbarkeit des Programms in den Abgrund reißt, Du einführst. An anderer Stelle hast Du selbst gesagt, dass man kaum eine Chance hat, Klassen zu verstehen oder zu nutzen, wenn sie nicht dokumentiert sind. Ein Programmierer, der so schlampert arbeitet, dass er aus Faulheit quer in die Formroutine eines anderen Reports einspringt, würde niemals ordentlich strukturierte und dokumentierte Klassen und Methoden erstellen. Da hätteste dann eher sowas wie eine instanziierte Klasse, bei der genau ein Objekt erzeugt wird und der gesamte Nutzcode im Constructor steht. Dann endet das Programm, und das ist dann sein OO.

Von daher kann man sagen, ja, technisch wäre es möglich, Formroutinen aus dem Inneren der Funktionsgruppe von außen zu rufen, aber es zu machen wäre ohne Übertreibung böswilliger Mutwillen, und wer den hat und im System entwickeln darf, der wird immer Wege finden, Schaden anzurichten. In der Praxis behaupte ich, wenn Du eine Funktionsgruppe mit einem Satz Funktionsbausteinen auf die Beine stellst, die von außen genutzt werden sollen, und die interne Modularisierung mit Hilfe von Formroutinen abwickelst, die innerhalb der Funktionsgruppe angesiedelt sind (also eben nicht als externer Subroutinenpool, der zur Nutzung einlädt), dann ist das in der Praxis (!) eine saubere Kapselung. Von daher bin ich der Meinung, dass der Standpunkt, Funktionsgruppen wären aufgrund mangelnder Kapselung abzulehnen, einer rein bürokratischen Geisteshaltung entspricht.

Dass Du mit Klassen über Instanziierung und Vererbung mehr Möglichkeiten hast, ist unbestritten. Ich habe nie gesagt, dass Funktionsgruppen und Klassen dasselbe sind.
Zudem entwickeln wir agil. Das bedeutet: Wie das fertige Haus aussehen soll, weiß man erst, wenn tapeziert ist, weil der Kunde ständig neue und geänderte Anforderungen an uns heranträgt, da er erst lernt, welche Möglichkeiten sich ihm bieten. Das ist völlig normal und in diesem Falle der beste Weg.
Normal ja, bester Weg nein. Ich bin weit davon entfernt, Dir an der Stelle einen Vorwurf zu machen, weil ich das kenne und genau weiß, dass die (in meinem Fall innerbetrieblichen) Kunden nicht wissen, was sie wollen. Dennoch muss natürlich das Bestreben sein, das Projekt so genau wie möglich im Vorfeld abzustecken und zu definieren, eben damit sich solche nachträglichen Anpassungen im Rahmen halten. Sonst bist Du ganz schnell bei 250% Deines geplanten Aufwandes oder baust gar einen Großflughafen.
Was wir dabei nie vergessen dürfen: Wir entwickeln ein AddOn, das später als Produkt verkauft werden soll. Wir wissen also gar nicht, inwieweit die Prozesse anderer Kunden abweichen. Was wir sicher wissen, ist: Sie werden. Wir müssen also eine ähnliche Einstellbarkeit und Erweiterungsfähigkeit bieten wie die SAP. Das ist etwas vollkommen anderes, als für einen bekannten Kunden etwas zu entwickeln.
Da hast Du recht. Wenn ein eigenständiges, verkäufliches Produkt entstehen soll, dann braucht man ohne Ende Customizingmöglichkeiten. Das halte ich auch für ein Paradebeispiel einer Situation, in der OO mit seinen ganzen Abstrahierungsmöglichkeiten vollkommen Sinn macht.
Sowas gab es auch bei früheren Kunden, eine Auftragsschnittstelle (prozedural entwickelt) sollte Varianten erhalten. Mein erster Schritt war, die nicht durch IF/THEN/ELSE zu realisieren, sondern durch Subklassen, was dazu führte, dass ich gemeinsames Coding in der Hauptklasse hatte und Individuelles in den Subklassen. Insbesondere bräuchte ich bei keiner der Varianten die schon bestehenden neu zu testen, weil ich die ja gar nicht verändert habe. Das hat einen immensen Testaufwand erspart, denn einen prozeduralen Report hätte man jedesmal komplett neu testen müssen.
Bedingt. Ich bin auch kein Fan des IF-Befehls. Häufig braucht man ihn, aber wenn es eine Alternative gibt (sei es CASE, sei es 7.40-Syntax, sei es CHECK :P), dann ist die in aller Regel besser. Man kann aber schon hingehen und z.B. alle Varianten, die Du mit einer Subklasse abbildest, als Fälle eines CASE aufführen, der meinetwegen pro WHEN einen PERFORM ausführt. Dann musst Du auch nicht alles neu testen, wenn Du eine der Formroutinen veränderst, denn die wird ja nur in dem speziellen Fall gerufen, in dem bei Dir Deine geänderte Subklasse gerufen werden würde. Der Nachteil wäre die geringere Abstraktion, der Vorteil aber einmal mehr die bessere Verständlichkeit, was da passiert, weil man im Code auf einen Blick alle Varianten sieht, die möglich sind und auch unter welchen Umständen sie jeweils gerufen werden. Für jemanden, der den Code nicht kennt, halte ich das für ein ganzes Stück besser nachvollziehbar.

Eine Alternative wäre, für die "Varianten" eine Customizingtabelle zu definieren, die die Namen von Funktionsbausteinen enthält, die Deinen Subklassen entsprechen, und darüber dann zu verzweigen. Letzteres macht natürlich nur dann Sinn, wenn diese nicht privat sein sollen. Sollen sie privat sein, wären Formroutinen aus den oben geschilderten Gründen besser, und dann kann man sich die Tabelle vermutlich sparen, weil man die dann sowieso statisch im lokalen Code implementiert und daher auch statisch im CASE auflisten kann.
Natürlich ist es einfacher und schneller, eine DB-Tabelle aus Feldern zu definieren. Trotzdem definieren wie sie immer aus Strukturen, die einen Gruppennamen erhalten
Da wäre ich Dir dankbar, wenn Du erläutern würdest, wie man sich das genau vorzustellen hat.

Re: Gehaltsvorstellungen SAP ABAP-Entwickler

Beitrag von ralf.wenzel (Top Expert / 3416 / 149 / 220 ) » 2. Okt 2018 13:18

Nur ganz kurz:

Dirty Assigns findest du ohne Ende im Coding der SAP. Hab ich mich gerade letzte Woche drüber geärgert, als ich nach Merkwürdigkeiten im BAL suchte.

Eine FORM-Routine ist etwas vollkommen anderes als ein Funktionsbaustein, weshalb ich die Verwendung als „privater Funktionsbaustein“ schon sehr weit hergeholt finde. Bei Methoden ist das anders: Eine Methode ist eine Methode und nur die Deklaration entscheidet über die Sichtbarkeit.

Funktionsbaustein im Customizing festlegen? Und damit keinerlei Verwendungsnschweise mehr haben? Da ist mir doch eine Factory lieber, in der wenigstens die Oberklasse steht. Ja, mit einem Case änderst du wahrscheinlich wenig, aber du änderst. In meinem Fall wird Altcoding GAR NICHT geändert.

Zu den Tabellen:

Bei mir besteht eine Tabelle zum Beispiel aus dem einzigen Einzelfeld MANDT, einem Include für alle Keyfelder (Gruppenname KEY), einem weiteren DATA für die weiteren Felder, einem weiteren CREATE mit Erstellerfeldern (Name, Datum, Uhrzeit) und noch einem CHANGE (entsprechend) für die letzte Änderung.

In DATA kann man Felder zu weiteren Includes zusammenfassen, die nur/gern zusammen auftreten (Statusschema und Status).

So erhält man nicht einfach „lose“ Felder, sondern semantisch zusammenhängende Feldgruppen, die man wiederverwenden und gemeinsam ansprechen kann. Das hat mir auch bei Altkunden schon viel Arbeit erspart, wenn es etwas zu ändern gab.



Ralf


Ralf

Vorherige Seite 4 von 8 (current) Nächste

Aktuelle Forenbeiträge

Langtext zur Exception
vor 44 Minuten von a-dead-trousers 11 / 96
Adobe LiveCycle Designer - Ausblenden Text auf letzter Seite
vor 2 Stunden von a-dead-trousers 4 / 91
Welche Entwicklertools?
vor 17 Stunden von LostDarkness 2 / 922
Werksspezifische Konfiguration kopieren
vor 19 Stunden von eleve 2 / 48
Removal of left space - next to a docking container
vor 19 Stunden von Haemma83 16 / 114

Unbeantwortete Forenbeiträge

BAPI_PO_CREATE1 und Einkaufsinfosatz
vor 3 Tagen von SweetRuedi 1 / 81
WCOCO: Gruppe für Betragsfelder 0S01
vor 5 Tagen von SAP_ENTWICKLER 1 / 52
CAS-Nr.: Chemical Abstracs Service
vor einer Woche von SAP_ENTWICKLER 1 / 92
Interaktives Skript, Rolle IC-Manager
vor 3 Wochen von erubadhron86 1 / 129