Achtung: Mach nicht diesen Fehler (als Softwareentwicklerin oder -entwickler)! // deutsch

preview_player
Показать описание

Es gibt einen Fehler, den macht jede Entwicklerin und jeder Entwickler über kurz oder lang im Lauf der eigenen Karriere. Und dabei geht es nicht um ein vergessenes Semikolon oder den Zugriff auf eine Variable, die null ist, sondern um etwas weitaus essenzielleres und grundlegenderes. Doch was ist das für ein Fehler, warum wirst Du ihn machen, und wie kannst Du ihm vorbeugen?

00:00 – Einführung
01:00 – Ein einfaches Problem
02:37 – Sprache, Plattform & Co.
03:32 – Variante #1: Der naive Ansatz
04:09 – Variante #2: Die skalierbare Lösung
05:56 – Variante #3: Den Go-Compiler ausreizen
07:47 – Einfach vs komplex
08:19 – Bewertung der Varianten
10:18 – Der eine Fehler, den alle Entwicklerinnen und Entwickler machen
11:55 – Einfachheit als Ziel

────────────────────

Über the native web 🦄

Wir sind ein Beratungs-, Schulungs- und Entwicklungsunternehmen, das sich auf Web- und Cloud-Technologien spezialisiert hat. Wir streben nach intelligenten und eleganten Lösungen für komplexe Probleme, und wir glauben, dass Softwareentwicklung kein Selbstzweck ist. Stattdessen sollte Software tatsächliche Probleme der realen Welt lösen.

Wir glauben, dass native Web- und Cloud-Technologien das Fundament sind, auf dem die Zukunft aufbaut. Unsere Kernkompetenz ist der Entwurf und die Entwicklung verteilter Web- und Cloud-Anwendungen unter Verwendung dieser Technologien in interdisziplinären Teams. Wir entwickeln auch unser eigenes Open-Source-Framework namens wolkenkit. Und wir lieben es, unser Wissen in Schulungen und Workshops, auf Konferenzen und bei Usergroups zu teilen.

────────────────────

Weiterführende Links 🌍

Рекомендации по теме
Комментарии
Автор

Stimmt. Verständnis und Einfachheit des Codes sind wesentlich wichtiger, als etwas völlig unnötig zu verkomplizieren. Vor allem kann man dann im Team besser arbeiten und man kann ihn selber später auch besser verstehen. Am Ende muss man die Lösung komplett neu machen, weil man die genutzten "Funktionen" so selten benutzt.

Die Lösung ist wirklich: Einfach und elegant halten.

johannesfischer
Автор

Jedes deiner Videos ist wunderbar, das hier ganz besonders.

HendrikMans
Автор

Auch wenn ich die Software-Entwicklung mehr als Hobby ansehe als für den Beruf konnte ich da jetzt schon einige Jahre damit verbringen.
Kurz: Version 1 ist für mich die klarer verständlichere und einfachere Art. Das wäre auch die, wie ich das einem der mich fragt vermitteln würde.

Du willst halt wenn jemanden der ein Problem hat einem schnell helfen das es Klick macht. Wie man dann das Wissen umsetzt und aufbläht ist danach ein anderes Thema, aber den Grundgedanken wie es funktioniert muss erstmal da sein. Meiner Meinung nach.

lusaca
Автор

Ich selbst bin seit einiger Zeit an dem Punkt, wo ich mich frage, ob Softwareentwicklung wirklich so kompliziert sein muss. Und oft liegt es meiner Erfahrung nach genau an dem hier beschriebenen Fehler. Lösungen werden unnötig kompliziert aufgebaut. Das beginnt mitunter aber schon auf der Fachebene, wo Anforderungen formuliert werden, die über den eigentlich notwendigen Nutzen hinausgehen, setzt sich fort in overengineerten Architekturen und endet letztlich in der Anwendung zu komplizierter Programmierkonzepte.
Es macht wirklich Sinn, sich die Frage zu stellen, was denn wirklich zur Lösung der Aufgabe notwendig ist und dann zunächst die einfachste Variante zu implementieren. Komplizierter kann man es dann später immer noch machen, wenn die Situation es erfordert.

