Method für die Durchschnittsberechnung Thema ist als GELÖST markiert

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

Re: Method für die Durchschnittsberechnung

Beitrag von ewx (Top Expert / 4124 / 183 / 417 ) » 17.01.2020 09:55

DeathAndPain hat geschrieben:
16.01.2020 15:49
Ich habe schon eine Menge Inline-Deklarationen gesehen, die die Verständlichkeit des Codes deutlich erschwert haben, weil man erst mal ins Grübeln gekommen ist, welcher Datentyp da jetzt eigentlich bei rauskommt.
Das ist doch eigentlich nicht schwer...
Die Inline-Deklaration ohne genaue Typ-Definition ist sehr eingeschränkt:
- Integer (Zahl)
- String (Literal in Backticks `)
- Character (Literal in Hochkomma ' )
Ich finde das sehr übersichtlich und intuitiv.

Wenn die Deklaration mit einem strukturierten Typen gemacht wird, ist das ebenfalls gut zu erkennen und auch nichts anderes als eine flexible Version von "DATA x TYPE y VALUE z".

Code: Alles auswählen.

DATA(excluded_functions) = VALUE ui_functions(
  ( 'CHANGE' )
  ( 'SAVE' )
  ( 'SOMETHING' ) ).
Zuletzt geändert von ewx am 17.01.2020 10:29, insgesamt 1-mal geändert.

Folgende Benutzer bedankten sich beim Autor ewx für den Beitrag:
gtoXX (17.01.2020 10:14)



Re: Method für die Durchschnittsberechnung

Beitrag von gtoXX (Specialist / 124 / 26 / 18 ) » 17.01.2020 10:03

DeathAndPain hat geschrieben:
16.01.2020 10:17


Und bitte jetzt nicht das Argument, dass alle Methoden nur 10 Zeilen lang sein sollten, so dass alles als lokal einzustufen ist. Dieses Paradigma halte ich für ebenso gutaussehend wie praxisuntauglich, denn es führt dazu, dass Fremdcode kaum mehr nachvollziehbar ist - obwohl es paradoxerweise genau das Gegenteil erreichen soll! Hintergrund ist, dass eine Unterroutine eine ähnliche Bedeutung hat wie ein selbst definierter Befehl.

Aber normale Felddeklarationen am Anfang der Routine durch Inlines ersetzen? Ne.
Dem muss ich mal widersprechen. Wenn man OO einsetzt, wie es wirklich mal gedacht war von Kay, delegiert man nur Messages. Ein Aufrufer bearbeitet selbst nichts. Das führt automatisch zu kürzeren und atomisierten Einheiten.

Die Methoden können sinnvolle Namen bekommen, was wiederum die Lesbarkeit von Fremdcode deutlich erhöht, statt durch 100 Zeilen code zu gehen und jede kleine Annweisung im Detail zu lesen, interpretieren und gedanklich abhaken, was man bewußt oder unbewusst macht.

https://leanpub.com/messaging_as_a_programming_model

Eine Unterroutine macht mehr als ein Befehl. Entweder stellt sie Businesslogik dar, was ein Befehl niemals tut, oder sie stellt eine gewisse Funktion dar, in dem Moment erst, ist sie mit einem Befehl vergleichbar.

Im Fall der Inline-Deklaration stimme ich Dir zu. Die Deklaration sollte, auch wenn es gewöhnungsbedürftig ist, wenn man aus der "alten" Welt kommt, genau bei ihrer ersten Verwendung erfolgen.

Das hat einen entscheidenden Vorteil : Wenn ich mir die Verwendung anschaue, sehe ich sofort, in welchem Kontext die Variable gedacht war. Bei einem Data-Block sehe ich das nicht.

Eine Ausnahme stellen Variablen dar, die bewußt den Initialwert darstellen. Diese können durchaus am Anfang stehen.

Beispiel :

is_initial_wert_b = Value typ_wert( ).

Perform routine_a USING parameter_a = 2
parameter b = is_initial_wert
.

Selbst wenn ich jetzt die Domäne von "typ_wert" ändere, ist sichergestellt das immer der passende Initialwert übergeben wird. Mal als extrem : Der Ursprungstyp war i und ich stelle um auf NUMC.
"Code lügt nicht ^^"

Re: Method für die Durchschnittsberechnung

Beitrag von gtoXX (Specialist / 124 / 26 / 18 ) » 17.01.2020 10:23

DeathAndPain hat geschrieben:
16.01.2020 10:17

Deswegen bin ich der Meinung, dass es sinnvoll ist, seinen Code in sinnvolle Verarbeitungsblöcke zu gliedern, diese als Unterroutinen auszuführen - und jede einzelne davon mit einem ausführlichen Textkommentar am Kopf der Routine zu versehen, der erläutert, was diese Routine genau macht und was rein- und rausgeht.

Wenn man aber jeden kleinen 5-Zeiler dieserart kapselt, ist das nicht mehr praktikabel, und man erreicht das Gegenteil von dem, was man erreichen möchte. Davon abgesehen hat Otto Normalprogrammierer ja noch nicht einmal die Disziplin, seine normalen Routinen mit einem anständigen Kopfkommentar zu versehen (selbst Klassen, öffentlichen Methoden und Funktionsbausteine sind ja erschreckend oft ohne jede Online-Doku). Da ist es realitätsfernes Wunschdenken anzunehmen, dass die Leute jedem mutwillig untergekapselten Fünfzeiler eine eigene Doku zukommen lassen, damit man beim Sichten der Aufrufstelle versteht, was dieser Aufruf genau tut. Aber selbst, wenn sie es täten, ist bei einer derart feinen Granulierung das Programm unübersichtlich, wenn man nur Aufrufstellen und zugehörigen Kommentartext (der hoffentlich stimmt und ausführlich genug ist) liest anstelle von echtem Code, bei dem man "sieht", was er macht.
Auch hier ein Veto noch :

Ausführliche Textkommentare bedeuten schlechten Code um es mal provokant zu sagen. Wenn ich Parameter beschreiben muss verschwende ich Zeit und Geld.

Wenn eine Routine sinnvoll benannt ist, benötige ich keinerlei Kommentare.

Wenn es ein 5 Zeiler ist und genau das ist der Grund, Code nicht länger zu machen, erfasse ich mit einem Blick, was er tut.

Nicht umsonst ist eine der Standard-ATC Prüfung das Verhältnis Kommentar zu Codezeilen. D.h. in einigen Projekten würden dir die literarischen Ausschweifungen deutlich um die Ohren gehauen :-).
Zuletzt geändert von gtoXX am 17.01.2020 11:08, insgesamt 1-mal geändert.
"Code lügt nicht ^^"

Re: Method für die Durchschnittsberechnung

Beitrag von gtoXX (Specialist / 124 / 26 / 18 ) » 17.01.2020 10:31

DeathAndPain hat geschrieben:
16.01.2020 12:09

Wenn eine Prozedur aus mehreren, linear aufeinanderfolgenden und absehbar nirgendwo anders benötigten Schritten besteht, dann entschließe ich mich auch gerne mal dazu, diese Schritte nicht zu kapseln, sondern mit deutlich sichtbaren Kommentartrennlinien voneinander zu trennen. Dann sieht man als Leser, wie ein Schritt auf den anderen folgt und das Ganze dennoch eine Einheit bildet. Natürlich darf die Gesamtlänge dabei nicht völlig aus dem Ruder laufen.

Code: Alles auswählen.

FORM WRITE_DATA.

  PERFORM PASS1.
  PERFORM PASS2.

ENDFORM.
Und danach dann die Implementierungen von PASS1 und PASS2. Das finde ich aber affig; mit dieser Kapselung gewinnt man nicht wirklich viel. Da mache ich lieber:

Code: Alles auswählen.

FORM WRITE_DATA.

********** PASS 1 **********
"  Actual code of pass 1

********** PASS 2 **********
"  Actual code of pass 2

ENDFORM.
Auch wenn jeder der beiden Pässe 50 Zeilen Code lang ist.
Dein Gedanke ist grundsätzlich erstmal nachvollziehbar. Leider ist es trotzdem der falsche Ansatz nach meiner Meinung. Erweiterbarkeit, Wiederverwendung und Austauschbarkeit sind hier nicht gewährleistet. Geschweige denn, das Unit-Tests möglich sind.

Denn bei einer Änderung an der Form WRITE_DATA sollten Pass1 und Pass2 noch immer das Gleiche tun wie vorher. Da es aber integrierter Code ist, kannst du das statt durch einen automatisierten Unit_test nur durch zusätzlichen manuellen Testaufwand ( bei dem immer wieder ein Szenario vergessen werden kann ) sicherstellen.

Langfristig gesehen ist es ineffizient.

Folgende Benutzer bedankten sich beim Autor gtoXX für den Beitrag (Insgesamt 2):
ewx (17.01.2020 10:39) • ST22 (17.01.2020 11:05)

"Code lügt nicht ^^"

Re: Method für die Durchschnittsberechnung

Beitrag von black_adept (Top Expert / 3341 / 60 / 623 ) » 17.01.2020 10:47

DeathAndPain hat geschrieben:
16.01.2020 10:17
[...]Und bitte jetzt nicht das Argument, dass alle Methoden nur 10 Zeilen lang sein sollten, so dass alles als lokal einzustufen ist. Dieses Paradigma halte ich für ebenso gutaussehend wie praxisuntauglich, denn es führt dazu, dass Fremdcode kaum mehr nachvollziehbar ist - obwohl es paradoxerweise genau das Gegenteil erreichen soll! Hintergrund ist, dass eine Unterroutine eine ähnliche Bedeutung hat wie ein selbst definierter Befehl. Die normalen ABAP-Befehle kennt jeder. Wenn da also 10 Zeilen normalen Codes stehen, kannst Du den normalerweise lesen und interpretieren. Wenn der Code aber nur aus Aufrufen irgendwelcher Unterroutinen besteht, die selber wieder aus Aufrufen bestehen, und das Ganze so weit runter, bis Du auf der Ebene, wo echter Code steht, keinen Kontext mehr siehst, dann ist das im Prinzip, also würdest Du eine Programmiersprache lesen, die Du nicht kennst (und die möglicherweise sogar Bugs enthält (jenseits von dem, was produktiv genutzte Programmiersprachen an Rest-Bugs zu haben pflegen)). [...]
😇 Für deine Ausführungen gibt es eine schöne Beschreibung in einem recht sehenswerten englischen Youtube Video über Anti-Patterns ( Anti-Entwurfsmuster ).
Wer direkt einsteigen will: Bei Minute 1:57 ( direkt nach den Vorbemerkungen zu Anti-Patterns ) wird mit dem Antipattern 1 genau das beschrieben inklusive der Konsequenzen.

Folgende Benutzer bedankten sich beim Autor black_adept für den Beitrag (Insgesamt 3):
gtoXX (17.01.2020 11:41) • DeathAndPain (17.01.2020 13:25) • Legxis (20.01.2020 12:11)

live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Method für die Durchschnittsberechnung

Beitrag von gtoXX (Specialist / 124 / 26 / 18 ) » 17.01.2020 12:21

Und einfach weil es so schön Lesenswert ist :

https://de.wikipedia.org/wiki/Anti-Pattern
"Code lügt nicht ^^"

Re: Method für die Durchschnittsberechnung

Beitrag von DeathAndPain (Top Expert / 1267 / 138 / 291 ) » 17.01.2020 13:38

ewx hat geschrieben:Du verwendest aber evtl. gleiche Variablen in Block A und B. Du kannst also mit einer Änderung in Block A das Verhalten von Block B verändern, ohne dass es dir bewusst ist!
Das meinte ich, als ich sagte: "Die einzige theoretisch mögliche Wechselwirkung wäre ein vergessener CLEAR zwischen den Pässen. Aber der ist für mich kein ausreichendes Entscheidungskriterium."

Natürlich sollte Block B nicht mit den Werten aus Block A weiterarbeiten, sondern eigenständig sein.
ewx hat geschrieben:Ein weiterer wichtiger Punkt, den ich bei kleinen Einheiten zu schätzen gelernt habe: Wenn du debuggen musst, dann musst du bei großen Code-Blöcken durch die meisten Anweisungen im Einzelschritt durch. Selbst wenn es nur drei Mal "F5" für drei Anweisungen ist anstatt ein Mal "F6" für die Funktion, die das gleiche tut, ist das im Stress und unter Zeitdruck eine enorme Hilfe. Ich finde es sehr hilfreich, wenn ich schnell über eine Funktion "hinweg-debuggen" kann, weil ich weiß, dass hier nichts Fehlerrelevantes passiert.
Das ist ein Problem, das bei mir gleichfalls nicht auftritt. Wenn ich in Block 2 etwas debuggen will, dann setze ich den Breakpoint dort. Block 1 mag davor stehen, aber da kein Breakpoint drin ist, läuft das System da einfach durch und bleibt trotzdem nur in Block 2 stehen. Das Systemverhalten ist also nicht anders, als wenn Block 1 vorher als getrennte Unterroutine abgehandelt werden würde.
ewx hat geschrieben:Die Inline-Deklaration ohne genaue Typ-Definition ist sehr eingeschränkt:
- Integer (Zahl)
- String (Literal in Backticks `)
- Character (Literal in Hochkomma ' )
Glaubst Du das? Es geht z.B. genauso die Zuweisung einer funktionalen Methode mit einem riesigen Rattenschwanz an Parametern. Dann musste erst mal schauen, wie die parametrisiert ist, bevor Du den Datentyp Deiner neuen Variable kennst. Zudem ist die "Zuweisungszeile" dann soundsoviel Bildschirmzeilen lang. Das ist um Größenordnungen unübersichtlicher als ein klares DATA xyz TYPE abc. Du bist gerade in einem völlig anderen Codeabschnitt und denkst über was völlig anderes nach, was mit dieser funktionalen Methode gar nichts zu tun hat, wirst aber aus diesen Gedankengängen herausgerissen, weil Du den Typ des Feldes klären möchtest.

Zugegeben, Eclipse unterstützt einen in solchen Fällen mit F2 sehr. Trotzdem finde ich das alles andere als übersichtlich.
ewx hat geschrieben:Dem muss ich mal widersprechen. Wenn man OO einsetzt, wie es wirklich mal gedacht war von Kay, delegiert man nur Messages. Ein Aufrufer bearbeitet selbst nichts. Das führt automatisch zu kürzeren und atomisierten Einheiten.

Die Methoden können sinnvolle Namen bekommen, was wiederum die Lesbarkeit von Fremdcode deutlich erhöht, statt durch 100 Zeilen code zu gehen und jede kleine Annweisung im Detail zu lesen, interpretieren und gedanklich abhaken, was man bewußt oder unbewusst macht.
Das ist Theorycrafting, wie auch Kay ein Akademiker war. In der Praxis hast Du zwar bedingt recht, aber Code, den man gelesen oder ausreichend überflogen hat, so dass einem weitestgehend klar ist, was da passiert, kann man gedanklich tatsächlich abhaken. Bei dem anderen stellt man sich immer wieder die Frage: "Habe ich jetzt richtig interpretiert, was SCHREIBE_MATERIALDATEN sicherlich machen wird? Oder muss ich da doch noch mal einsteigen und noch tiefer in die Verästelungen runter, um zu analysieren, was die Befehle, äh, Unterprogramme, die da definiert werden, eigentlich tun?"

Das ist die Realität, so wie ich sie erlebe. Die Tatsache, dass Routinennamen in ABAP auf gerade mal 30 Zeichen beschränkt sind, lässt die Annahme, man könne damit ausdrücken, was sie genau bewerkstelligen, als geradezu zynisch erscheinen. Aber selbst, wenn es 80 Zeichen wären, würde das nicht ausreichen, um demjenigen, der das Programm nicht kennt, ausreichend genau zu vermitteln, was die Routine tut und was die Bedeutung der Felder ist, die rein- und rausgehen. Den tatsächlichen Code zu begutachten mag aufwendig sein, aber wenn ich den untersucht habe, dann weiß ich, was da passiert.

Vor allem, weil man fremden Code meist dann begutachten muss, wenn er nicht das tut, was er soll, wenn also irgendwo ein Bug drin ist. Da ist es dann blöd, wenn ich mich auf mein Verständnis des Namens einer Unterroutine verlasse, damit sogar recht habe, aber diese aufgrund eines Bugs eben doch nicht genau das macht, was ich erwarte und ich rätselrate, ob das Programmverhalten an der Stelle, die ich gerade untersuche, falsch ist oder nur meine Einschätzung des Sollverhaltens der Routine nicht stimmt. Bei ABAP-Befehlen weiß ich genau, was sie tun, und Bugs auf dieser Ebene sind auch nahezu auszuschließen. Da steht man auf viel sichererem Boden.

Wohlgemerkt: ich rede keinem unmodularisierten Spaghetticode das Wort. Aber die Aufteilung in Unterprogramme sollte so gewählt sein, das jedes eine klar definierte Aufgabe umfasst, die dann auch sorgsam zu dokumentieren sich lohnt. Dann kann der Leser sich diese Doku (da können 3 Sätze reichen) durchlesen, hat eine Vorstellung davon, was diese Routine macht, weiß, dass diese Vorstellung richtig ist, da sie nicht nur auf seiner Interpretation von Prozedurnamen beruht, und kann abhängig von seiner Problemstellung beurteilen, ob er in diese Routine tiefer einsteigen muss oder sein Problem höchstwahrscheinlich an anderer Stelle zu finden sein wird.
gtoXX hat geschrieben:Ausführliche Textkommentare bedeuten schlechten Code um es mal provokant zu sagen. Wenn ich Parameter beschreiben muss verschwende ich Zeit und Geld.

Wenn eine Routine sinnvoll benannt ist, benötige ich keinerlei Kommentare.
So einen Unfug habe ich schon lange nicht mehr gehört. Gute Ausrede für Entwickler, die zu faul zum Dokumentieren sind. Aber fremder Code, der ja immer auch mit fremden Philosophien geschrieben worden ist, ist ohne Kommentar unverständlich. Zumal nicht nur die grobe Aufgabe der Routine, wie ich sie im (maximal dreißigzeichigen) Namen skizzieren kann, von Bedeutung ist, sondern auch der genaue Inhalt ihrer Parameter, also wann welcher Parameter welchen Wert haben sollte bzw. im Fall von Rückgabeparametern welchen Wert haben wird.
gtoXX hat geschrieben:Dein Gedanke ist grundsätzlich erstmal nachvollziehbar. Leider ist es trotzdem der falsche Ansatz nach meiner Meinung. Erweiterbarkeit, Wiederverwendung und Austauschbarkeit sind hier nicht gewährleistet. Geschweige denn, das Unit-Tests möglich sind.

Denn bei einer Änderung an der Form WRITE_DATA sollten Pass1 und Pass2 noch immer das Gleiche tun wie vorher.
Du hast es nicht verstanden, und zwei andere, die sich bei Dir dafür bedankt haben, demnach auch nicht.

Die Form WRITE_DATA besteht nur aus Pass 1 und Pass 2, wie Du selber zitiert hast!!! Damit gibt es keine Änderung an dieser Form, die keine Änderung an Pass 1 oder Pass 2 wäre, und Deine ganze Aussage ergibt keinen Sinn mehr. Die Aufgabe, die Daten zurückzuschreiben, besteht genau aus diesen beiden Teilen. Und genau das ist der Grund, weshalb ich getrennte Unit Tests für Pass 1 und Pass 2 für unnötig halte, denn nur gemeinsam bewerkstelligen sie die an dieser Stelle geforderte Aufgabe. Entweder die Form WRITE_DATA sorgt dafür, dass hinterher auf der Datenbank die gleichen Daten stehen wie in der internen Tabelle, oder sie tut es nicht. Das ist der Unit Test, um den es hier geht, nicht um Teiltests irgendwelcher Fragmente.
black_adept hat geschrieben:😇 Für deine Ausführungen gibt es eine schöne Beschreibung in einem recht sehenswerten englischen Youtube Video über Anti-Patterns ( Anti-Entwurfsmuster ).
Wer direkt einsteigen will: Bei Minute 1:57 ( direkt nach den Vorbemerkungen zu Anti-Patterns ) wird mit dem Antipattern 1 genau das beschrieben inklusive der Konsequenzen.
Herrlich beschrieben! 😎
gtoXX hat geschrieben:Und einfach weil es so schön Lesenswert ist :

https://de.wikipedia.org/wiki/Anti-Pattern
Ich glaube, Du hast noch nicht einmal verstanden, dass die von black_adept verlinkte Videostelle ab Minute 1:57 mir genau das Wort redet. Und das, obwohl er das explizit noch dazugesagt hat...
Zuletzt geändert von DeathAndPain am 18.01.2020 10:04, insgesamt 1-mal geändert.

Folgende Benutzer bedankten sich beim Autor DeathAndPain für den Beitrag (Insgesamt 2):
Ichse2 (17.01.2020 13:54) • Legxis (20.01.2020 11:56)


Re: Method für die Durchschnittsberechnung

Beitrag von ewx (Top Expert / 4124 / 183 / 417 ) » 17.01.2020 14:06

DeathAndPain hat geschrieben:
17.01.2020 13:38
Es geht z.B. genauso die Zuweisung einer funktionalen Methode mit einem riesigen Rattenschwanz an Parametern.
Das stimmt. Das hatte ich vergessen.
Ist aber im Grunde egal, ob ich in die Definition der Routine klicke, um zu sehen, wie der Returning-Parameter definiert ist, oder zur DATA-Anweisung verzweige.

Re: Method für die Durchschnittsberechnung

Beitrag von DeathAndPain (Top Expert / 1267 / 138 / 291 ) » 17.01.2020 14:36

Du wirst auf den Namen der Variable doppelklicken, damit zur DATA-Anweisung katapultiert, findest dort nichts Brauchbares und musst daher von dort aus per weiterem Doppelklick zur Definition der Methode abspringen, in deren Definition der RETURNING-Parameter anders heißt. Dort musst den Namen Deines Feldes geistig auf den Namen des RETURNING-Parameters mappen und dessen Typ nachsehen. Machbar? Ja. Schön? Nein.

Re: Method für die Durchschnittsberechnung

Beitrag von gtoXX (Specialist / 124 / 26 / 18 ) » 17.01.2020 16:09

DeathAndPain hat geschrieben:
17.01.2020 13:38
Black_adept hat geschrieben:Du verwendest aber evtl. gleiche Variablen in Block A und B. Du kannst also mit einer Änderung in Block A das Verhalten von Block B verändern, ohne dass es dir bewusst ist!
Das meinte ich, als ich sagte: "Die einzige theoretisch mögliche Wechselwirkung wäre ein vergessener CLEAR zwischen den Pässen. Aber der ist für mich kein ausreichendes Entscheidungskriterium."

Natürlich sollte Block B nicht mit den Werten aus Block A weiterarbeiten, sondern eigenständig sein.
Ein klassisches Beispiel für Codebloating. Unnütze Codezeilen wie Clearings, die bei klarer Trennung nicht notwendig sind.
DeathAndPain hat geschrieben:
17.01.2020 13:38


Glaubst Du das? Es geht z.B. genauso die Zuweisung einer funktionalen Methode mit einem riesigen Rattenschwanz an Parametern. Dann musste erst mal schauen, wie die parametrisiert ist, bevor Du den Datentyp Deiner neuen Variable kennst. Zudem ist die "Zuweisungszeile" dann soundsoviel Bildschirmzeilen lang. Das ist um Größenordnungen unübersichtlicher ...
Also das ist eine sehr unüberlegtes Argument. Methoden zu verwenden, über deren Ergebnis sich man vorher nicht informiert hat, wäre absolut unüberlegt. Natürlich weisst Du welchen Typ dein Ergebnis hat.
DeathAndPain hat geschrieben:
17.01.2020 13:38
Das ist Theorycrafting, wie auch Kay ein Akademiker war. In der Praxis hast Du zwar bedingt recht, aber Code, den man gelesen oder ausreichend überflogen hat, so dass einem weitestgehend klar ist, was da passiert, kann man gedanklich tatsächlich abhaken. Bei dem anderen stellt man sich immer wieder die Frage: "Habe ich jetzt richtig interpretiert, was SCHREIBE_MATERIALDATEN sicherlich machen wird? Oder muss ich da doch noch mal einsteigen und noch tiefer in die Verästelungen runter, um zu analysieren, was die Befehle, äh, Unterprogramme, die da definiert werden, eigentlich tun?"

Das ist die Realität, so wie ich sie erlebe. Die Tatsache, dass Routinennamen in ABAP auf gerade mal 30 Zeichen beschränkt sind, lässt die Annahme, man könne damit ausdrücken, was sie genau bewerkstelligen, als geradezu zynisch erscheinen. Aber selbst, wenn es 80 Zeichen wären, würde das nicht ausreichen, um demjenigen, der das Programm nicht kennt, ausreichend genau zu vermitteln, was die Routine tut und was die Bedeutung der Felder ist, die rein- und rausgehen. Den tatsächlichen Code zu begutachten mag aufwendig sein, aber wenn ich den untersucht habe, dann weiß ich, was da passiert.

Vor allem, weil man fremden Code meist dann begutachten muss, wenn er nicht das tut, was er soll, wenn also irgendwo ein Bug drin ist. Da ist es dann blöd, wenn ich mich auf mein Verständnis des Namens einer Unterroutine verlasse, damit sogar recht habe, aber diese aufgrund eines Bugs eben doch nicht genau das macht, was ich erwarte und ich rätselrate, ob das Programmverhalten an der Stelle, die ich gerade untersuche, falsch ist oder nur meine Einschätzung des Sollverhaltens der Routine nicht stimmt. Bei ABAP-Befehlen weiß ich genau, was sie tun, und Bugs auf dieser Ebene sind auch nahezu auszuschließen. Da steht man auf viel sichererem Boden.


Wohlgemerkt: ich rede keinem unmodularisierten Spaghetticode das Wort. Aber die Aufteilung in Unterprogramme sollte so gewählt sein, das jedes eine klar definierte Aufgabe umfasst, die dann auch sorgsam zu dokumentieren sich lohnt. Dann kann der Leser sich diese Doku (da können 3 Sätze reichen) durchlesen, hat eine Vorstellung davon, was diese Routine macht, weiß, dass diese Vorstellung richtig ist, da sie nicht nur auf seiner Interpretation von Prozedurnamen beruht, und kann abhängig von seiner Problemstellung beurteilen, ob er in diese Routine tiefer einsteigen muss oder sein Problem höchstwahrscheinlich an anderer Stelle zu finden sein wird.
Wenn Du es mal eingesetzt hättest, würdest Du sehen, das es von Theocrafting weit entfernt ist. Klar, wenn ich nur write-and-forget-code schreibe mag es übertrieben erscheinen.

Deine Argumentationskette ist auch nicht logisch. Wenn ich einen Bug suche in mir fremden Code, schaue ich per se in jede Zeile. Auch in Unteroutinen. Wenn die Modularisierung sinnvoll gewählt ist, reichen auch 30 Zeichen für einen Namen aus.
Da brauche ich nicht in jede Unterroutine schauen.
DeathAndPain hat geschrieben:
17.01.2020 13:38
So einen Unfug habe ich schon lange nicht mehr gehört. Gute Ausrede für Entwickler, die zu faul zum Dokumentieren sind. Aber fremder Code, der ja immer auch mit fremden Philosophien geschrieben worden ist, ist ohne Kommentar unverständlich. Zumal nicht nur die grobe Aufgabe der Routine, wie ich sie im (maximal dreißigzeichigen) Namen skizzieren kann, von Bedeutung ist, sondern auch der genaue Inhalt ihrer Parameter, also wann welcher Parameter welchen Wert haben sollte bzw. im Fall von Rückgabeparametern welchen Wert haben wird.
1. Für mich sind zuviele Kommentare ein Zeichen für Faulheit zum sinnvollen Programmdesign
2. Ausführliche Kommentare sind eine unzuverlässige Quelle.
a). Sie kosten bei jeder Änderung sinnlose Wartungszeit
b). Es ist nie sichergestellt, dass das Kommentar die Realität widerspiegelt. Wenn Du das Video verstanden hättest, hättest Du mitbekommen, das er genau das anprangert.

