Wieviele LOC für Funktion?



  • knivil schrieb:

    Eine Java-Philosophie :). Dazu ein etwas kritischer Artikel: execution-in-kingdom-of-nouns

    Sehe den Zusammenhang nicht. In Java packt man alles in Klassen weil man nicht anders kann. Es ist nunmal so, dass ein Nomen ein hinweis auf eine Klasse ist. Natuerlich muss man auch so weit gehen und sagen ein verb ist ein Hinweis auf eine Funktion. Und ein Adjektiv ist ein Hinweis auf ein Property. Aber darum geht es hier ja nicht. Wenn ich eine struct erstelle, dann kann ich daraus gleich was ordentliches machen mit Ctor. Und das ist der Punkt.

    Structs die nur Daten enthalten habe ich eigentlich nie - weil es keinen Vorteil bringt. Wenn ich eine struct habe die Daten enthaelt, kann ich gleich einen Ctor und gaengige Funktionen zur Manipulation von ihnen anbieten.

    Bestes Beispiel ist hier wohl volkards Stack Beispiel. Wenn man entitaeten in sich schliesst, dann kuerzt man Code enorm (und vorallem: man macht ihn robuster).

    Xebovs Code wuerde zB sogar einen enormen Geschwindigkeitsvorteil bekommen...



  • volkard schrieb:

    ein klassiker ist das stack::push.

    Das ist aber unlauterer Wettbewerb. Ein Stack ist etwas generisches, außerdem das Standardbeispiel in unzähligen Büchern und Tutorials. Eine einzigartige Applikationslogik in gleicher Weise auseinanderzustrahieren ist ungleich schwerer, der Nutzen nicht unmittelbar einsichtig, manchmal ist es sogar kontraproduktiv.



  • Shade Of Mine schrieb:

    Xebov schrieb:

    Viel Spaß beim auseinandernehmen, bin echt mala uf das Ergebniss gespannt.

    Komplettes redesign.

    Seh ich genauso. Man könnte auch erwidern: Viel Spaß beim Debuggen. Viel Spaß beim Pflegen. Viel Spaß beim Verstehen wenn der Code nach 6 Monaten wieder angefasst werden muss.



  • Bashar schrieb:

    Eine einzigartige Applikationslogik in gleicher Weise auseinanderzustrahieren ist ungleich schwerer, der Nutzen nicht unmittelbar einsichtig, manchmal ist es sogar kontraproduktiv.

    👍



  • Bashar schrieb:

    Eine einzigartige Applikationslogik in gleicher Weise auseinanderzustrahieren ist ungleich schwerer,

    Ist eine Behauptung. Gegegenbehauptung: Ist nur dann schwerer wenn die Logik in schlechtem Design umgesetzt wird.

    der Nutzen nicht unmittelbar einsichtig,

    Wie stehts mit Lesbarkeit, Wartbarkeit, Verständlichkeit, Erweiterbarkeit? Ist das nicht Nutzen genug?

    manchmal ist es sogar kontraproduktiv.

    Definiere kontraproduktiv in dem Zusammenhang und zeig dann wo es kontraproduktiv sein soll. Ich stimme nur dann zu, wenn kontraproduktiv = "kurzfristig zeitaufwändiger (und langfristig interessiert nicht)"



  • manchmal. und vor allem sind die gewinne nicht unmittelbar ersichtlich, weshalb mans besser trotzdem tut.



  • Shade Of Mine schrieb:

    Xebovs Code wuerde zB sogar einen enormen Geschwindigkeitsvorteil bekommen...

    Wieso würde der Code nen Geschwindigkeitsvorteil bekommen? Was spricht den gegen ein Struct zum lagern der Daten? Was hätte ich davon wenn ne Modelklasse die daten in ein Array legt und diese daten in enr eigenen klasse sind und somit alles was rein muß zu den datens elbst durch muß statt vond er Klasse direkt behandelt zu werden, das wäre ja doppelt gemoppelt.



  • pumuckl schrieb:

    Bashar schrieb:

    Eine einzigartige Applikationslogik in gleicher Weise auseinanderzustrahieren ist ungleich schwerer,

    Ist eine Behauptung. Gegegenbehauptung: Ist nur dann schwerer wenn die Logik in schlechtem Design umgesetzt wird.

    Ich verstehe deine Gegenbehauptung nicht. Ein gutes Design zu finden ist nur schwer, wenn man es schlecht macht?

    der Nutzen nicht unmittelbar einsichtig,

    Wie stehts mit Lesbarkeit, Wartbarkeit, Verständlichkeit, Erweiterbarkeit? Ist das nicht Nutzen genug?

    Doch, aber das bekommst du nicht automatisch. Dazu muss das Design nämlich auch gut sein. Den Code von Xebov kann man einfach von oben nach unten lesen und verstehen. Wenn du das ganze durch ein Klassenkonstrukt ersetzt, wird es erstmal komplizierter, es sei denn, du machst es wirklich richtig gut.

    manchmal ist es sogar kontraproduktiv.

    Definiere kontraproduktiv in dem Zusammenhang und zeig dann wo es kontraproduktiv sein soll. Ich stimme nur dann zu, wenn kontraproduktiv = "kurzfristig zeitaufwändiger (und langfristig interessiert nicht)"

    Kontraproduktiv heißt, dass der Code schwerer verständlich und weniger wartbar wird.



  • Bashar schrieb:

    Ich verstehe deine Gegenbehauptung nicht. Ein gutes Design zu finden ist nur schwer, wenn man es schlecht macht?

    Nein. Ein gutes Design ist schwer zu finden wenn schon das übergeordnete Design schlecht ist.

    Doch, aber das bekommst du nicht automatisch. Dazu muss das Design nämlich auch gut sein. Den Code von Xebov kann man einfach von oben nach unten lesen und verstehen. Wenn du das ganze durch ein Klassenkonstrukt ersetzt, wird es erstmal komplizierter, es sei denn, du machst es wirklich richtig gut.

    Den Code von Xebov find ich alles andere als leicht zu lesen und zu verstehen. Die Funtkion erfüllt mehrere Aufgaben auf einmal, auf verschiedenen Abstraktionsebenen (von byteweise I/O bis zu den ModelParts) und benutzt zu allem Überfluss auch noch schlecht gewählte Namen (wenn ich ModelParts und Model lese, gehe ich davon aus, dass Model ein Modell ist, das aus modelParts besteht - es scheint sich aber um eine Datei zu handeln). Natürlich muss das Design gut sein damit man die Vorteile von sauberem Code nutzen kann. Aber ein gutes Design zu finden ist eben nicht so schwer wie einige behaupten.

    Kontraproduktiv heißt, dass der Code schwerer verständlich und weniger wartbar wird.

    Noch schwerer verständlich als ein Moloch von über 60 Zeilen wäre nur eine Funktion mit noch mehr Zeilen oder schlechter gewählten Variablennamen. Ich werd mich nachher zu Hause mal kurz dransetzen und versuchen zu skizzieren wie man die Funktion ein wenig lesbarer gestalten könnte.



  • pumuckl schrieb:

    Den Code von Xebov find ich alles andere als leicht zu lesen und zu verstehen. Die Funtkion erfüllt mehrere Aufgaben auf einmal, auf verschiedenen Abstraktionsebenen (von byteweise I/O bis zu den ModelParts) und benutzt zu allem Überfluss auch noch schlecht gewählte Namen (wenn ich ModelParts und Model lese, gehe ich davon aus, dass Model ein Modell ist, das aus modelParts besteht - es scheint sich aber um eine Datei zu handeln). Natürlich muss das Design gut sein damit man die Vorteile von sauberem Code nutzen kann. Aber ein gutes Design zu finden ist eben nicht so schwer wie einige behaupten.

    Das leseproblem liegt nur daran das du die Klassenvariablen nicht kennst. Die Funktion ist von oben nach unten zu lesen, sie liest nur Daten ein und reicht sie ggf an die Richtige Stelle weiter, ich sehe da keine Stellen wo die Funktion nochetwas anderes tut als einlesen und weitergeben. Die Funktion liest aus einer Modelldatei die Modell-Teile ein. Deswegen heist die Datei auch Model. Leichte rweiterbar ist die Funktion auch, ich hab für den Dateitypen eine Kleine Dokumentation geschrieben in der steht was an welcher Stelle steht und in welchem Format.

    Um dir noch etwas Überblick zu verschaffen wenn du dann selbst was Skizieren willst. Die Funktion ist Teil eienr Gruppe von Einlesefunktionen, die Klasse öffnet eine Modell-Datei als Model und fängt an einzulesen (das Dateidesign habe ich so gemacht das man sie ohne springen am Stück von oben nahc unten lesen kann) Sie liest aus der datei die Anzahl der Model-Teile aus (ModelParts) und erstellt ein Array eienr Struktur in richtiger Größe (ModelParts) dieses Struktur beinhaltet alle Details über den Modelteil, und diese Details werden in dieser Funktion nacheinander für jeden ModelPart eingelesen (die liegen auch in der Datei hintereinander)



  • pumuckl schrieb:

    Den Code von Xebov find ich alles andere als leicht zu lesen und zu verstehen.

    naja, echt schrecklich ist was anderes. der code geht so. und ist unreparierbar, außer man schmeißt verdammt viel weg. außerdem ist bei gamecoderz manches suboptimal, deaswegen liest sich der code auch ganz angenehm, weil man diese funktion und ihre vettern schon lange kennt. und wenn man's anders macht, entfernt man sich von der gemeinde, was beim gegenseitig-helfen wieder von nachteil ist.



  • Das leseproblem liegt nur daran das du die Klassenvariablen nicht kennst

    super - damit ist er wohl wartbar, wenn man erst alle klassenvariablen kennen muss, um den code zu verstehen? Oo

    die Funktion nochetwas anderes tut als einlesen und weitergeben

    also erfüllt sie nur eine aufgabe - oder doch mehrere?!

    klar macht es ihn nicht zu furchtbar schlechtem code, den niemals mehr wieder irgendwer verstehen kann - aber es macht ihn nicht zu perfektem Code - und das man ihn übersichtlicher gestalten könnte, solltest du nun auch langsam mal glauben ^^

    bb



  • volkard schrieb:

    und wenn man's anders macht, entfernt man sich von der gemeinde, was beim gegenseitig-helfen wieder von nachteil ist.

    Das ist mal eine Legitimation. 😉

    Man kann übrigens auch beim Spiele-Programmieren versuchen, aufs Design zu achten. Bei dieser Art von Programmen, die unter Umständen besonders bug- und wartungsanfällig ist, kann sich das erst recht auszahlen. Manchmal ist sauberes Design eben nicht ganz einfach, besonders, wenn man faul ist und schnelle Resultate erzielen möchte. Es braucht relativ viel Erfahrung, bis man merkt, welche Strukturierung einem Vorteile in der Handhabung bringt und sich auch längerfristig bewährt...

    unskilled schrieb:

    aber es macht ihn nicht zu perfektem Code

    Irgendwann kommt der Punkt der Entscheidung zwischen Aufwand für Design und Zweckmässigkeit der Applikation. Am Design kann man oft ewig weiterfeilen, bei komplexeren Problemen wird es immer mehrere Lösungen geben, und so richtig gefällt einem meist doch keine, egal, wie lange man schon daran gearbeitet hat. 😉



  • pumuckl schrieb:

    Bashar schrieb:

    Ich verstehe deine Gegenbehauptung nicht. Ein gutes Design zu finden ist nur schwer, wenn man es schlecht macht?

    Nein. Ein gutes Design ist schwer zu finden wenn schon das übergeordnete Design schlecht ist.

    Letzteres kann man in jedem größeren Projekt als gegeben annehmen, daher q.e.d. 😉

    Den Code von Xebov find ich alles andere als leicht zu lesen und zu verstehen. Die Funtkion erfüllt mehrere Aufgaben auf einmal, auf verschiedenen Abstraktionsebenen (von byteweise I/O bis zu den ModelParts) und benutzt zu allem Überfluss auch noch schlecht gewählte Namen (wenn ich ModelParts und Model lese, gehe ich davon aus, dass Model ein Modell ist, das aus modelParts besteht - es scheint sich aber um eine Datei zu handeln).

    Die gewählten Namen könnten ein Problem sein, allerdings kein Designproblem. Dass die Funktion mehrere Aufgaben auf einmal erfüllt, ist nur dann ein Problem, wenn man diese Teilfunktionalitäten auch separat nutzen möchte. Dann muss man nämlich Code duplizieren. Ob das hier der Fall ist? Aber Wiederverwendbarkeit und Verständlichkeit sind zwei verschiedene Paar Schuh.
    Verschiedene Abstraktionsebenen sind es, weil die Funktion die Schnittstelle zwischen zwei solchen bildet, sie konstruiert ja High-Level-Objekte aus Bytes.

    Noch schwerer verständlich als ein Moloch von über 60 Zeilen wäre nur eine Funktion mit noch mehr Zeilen oder schlechter gewählten Variablennamen. Ich werd mich nachher zu Hause mal kurz dransetzen und versuchen zu skizzieren wie man die Funktion ein wenig lesbarer gestalten könnte.

    Können wir die Variablennamen mal beiseite lassen? Mir geht es um Design, also etwas strukturelles. Und "lesbar" ist auch dehnbar. Mich interessieren konkrete Designprobleme.



  • unskilled schrieb:

    super - damit ist er wohl wartbar, wenn man erst alle klassenvariablen kennen muss, um den code zu verstehen? Oo

    Nein man muß nicht alle kennen, aber du kannst ja nun auch keinen motor Reparieren wenn du nur 4 Schrauben davon kennst oder?

    unskilled schrieb:

    also erfüllt sie nur eine aufgabe - oder doch mehrere?!

    Eine, Daten einlesen und an einigen Stellen werden sie weitergegeben wenn sie nicht direkt verwertbar sind.



  • ok - du hast recht...

    der rest ist dumm, hat keine ahnung oder naja.. ist einfach im unrecht...

    hf



  • unskilled schrieb:

    ok - du hast recht...

    der rest ist dumm, hat keine ahnung oder naja.. ist einfach im unrecht...

    hf

    Bist du jetzt beleidigt weil ich bei eienr Klassenfunktion vorraussetze das man dir Klassenvariablen zum Teil kennt und weil ich es nunmal als eine Aufgabe ansehe die Daten einzulesen und weiterzugeben?



  • Xebov schrieb:

    Wieso würde der Code nen Geschwindigkeitsvorteil bekommen?

    Weil du dir den temporaeren Speicher sparen kannst den du dauernd per new anforderst. Je nachdem wieviel Daten du da hin und her schaufelst kann das relevante Vorteile bringen es einzusparen.

    Was spricht den gegen ein Struct zum lagern der Daten?

    Nichts, nur dass man dann eben auch noch einen Ctor definiert und uU named ctors um die Daten leichter initialisieren zu koennen.

    Was hätte ich davon wenn ne Modelklasse die daten in ein Array legt und diese daten in enr eigenen klasse sind und somit alles was rein muß zu den datens elbst durch muß statt vond er Klasse direkt behandelt zu werden, das wäre ja doppelt gemoppelt.

    Eine struct ist eine Klasse. Einer struct einen ctor und uU sinnvolle Methoden zu geben tut nicht weh. Zumindest der Ctor sollte sein. Da du zB bei deinem Code immer doppelte Initialisierungen hast. Das ist fehleranfaellig. Lieber die Daten gleich direkt initialisieren - das bringt nicht nur mehr lesbarkeit und oft mehr performance, sondern erleichtert auch die Wartbarkeit enorm.

    Wie gesagt, das ganze etwas generischer aufbauen und vorallem von dem rohen lesen der Datei weggehen. Das waere der wichtigste Schritt. Der Rest kommt dann von alleine.

    ob im nachhinein ein redesign sinn macht sei mal dahingestellt. meistens kostet refactoren zuviel zeit. aber wenn moeglich wuerde ich das design so frueh wie moeglich so schoen wie moeglich hinbekommen.

    das bisschen zeit das man dadurch verliert ist irrelevant wenn man dann naemlich spaeter die anforderungen anpassen muss (was bei jedem groesseren projekt sowieso passiert) und dann hat man die zeit wieder drinnen. deshalb: wenn man die zeit hat, so gut designen wie irgend moeglich. gerade am anfang vom projekt ist genug zeit da - die laeuft erst gegen ende aus.



  • Xebov schrieb:

    Nein man muß nicht alle kennen, aber du kannst ja nun auch keinen motor Reparieren wenn du nur 4 Schrauben davon kennst oder?

    Nö, aber immerhin hat so ein Motor Schrauben. Deiner ist aus einem Stück gegossen und müsste weggeschmissen werden, wenn er kaputt ist.



  • die Funktion nochetwas anderes tut als einlesen und weitergeben

    und temporäre dynamische Arrays verwalten und den Chunk verwalten (wozu auch immer der gut sein soll) und über das ganze Array iterieren...

    Ich bin schon dabei, dauert noch bissl...
    Wird auch noch keinesfalls zufriedenstellend, da ich die äußeren Gegebenheiten nicht kenne.


Anmelden zum Antworten