Warum jammern alle über schlechten Code?



  • Eisflamme schrieb:

    Dementsprechend sollten aber auch "Seniors" oder "Leads" dementsprechende Code-Reviews auf regelmäßiger Basis durchführen, Schwachstellen aufspüren, und in kurzen 5min-Reviews (bspw. beim täglichen Standup-Meeting) auf die Probleme die daraus resultieren hinweisen und "besseren" Code zeigen + warum der Code besser ist. Das Ausbessern selbst dann am besten gleich dem Verursacher überlassen, so lernt er dazu + bekommt nicht das Gefühl, dass es eh jemanden gibt der auf ihn aufpasst und seine Code-Qualität egal ist.

    Herrlich wäre das. Aber das klingt für mich nach "Schweben in sieben Wolken". Wo passiert so was denn? Und der Chefentwickler muss die entsprechende Kompetenz haben, um die Designfehler des Originalcodes fein auszuweisen und gleichzeitig einen schöneren Code darzustellen. Dafür besteht im Regelfall wohl leider kaum Zeit.

    Das müsste aber jemand machen, der nur daran interessiert ist, richtige Probleme zu fixen. Sobald es nämlich darum geht aus funktionierendem & nicht allzu schlimmem Code irgendwelche eleganten/idiomatischen Lösungen zu machen ... gute Nacht.



  • Ethon schrieb:

    Eisflamme schrieb:

    Dementsprechend sollten aber auch "Seniors" oder "Leads" dementsprechende Code-Reviews auf regelmäßiger Basis durchführen, Schwachstellen aufspüren, und in kurzen 5min-Reviews (bspw. beim täglichen Standup-Meeting) auf die Probleme die daraus resultieren hinweisen und "besseren" Code zeigen + warum der Code besser ist. Das Ausbessern selbst dann am besten gleich dem Verursacher überlassen, so lernt er dazu + bekommt nicht das Gefühl, dass es eh jemanden gibt der auf ihn aufpasst und seine Code-Qualität egal ist.

    Herrlich wäre das. Aber das klingt für mich nach "Schweben in sieben Wolken". Wo passiert so was denn? Und der Chefentwickler muss die entsprechende Kompetenz haben, um die Designfehler des Originalcodes fein auszuweisen und gleichzeitig einen schöneren Code darzustellen. Dafür besteht im Regelfall wohl leider kaum Zeit.

    Das müsste aber jemand machen, der nur daran interessiert ist, richtige Probleme zu fixen. Sobald es nämlich darum geht aus funktionierendem & nicht allzu schlimmem Code irgendwelche eleganten/idiomatischen Lösungen zu machen ... gute Nacht.

    Was ist eine idiomatische Lösung? Hab das Wort neulich in der Java-"Fachdiskussion" auch dauernd gelesen, finde aber im Netzt keine passende Übersetzung.



  • Redewendungen in C++. Sowas: http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms . Also spezielle Patterns in der jeweiligen Programmiersprache (hier C++), die in anderen Programmiersprachen aufgrund anderer Sprachmittel anders geloest werden muessen/koennen. Im Gegensatz dazu sind Designpatterns nicht zwingend an die Sprache sondern vielmehr an das Paradigma beispielsweise OOP gebunden.



  • Was Idiome sind, wußte ich schon.

    Also ist eine idiomatische Lösung eine, die Idiome benutzt? Tut doch eh jede. Und warum verwenden so viele "idiomatisch", wenn sie "kanonisch" meinen?



  • Habe eine mir vertraute Bedeutung für idiomatisch gefunden: http://www.wortbedeutung.info/idiomatisch/

    Zum Thema: Es gibt keine Messregel für die Qualität von Code mit einer Skala von z.B. 0 (sehr schlecht) bis 100 (sehr gut).

    Es gibt nur einige Ansprüche:
    - soll sicher funktionieren
    - soll auch Ausnahmefälle berücksichtigen
    - soll übersichtlich strukturiert und nachvollziehbar sein, auch für fremde Personen oder die Entwicklung im Team
    - soll hinreichend dokumentiert sein
    - soll für Änderungen und Erweiterungen vorbereitet sein
    - muss den Kostenrahmen einhalten

    Ich denke, das reicht. Alles weitere ist Praxis, nicht unbedingt Wissenschaft.



  • volkard schrieb:

    Was Idiome sind, wußte ich schon.

    Also ist eine idiomatische Lösung eine, die Idiome benutzt? Tut doch eh jede. Und warum verwenden so viele "idiomatisch", wenn sie "kanonisch" meinen?

    Die Frage verstehe ich nicht ganz. Mir hilft vielleicht ein Beispiel: Was ist die kanonische/idiomatische Implemtieriung eines Zustandsautomaten, also: Wenn in Zustand A ein c gelesen wird, dann mache X und sei danach in Zustand C?

    Idiomatisch in C++: switch-Statement.
    Idiomatisch in ...: Coroutine.

    Kanonisch ... ? State-Pattern? Tabelle?

    Irgendwie passt "kanonisch" hier nicht. Wenn ich an kanonische Normalformen denke, so sind sie zwar einheitlich, aber sehr aufgeblaeht und restriktiv in den verwendeten Sprachmitteln (z.b. nur AND und OR), was eher nicht erstrebenswert ist. Boilerplatecode mag keiner lesen oder schreiben.



  • Warum werden in der Informatik / IT-Branche so oft bereits vorhandene Begriffe zweckentfremdet mit unklarer neuer Bedeutung verwendet. 😕
    Das fängt bei Design und Architektur bereits an! 🙂 Bei fremden Code wird einfach gejammert, weil man ihn erst verstehen muss! 😞



  • berniebutt schrieb:

    Warum werden in der Informatik / IT-Branche so oft bereits vorhandene Begriffe zweckentfremdet mit unklarer neuer Bedeutung verwendet.(

    In der Informatik macht man es aus dem selben Grund so, aus dem man es auch in den anderen technischen Fachrichtungen: weil es einfacher zu merken ist als wenn man komplett neue Begriffe erfinden würde.
    Und öfter macht man es, weil sich in der Informatik wahnsinnig viel tut, und so schnell so viele neue Dinge dazukommen für die man einen Namen braucht.

    ----

    Bis zu einem gewissen Punkte könnte man sich noch behelfen indem man immer beschreibt was man meint, und sich auf eine kanonische (*g*) Beschreibung einigt.
    Dummerweise würde man so vermutlich gleich mehrere Minuten brauchen nur um die kanonische Beschreibung für Begriff wie "Translation Lookaside Buffer" zu sagen.
    Ist nicht praktikabel.

    Also bleibt nur Fachbegriffe zu erfinden. Und da bastelt man halt üblicherweise was aus bestehenden Wörtern zusammen als neue zu erfinden, weil's wie gesagt einfacher ist.

    ----

    Für alle die sich daran stören gibt's aber eine ganz einfache Lösung: englische Fachbegriffe verwenden. Auf die Englischen Wörter aus denen die zusammengebaut sind hat ein deuschsprachig aufgewachsener Mensch noch keine so starke Prägung. Dadurch fallen die Nachteile grösstenteils weg die sich durch die Wiederverwendung von Begriffen aus dem normalen Sprachgebrauch ergeben.



  • Ich meckere viel lieber über alten code, den ich selbst geschrieben habe, weil ich damit zeigen kann, wieviel ich seit damals dazugelernt habe. Ich denke, dass ich die Geschäftsleitung damit noch wesentlich mehr beeindrucken kann als mit dem Schlechtmachen der Arbeit meiner (Ex-)Kollegen. 😉



  • Ich bin und war an 2 sehr langlebigen Projekten beteiligt (bin jeweils 10+ Jahre nach Projektbeginn zugestoßenen), ebenso wie ich kurzlebige kenne.

    Allgemein kann man langlebige Projekte wesentlich eher zu Problemen tendieren, als kurzlebige (Was nicht heißt das man nicht in beiden Fällen Fehler gemacht hat - Wäre auch verwunderlich, es gibt keine perfekten Programmierer, die alles exakt so vorausplanen können wie dann wirklich erforderlich ist).

    Meines Erachtens kann man Code durchaus eine grundlegende Qualität zusprechen, und dies auch durch Beobachtung von neuen Entwicklern herausfinden (ich habe in beiden Projekten in der Entwicklungszeit noch weitere neue Entwickler kennen gelernt, und an diesen etwa die gleichen Symptome bemerkt):

    - Projekt a: Einarbeitung nur sehr stockend, bis zum Schluss viele alte Codestellen schlicht nicht verständlich. Fehlerkorrekturen nahmen hier mindestens 75% der verfügbaren Zeit ein.
    - Projekt b: Bereits innerhalb kürzester Zeit waren alle Neueinsteiger fest im Projektleben, und nur bei wenig Codestellen gab es überhaupt Verständnisprobleme. Fehlerkorrekturen kommen hier zwar vor, liegen aber vielleicht bei 10% der Gesamtzeit.

    Altcode der nicht angefasst/angepasst werden muss ist selten wirklich schlecht, selbst wenn hier mehrere Codestile/Paradigmenwechsel aufeinander treffen (Wobei es auch wirklich "defekten" Code gibt). Aber Altcode der ständig erweitert wird kann entweder wartbar bleiben oder zu einem unwartbaren Moloch werden, abhängig davon wie im Projekt mit Änderungen vorgegangen wird:

    - Projekt a: Änderungen am Altcode waren weitgehend Tabu, Refactoring und Reengineering waren mehr oder weniger verboten. Code wurde immer nur an bestehenden drangepappt, Fehler meist nur durch Workarounds umgangen, wenn die Korrektur Designänderungen nach sich gezogen hätte. Zudem war der Chefentwickler (tut mir Leid das ich es so drastisch ausdrücke, der Eindruck war aber auch bei allen anderen Entwicklern die ich in der Projektzeit erlebt habe) kein guter Entwickler, sei es nun, das er mit dem Studium das Lernen beendet hatte, sei es nun, das auch so sehr viele gravierende Design- und Verständnisfehler in seinem Code waren.

    - Projekt b: Hier gibt es zwar auch ein paar schlechte Codehierarchien die zu etwas angewachsen sind, wofür sie nicht designt waren (und sich nun als zu unflexibel herausstellen), es gibt hier aber ein ganz massiven unterschied: Codepflege ist erlaubt/erwünscht und vor allem ist hier auch die Zeit dafür da. Der Code als ganzes ist recht gut verständlich, selbst wenn man einiges anders machen würde. Ich habe selten ein Projekt erlebt das im Verhältnis auf die Entwicklungszeit so sauber war - Auch wenn tatsächlich eine Neuentwicklung ansteht, es haben sich dafür aber auch einige Rahmenbedingungen massiv geändert, und es wird an einigen Stellen eine wesentlich höhere Flexibilität nötig.



  • Weil alter Code nunmal schlecht aussieht, sich die Techniken weiterentwickeln und man manchmal das Gefühl hat dass der Programmierer seinen Code nach dem Motto "Nach mit die Sinnflut" hingekotzt hat.

    Habe schon Dinge wie kryptische Funktionsnamen, schlechte Funktionsdefinitionen, eine Datei in der alle globalen Variablen definiert sind und Funktionen voller Seiteneffekte erlebt. Mangelnde Const Correctness (Was ist das?), fehlende Dokumentation, mangelnde Überprüfung von statischen Array's, sind da nur die kleineren Dinge.

    Zum Teil sind die Codes auch deswegen entstanden weil die Programmierer eine etwas andere Sichtweise hatte. Da programmierte man noch Bits und Byte lastiger und keiner kam auf die Idee den Code anderes zu benutzen wie ihn der Programmierer benutzte.



  • Bitte ein Bit schrieb:

    Mangelnde Const Correctness (Was ist das?)

    Ich bin zwar ein Freund von Const Correctness, aber dies ist von den aufgeführten Punkten noch das kleinste Übel. Fehlende oder zumindest spärliche Dokumentations wiederum ich doch eigentlich schon Standard... (Wenn die Kommunikation im Unternehmen stimmt, kann dies aber zumindest zu teilen wettgemacht werden - sofern der Entwickler noch existiert).

    Bitte ein Bit schrieb:

    Da programmierte man noch Bits und Byte lastiger und keiner kam auf die Idee den Code anderes zu benutzen wie ihn der Programmierer benutzte.

    In kleineren Firmen kann noch ein weiterer Grund hinzu kommen:
    Man hat den Code niemals für ein Anderes, oder für eine langfristiges Projekt geschrieben, oder gar gedacht das man immer Alleine arbeitet.

    Faktor 1 kommt unter anderem zum Tragen wenn Projekte nur billig abgehandelt wurden sind (Kunde war nicht bereit für mehr zu zahlen) und irgendein Manager dann meint das es doch da mal ein ähnliches Projekt gab, auf das man zurückgreifen kann...

    Und das aktuelle Projekt ist aus einer Studienarbeit entstanden, und wurde einige Zeit alleine entwickelt.



  • irgendein Manager dann meint das es doch da mal ein ähnliches Projekt gab, auf das man zurückgreifen kann...

    Software Engineering nach dem Motto: Copy Paste Clone Modfiy

    Die Sünden der Vergangenheit rächen sich bis in alle Ewigkeit...



  • Bitte ein Bit schrieb:

    irgendein Manager dann meint das es doch da mal ein ähnliches Projekt gab, auf das man zurückgreifen kann...

    Software Engineering nach dem Motto: Copy Paste Clone Modfiy

    Die Sünden der Vergangenheit rächen sich bis in alle Ewigkeit...

    In dem konkreten Fall sogar par excellence. Das Originalprojekt wurde mit Minimalbudgets (Kunde hat sogar die QS gestrichen, selbst wenn wir sie zumindest grundlegend durchgeführt haben), fest "verdrahteten" (mit vorgegebenen Versionsnummern) Abhängigkeiten zu Fremdsystemen etc. - Der ursprüngliche Kunde wollte ein sehr günstige Individualsoftware...



  • z.T. Copy-Paste...

    Ich hab' ein Projekt zu warten, da kommt an einigen Stellen sowas in dieser Art vor:

    if (FallunterscheidungDieIrgendwannMalDazugekommenIst)
        {
            if (AndereFallunterscheidungDieIrgendwannMalDazugekommenIst)
            {
                if (NochEineFallunterscheidungDieIrgendwannMalDazugekommenIst)
                {
                    // Code-Block der gerne mal 20+ Zeilen haben kann
                }
                else
                {
                    // Code-Block der gerne mal 20+ Zeilen haben kann
                }
            }
            else
            {
                if (NochEineFallunterscheidungDieIrgendwannMalDazugekommenIst)
                {
                    // Code-Block der gerne mal 20+ Zeilen haben kann
                }
                else
                {
                    // Code-Block der gerne mal 20+ Zeilen haben kann
                }
            }
        }
        else
        {
            if (AndereFallunterscheidungDieIrgendwannMalDazugekommenIst)
            {
                if (NochEineFallunterscheidungDieIrgendwannMalDazugekommenIst)
                {
                    // Code-Block der gerne mal 20+ Zeilen haben kann
                }
                else
                {
                    // Code-Block der gerne mal 20+ Zeilen haben kann
                }
            }
            else
            {
                if (NochEineFallunterscheidungDieIrgendwannMalDazugekommenIst)
                {
                    // Code-Block der gerne mal 20+ Zeilen haben kann
                }
                else
                {
                    // Code-Block der gerne mal 20+ Zeilen haben kann
                }
            }
        }
    

    Die Code-Blöcke in den innersten "ifs" unterscheiden sich dabei meist nur minimal, und in ALLEN Fällen hätte sich die Duplizierung vermeiden lassen.

    Manchmal ist das Muster nicht so klar wie in diesem stilisierten Beispiel, aber im Grund genommen läuft es darauf hinaus.

    Diese Duplizierungen sind dann an zumindest einer Stelle nochmals dupliziert, und zwar in 3 Funktionen die fast das selbe machen. (Wobei nicht alle Fallunterscheidungen überall benötigt werden. Dass der Code nicht 3*8 == 24 mal sondern vielleicht "nur" 15-20 mal dupliziert ist macht die Sache aber auch kaum besser.)

    Ich hatte noch keine Zeit das anzupassen, aber sobald ich die nächste grössere Änderung an dem Programmteil mache fliegt das raus und wird durch etwas ersetzt was zumindest halbwegs wartbar ist.

    Ist übrigens auch ein Projekt das nach dem Motto "immer nur dazustöpseln, bloss nie was ändern was nicht sein muss, und schon gar keinen alten Code löschen, lieber auskommentieren und vor sich hinrotten lassen" über mehrere Jahre erweitert/geändert wurde.

    Das krasse daran ist:
    * Das ist nicht erfunden.
    * Die Duplizierung könnte man relativ einfach vermeiden, und der de-duplizierte Code würde nichtmal irgendwelche wenig intuitiven Hilfskonstrukte enthalten, sondern viel klarar das abbilden was eigentlich gemacht wird.



  • @hustbaer: Das Gefährliche an solchen Konstrukten ist, dass bei einem Refactoring die Semantik unabsichtlich verändert werden kann. Besonders wenn sich Codeduplikationen minimal unterscheiden.

    Und viele Programmierer haben dann nicht den Mut, den bestehenden Code zu ändern, sondern schreiben neue Zeilen einfach dazu. Letzten Endes führt das zu solchen Auswüchsen...



  • @Lord Tiberius II
    Vollkommen richtig!

    Wirklich ärgerlich ist es aber (für mich persönlich zumindest), wenn man weiss dass dieser Code von einem einzigen Programmierer verbrochen wurde. Und wenn man schon alleine an einem (Teil eines) Projekt(s) arbeitet, dann sollte man doch wenigstens aufpassen dass man die Grenze nicht überschreitet ab wo es unwartbar wird. Und wenn diese erreicht ist einfach hart bleiben und dem Chef sagen "ne, das dauert jetzt N Tage, geht nicht schneller".

    Zumindest wenn man Chefs hat bei denen "machen wir jetzt schnell, später haben wir dann mehr Zeit, da können wir putzen" nicht funktioniert. Weil später 1000 andere Dinge noch viel dringender sind. Viel viel dringender als das Ultradringende das den ersten, zweiten ... und siebenundzwanzigsten Hack erfordert hat.

    D.h. es gab hier "nur" Zeitdruck, kein absolutes Verbot von Oben ein wenig zu refactoren. Ich hab' mich da früher auch zu sehr beeindrucken lassen und selbst einige z.T. sehr schlimme Dinge verbrochen. Aber ich hab' halt irgendwann dazugelernt.

    Ich würde mir sehr sehr wünschen in einem Team/Umfeld zu arbeiten wo solche Sachen kein Thema sind.

    ----

    Diese eine spezielle Sache ist aber gottseidank nicht so tragisch wie sie sein könnte. Blöd wäre wenn das irgendwelche komplizierte Business-Logik wäre für die es keine/nur unzureichende Test-Cases gibt, die zu 99% so stimmt wie sie implementiert ist, und das eine Prozent wo sie nicht stimmt ist gar nicht genau bekannt. Das wäre wirklich doof.

    In meinem Fall ist es aber bloss Code von dem ich genau weiss was er machen soll, dessen Resultat ziemlich einfach überprüfbar ist. Und es gibt im Prinzip auch nur ein "funktioniert" bzw. "funktioniert nicht", und kein exaktes Verhalten das es nachzubilden gibt.

    Ich hatte nur bisher noch keine Zeit es zu machen. Weil das halt trotzdem es relativ unkritisch ist auch ein paar Tage dauert es umzuschreiben (bzw. neu zu schreiben).



  • hustbaer schrieb:

    ...Blöd wäre wenn das irgendwelche komplizierte Business-Logik wäre für die es keine/nur unzureichende Test-Cases gibt,...

    Ist das nicht der Standard? ;p



  • Auch schlimm sind hartcodierte Sonderfälle. Wenn die Logik in seltenen Fällen leicht abgeändert werden muss. Dummerweise häufen sich die Sonderfälle dann irgendwann bis der einstige Normalfall zum Sonderfall wird. Spätestens dann sollte man ebenfalls darüber nachdenken, das anders zu regeln (was nicht selten einiges an refactoring erfordert)



  • hustbaer schrieb:

    Gerade schlechte Programmierer haben dann Schwierigkeiten sich im Code andere Leute zurechtzufinden. Und gerade schlechte Programmierer überschätzen sich am meisten. Also jammern sie, und meinen sie könnten das alles viel besser machen, wenn sie es nur neu schreiben dürften.

    Allerdings kenne ich wenige Branchen, in denen die Qualität der einzelnen Arbeitskräfte so stark variiert wie im IT-Bereich im Allgemeinen und in der Entwicklung im Besonderen. Hier hat der enorme Bedarf dazu geführt, dass das viele Geld eine Menge weniger qualifizierte IT-ler unterwegs sind.

    Auf der anderen Seite gibt auch nur wenige Bereiche, in denen die Arbeitsqualität für die Auftraggeberseite so wenig/spät zu beurteilen ist, wie im IT-Bereich. Dank der heute üblichen Tools sieht die Software von außen schon mit minimalem Aufwand perfekt aus. Designfehler, mangelnde Effizienz, reduzierte Entwicklungsfähigkeit kann man von außen schlecht beurteilen und nur schlecht maschinell messen. Außer in der hohen Quote der gescheiterter Projekte.

    War ganz erstaunt, dass diese grundlegende Problematik schon in der Literatur der Sechziger bis Achtziger diskutiert wurde. Frederick P. Brooks zum Beispiel erkannte die Herausforderung korrekt, dass es nicht darum geht, die perfekten Entwickler zu finden/auszubilden, sondern wie man mit Unmengen von weniger begabten Menschen ein lauffähiges Betriebssystem entwickelt.

    Ciao, Allesquatsch


Anmelden zum Antworten