Oder um einen ehemaligen Kollegen zu zitieren "Code lügt nicht."

Es heisst nicht gar nicht zu kommentieren. Aber sich nicht so ausufernd, wie Du es beschreibst. Und nebenbei : Dein bester Kommentar wäre ein Unit test. Denn wenn Du diesen schreibst, weiß man ganz genau welchen Rückgabewert Du bei welchem Input erwartest - und ganz entscheidend - Wenn dein Code sich ändert, bist du gezwungen diesen Kommentar auf jeden Fall zu aktualisieren, damit der nächste Test funktioniert.


DeathAndPain hat geschrieben:
17.01.2020 13:38
Du hast es nicht verstanden, und zwei andere, die sich bei Dir dafür bedankt haben, demnach auch nicht.
Ich habe es sehr wohl verstanden. Du hast 2 funktionale Einheiten, die in einem Programmteil benutzt werden. Was Du nicht verstanden hast ist : Wie sie das tun was Du willst, kann deiner verwendenden Routine egal sein. Und wenn sie angepasst werden müssen um noch zu funktionieren, funktioniert das in deinem Coding nicht, weil sie nicht autark sind. Ich muss dazu noch verstehen, was dein Umfeld-Coding macht um nicht aus Versehen etwas kaputt zu machen. Bei einer vernünftigen Trennung ist das nicht nötig.