GeorgWittberger
Автор

Großartiges Zitat von Chuck Moore, Erfinder der Programmiersprache Forth: "I'm never afraid of simplicity. Show me a simpler way do the things I'm doing and I will go for it."

ReneHartmann
Автор

Hi Golo!

Ich stimme deiner Ausführung voll und ganz zu. Du hast es wirklich wieder mal auf den Punkt gebracht und ich fühle mich auch so ein wenig ertappt. Ja, es mag stimmen, dass alle erfahrerenen Entwickler zu komplexerem Code tendieren. Ich habe allerdings über die Jahre (ca. 15 am Stück) meine Erfahrungen sammeln können in dem Thema:

Zu Beginn tendierte ich auch immer mehr dazu, wahrscheinlich aufgrund von Wissbegierigkeit, immer ausgefeilteren und "besseren" Code zu schreiben. Ich wollte eben auch alle Sprachmerkmale verstehen und diese auch gleich anwenden. Mit der Zeit stellte es sich heraus, dass ich nach und nach, sobald Code adaptiert werden musste, Schwierigkeiten hatte, diesen einfach zu adaptieren auf neue Anforderungen. Und das obwohl ich mir damals, als ich den Code vor 5 Jahren geschrieben hatte, gemeint hätte, dieser sämtliche neue Anforderungen abdecken wird. Gut, es ging dann schon irgendwie, nur dieses "irgendwie" machte mich schon damals stutzig und es brauchte auch eine Weile, bis ich ans Ziel kam.

Also nach ca. 15-20 Jahren Coding-Erfahrung im Berufsumfeld mag ich meinen, dass ich bereits nach den ersten 5 Jahren mich dann eher auf die konservative Seite geschlagen habe und damals sogar das injection (ioc) pattern abgelehnt hatte. Ich hatte allerdings damals noch nicht die Erfahrung, dass IoC tatsächlich etwas gutes in sich habe könnte, weil ich Frameworks komplett ausgeblendet hab. Momentan mag ich Frameworks schon sehr; v.a. Spring Boot. M.E. ein sehr gelungenes Framework im Großen und Ganzen.

Wo ich heute noch hadere ist, wenn es darum geht, asynchronen Code in Java zu schreiben. Zumindest in der Hinsicht, dass man Patterns verwendet, die augenscheinlich im Code-Ablauf hintereinander stehen, dann durch irgend eine compiler-magic in irgendwas anderes transferiert werden und man auf diese Weise prozedurale Vorgehensweisen, die eigentlich nicht asynchron sein müssten aufgrund der Anforderung an einen bestimmten Code-Abschnitt, nicht mehr ordentlich lesen kann. Davon abgesehen, dass man solchen Code auch nicht mehr ordentlich debuggen kann m.E.

Aber dann gibt es eben auch die Kehrseite der Medaille. Ich habe schon oft erlebt, dass Leute z.B. mit Spring Boot hantieren und dann mehr und mehr static code schreiben, weil cyclic dependencies auftreten. Das hat m.E. auch kein zielführendes Ergebnis mehr. Normalerweise müsste man den Code neu strukturieren bzw. überdenken (stimmen die Abhängigkeiten? Sind die Abhäängigkeiten wirklich gut strukturiert?). ALternative ist, dass man lazy initialization verwendet; was m.E. immer noch besser ist, als statischen Code zu schreiben. Der Code wird immer mehr statisch und schlussendlich, wenn ich mich aus dem Fenster lehnen darf, muss man auch kein Framework mehr verwenden, wenn man nur mehr statische Methoden hat, aller Parameter weiter reicht usw. Dann genügen auch Maven- oder Gradle-dependencies und ein statisches Molloch.

zimsbert
Автор

Ein sehr wichtiger Punkt. Wir haben einen talentierten jungen Entwickler, der jedes neue sprachfeature nutzt… und uns ziemlich alt aussehen lässt :)

Er findet es dann einfacher und eleganter…
Elegant ist auch abhängig, ob man das Feature kennt….