Brauche ich einen Teil von beidem noch woanders kommt das Anti-Pattern "Copy und Paste" zum Einsatz.

Der Denkfehler hier ist, das Du dies für 1 Funktion hältst. Es sind aber 2 autarke Operationen. Diese beiden kombiniert ergeben die Funktion WRITE.

Wir verwenden ein generisches DAO für genau diesen Versionsabgleich (Alt - Neu ).
Wobei wir dank GUIDs als technische Schlüssel nicht auf das Delete angewiesen sind, wenn der semantische Schlüssel sich ändert. Ich weiß das SAP das in der Alt-Welt so gemacht hat.

Dieses DAO verwendet intern die selbe Lesemethode, die man sonst auch zum Lesen von Datensätzen benutzt. Dann wird abgeglichen, was schon auf der DB war und demzufolge zu updaten ist oder was zu inserten ist.

Wenn ich jetzt an der Lesemethode was ändern muss, muss ich keine einzige Verwendungsstelle anpassen. Und habe genau 1 Änderung für aktuell 160 Objekte die danach genauso fehlerfrei arbeiten wie davor.

Für eine DB-Operation mag dein Beispiel noch gehen. In der Anwendungsentwicklung ist und bleibt es schlecht.
"Code lügt nicht ^^"

Re: Method für die Durchschnittsberechnung

Beitrag von DeathAndPain (Top Expert / 1267 / 138 / 291 ) » 20.01.2020 09:25

Ich steig da jetzt nicht weiter drauf ein; das bringt nichts, da Deine Worte zeigen, dass Du es auch weiterhin nicht verstanden hast und ich nicht den Eindruck habe, dass ich es Dir begreiflich machen kann.

Re: Method für die Durchschnittsberechnung

Beitrag von black_adept (Top Expert / 3341 / 60 / 623 ) » 20.01.2020 09:47

gtoXX hat geschrieben:
17.01.2020 16:09
1. Für mich sind zuviele Kommentare ein Zeichen für Faulheit zum sinnvollen Programmdesign
2. Ausführliche Kommentare sind eine unzuverlässige Quelle.
a). Sie kosten bei jeder Änderung sinnlose Wartungszeit
b). Es ist nie sichergestellt, dass das Kommentar die Realität widerspiegelt.
Ad 1.) ZU viel von jedem ist schlecht. Sogar Sauerstoff . Aber ausführliche Kommentare sind kein Zeichen von Faulheit sondern einfach nett gegenüber denjenigen die ein Programm warten sollen. Ich freue mich immer wieder über Codestrecken wo ein "Siehe Ticket .... Folgendes Problem war damals aufgetaucht.... Anforderer war... , Folgender Lösungsansatz wurde gewählt weil... " oder auch nur Teile davon stehen. Wenn nicht hätte ich desweilen den einen oder anderen Code entsorgt weil er sinnlos aussah aber der Kommentar hat mir verraten dass dem in diesem speziellen Fall nicht so war. Oder an wen ich mich wenden konnte wenn wir weiter an der Ecke rumschrauben wollten.