Die Frage ist, ist es zu kompliziert oder sind wir zu dumm 😅😅😅

mikkid
Автор

Es hängt für mich nicht am konkreten Code, sondern am Team welches den Code warten und weiterentwickeln muss. Wer all die tollen, fancy technischen Lösungswege kennt, dennoch versucht, die Flughöhe des Teams zu berücksichtigen und für das Team verständlichen Code schreibt, ist mein eigentlicher Hero. Er kombiniert technisches Know-How mit sozialen Softskills. Ob eine Lösung gut oder schlecht ist, hängt für mich davon ab, ob das Team sie beherrschen kann. Nimm den Super-Hero, der für den Rest unverständliche Magie implementiert, raus und das Team beginnt zu fliegen.

dsb
Автор

Das gute alte Over-Engineering.
Ich habe auch so Kollegen, da weiß man genau, bis zu welcher Seite sie an dem Tag in ihrem Design Patterns-Buch gelesen hatten.
Schlimm finde ich auch die inflationäre Verwendung von Dependency Injection (also IoC-Frameworks, die ohne Reflection gar nicht funktionieren können) ohne echte Notwendigkeit.

cdoubleplusgood
Автор

Bravo, volle Zustimmung. Du hast das Strategy -Pattern erwähnt, und da kommen mir Erinnerungen an frühere Teamkollegen hoch. Sie pflegten es, möglichst jedes neue Problem oder Feature mit einem oder mehreren kombinierten GoF -Patterns zu lösen. Meine deutlich knapperen straight-forward Lösungen wurden daher nur allzu gerne rejected in den Reviews. Ich bin dann schnell wieder weg, weil mir das wirklich unsinnig schien.

maxjung
Автор

Ich fühle mich richtig ertappt von deiner Message :D
mir ist aufgefallen, dass ich diese Dinge getan habe, aber seitdem ich andere Verantwortlichkeiten habe finde ich nicht mehr die zeit dafür simplen code so zu verkomplizieren. Also könnte man im nachhinein sagen ich war mit simplem Problemen unterfordert und habe versucht mich anderen Konstrukten zu widmen, auch um neue Dinge zu lernen. Jetzt wo ich weniger Zeit habe greife ich einfach zu der simpelsten und schnellsten Lösung.

casdf
Автор