Ad 2a) Das meinst du nicht ernst, oder?
Ad 2b) Wenn sie das nicht tun darf man den Verfasser des Kommentars oder desjenigen, der den Code so abgewandelt hat, dass der Kommentar nicht mehr stimmt teeren und federn.
gtoXX hat geschrieben:
17.01.2020 16:09
Dein bester Kommentar wäre ein Unit test.
In der Theorie ja, in der Praxis wo es die eine oder andere Budgetlimitierung gibt ( Zeit oder Geld ) bei den Kunden für die ich bisher gearbeitet habe scheinbar nicht ( auch nicht auf Anfrage! )
Und anlehnend an dein 2b): Es ist auch nicht sichergestellt, dass ein Unittest die Realität wiederspiegelt sondern nur die Testfälle die man für relevant gehalten hat.

Folgende Benutzer bedankten sich beim Autor black_adept für den Beitrag:
DeathAndPain (20.01.2020 10:47)

live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Method für die Durchschnittsberechnung

Beitrag von DeathAndPain (Top Expert / 1267 / 138 / 291 ) » 20.01.2020 10:56

Aber ausführliche Kommentare sind kein Zeichen von Faulheit sondern einfach nett gegenüber denjenigen die ein Programm warten sollen. Ich freue mich immer wieder über Codestrecken wo ein "Siehe Ticket .... Folgendes Problem war damals aufgetaucht.... Anforderer war... , Folgender Lösungsansatz wurde gewählt weil... " oder auch nur Teile davon stehen.
Genau. Am Anfang meiner Routinen (oder vor komplizierteren LOOPs etc.) steht auch ein Textblock, der schildert, was dieser Code-Teil tun soll und was ich mir bei meinem Lösungsweg gedacht habe. Dann hat jeder, der später daran Änderungen vornehmen möchte (mich selbst eingeschlossen) die Chance, diese Überlegungen einzubeziehen und den Code im Kontext zu sehen.

Auch wenn ich für die Lösung eines Detailproblems mal eine syntaktisch elegant-kurze, aber auf den ersten Blick nicht gleich verständliche Implementierung gewält habe, schreibe ich gern mal etwas Text dazu, der erläutert, was ich mir dabei gedacht habe.
Ad 2b) Wenn sie das nicht tun darf man den Verfasser des Kommentars oder desjenigen, der den Code so abgewandelt hat, dass der Kommentar nicht mehr stimmt teeren und federn.
An der Stelle liegt die Wahrheit in der Mitte, denn nicht immer trifft der Kommentar trotz bester Absichten seines Autors genau das Programmverhalten. Im Gegensatz zu Code kann man Kommentartext halt nicht testen und debuggen.

Dennoch ist der Kommentar wichtig, weil er das Sollverhalten schildert und den gedanklichen Hintergrund, auf dem der Code entstanden ist, erkennbar macht. Dadurch erlangt man meist die Fähigkeit zu beurteilen, ob bestimmte Codeelemente Teil des Designs oder Programmierfehler sind, und wenn der Code doch mal vom Kommentar abweicht, ohne dass dies ein Programmierfehler ist, versteht man meist auch, wie es dazu kommen konnte (möglicher Spezialfall wurde im Kommentar nicht erwähnt, aber im Code beachtet etc.).

Vorherige Seite 2 von 2 (current)