Das leidige Thema "OverEngineering"
Ich habe mich selbst auch schon öfters dabei ertappt, dass ich (in C#) versucht habe, jede Funktion in eigene Assemblies auszulagern und unzählige Interfaces definiert etc.
Um dann am Ende festzustellen, dass ich die verschiedenen Assemblies doch jeweils nur an einer Stelle verwende und diese doch immer gleichzeitig aktualisiere etc.

Und meiner Erfahrung nach, ist es (zumindest in C#) häufig einfacher, einzelne Komponenten nachträglich auszulösen und getrennt weiter zu entwickeln, als von Anfang an alles getrennt aufzubauen

MarkusH
Автор

Probleme nachvollziehbar zu lösen ist eine hervorragende Eigenschaft eines Entwickles.
Es geht so schnell dass bestimmte Feature einer Sprache nicht mehr unterstützt/entfernt werden oder der Entwickler es elegant in einer Zeile lösen wollte und so die Tore zu einem unwartbarem Softwarelabyrinth geöffnet wurden aus dem es kein Ausweg mehr gibt.

Jetzt braucht man natürlich den 10x Entwickler mit einem hohen Developer Velocity Index und eine Contribution Analysis um die Kreativität schon im Ansatz zu ersticken 😂

amadeus.mueller
Автор

Tolles Video und vor allem sehr anschaulich erklärt!

Die Situation habe ich auch schon sehr oft kennengelernt und finde es gar nicht so im einfach, damit immer gut umzugehen.
Man blickt auf Code ja meist aus der Sicht von sich selbst.

marinaegner
Автор

Mein Senf hierzu: Es gab mal ein Video von dir, in dem hast du gezeigt wie man mit Typescript Testdriven Development angeht. In diesem Video hast du einen sehr schönen, lesbaren Code geschrieben und ich dachte mit „Wow, toll!“ Dann hast du gesagt „jetzt kann man noch hier die Klammern wegkürzen, dadurch kann das Return entfallen, und überhaupt kann man noch hier und da und guck mal dahinten“… Und ich so: WTF!! DS war hinterher überhaupt nicht mehr einfach lesbar. Ich denke du meinst genau Situationen wie diese! 😉🥳

derschratling
Автор

Mir ist aufgefallen, dass der Punkt kotkommentierung, sorry codekommentierung, hier überhaupt nicht angesprochen wurde 😆. Best Practice über alles und es wird auch das Verständnis derjenigen, die noch auf B1 Niveau sind und dazu lernen wollen, anheben. dieses YouTube Skript wurde ja auch nicht auf a2 Sprachniveau aufgenommen. So sollte man auch in der Programmierung jedem dem seinem Kenntnisstand entsprechend zugestehen, seinen Code zu schreiben.

sola_scriptura_de
Автор

Ein schwieriges Thema, für welches wohl die Aussage "es kommt drauf an ..." wieder mal passend ist. Das Problem ist meistens, dass man zum Zeitpunkt der Erstellung nicht weiß ob an der Stelle eine spätere Erweiterbarkeit notwendig ist. Im Zweifelsfall sollte man es einfach halten, gut kommentieren und später kann man es immer noch komplexer gestalten, falls notwendig.
Schöne Woche!

yt
Автор

Bin bei diesem Thema ganz bei dir.
Ich arbeite häufig mit jüngeren Kollegen zusammen, die super komplexen Code schreiben, den ich mit meiner "Erfahrung" kaum noch verstehe.

Das sorgt dann bei mir für Frustration, wenn ich dann mit dem Code arbeiten muss. Die Einarbeitungszeit ist hoch, für die Features oder Bugs die es zu ergänzen gibt. Häufig sind die Lösungen dann "goldene Wasserhähne", die alle Eventualitäten abdecken. Ein Aspekt, der mir in dem Video gefehlt hat oder zumindest nicht so deutlich war.

Ja, wir wollen Code so schreiben, dass er flexibel und erweiterbar sein kann. Aber es muss es doch nicht immer sein.
Wenn es die Anforderung gibt, dass der Code nur unter 3 Betriebssystemen laufen können soll, dann reicht doch auch einfach ein switch.

maunzcache
Автор

Hallo Golo, danke für dieses Video.
Ja Du hast recht, es soll einfach sein, aber es soll auch erweiterbar sein. Und hier trennt sich die Spreu vom Weizen.
Die Aufgabe, bzw. das Problem beschreibt den Weg.
In Deinem Fall, mit den Betriebsystemen, gebe ich Dir vollkommen Recht.
Es ist überschaubar, es bleibt kurz und, Erweiterungen werden nicht so schnell kommen, denn die Handvoll von Betriebsysteme wird jetzt nicht monatlich oder täglich länger.

Anders sieht es mit cases aus, die eine hohe Fluktuation haben oder regelmäßig erweitert werden müssen.
Dann streckt Deine Switch Funktion schnell alle 4re von sich.
Bei Tausend Fällen, wird die Switch—Anweisung total unüberschaubar.
Gerade im Clean Code Bereich werden genau Deine folgenden Beispiele verwendet, weil sie sicherer sind und das Switch-Case für größere cases als böse gesehen wird.
Nicht ohne Grund, wohlgemerkt.
Mit dem Strategy Muster bist Du sogar Typesicher, vorausgesetzt Du benutzt OOP.

Muster haben ihre Berechtigung, und wer sie kennt, der wird sie lesen können.
Aber Zuviels Muster können es versauen.

Meine häufigsten Muster sind Strategy, Fassade, Factory.

Von Dispose, MVC, MVVM, aaa etc. mal abgesehen.

LG
Marcus

marcusreinicke
Автор

Lesbarkeit und Einfachheit sind das oberste Gebot beim Programmieren. Ich programmiere seit Anfang der 80er, also seit 40 Jahren.

ralfpeine