Podcaster
Episoden
06.08.2021
3 Minuten
Folge 11 – Das CRUD-Pattern CRUD – Alptraum und Lebenselexier jedes
Entwicklers. CRUD steht für CREATE READ UPDATE DELETE und sind die
4 Daten-Operationen, die man einbauen muss, um eine sinnvolle
Oberfläche oder API zu designen. CREATE – irgendwie muss man den
Datensatz erstellen können. Ein Anlege-Formular muss die Felder des
Datensatzes leer oder mit Default-Werten gefüllt anbieten. Per
Knopfdruck wird der Datensatz erstellt. READ – Bei den
Leseoperationen gibt es generell 2 Arten: Die Liste bzw. Tabelle,
in der man ALLE Datensätze sieht: Tabellarisch, durchsuchbar,
filterbar; Und dann gibt es noch den Detail-View, also die
Detail-Ansicht. Während man in der Tabelle die Spalten weglässt,
die nicht unbedingt für eine Suche oder das Wiederfinden von
Datensätzen notwendig sind, sind im DetailView dann alle Daten
eingeblendet. Handelt es sich im relativ einfache Datensätze wie
z.B. eine einfache Relation mit 2 Spalten, kann man den DetailView
auch weglassen. UPDATE – Das Update-Formular ist wie das
Create-Formular aufgebaut: Die Spalten, die man noch bearbeiten
können soll, werden mit den bisherigen Daten des Datensatzes
gefüllt, man bearbeitet diese und drückt auf Speichern. Viele
Entwickler versuchen, Zeit zu sparen und lassen immer wieder
CRUD-Operationen weg. Meist leidet darunter die UPDATE-Funktion.
Auf diese kann man noch am ehesten verzichten: anstatt einen
Datensatz zu bearbeiten kann ihn ja der User löschen und neu
anlegen. DELETE – Beim Löschen gibt man meistens dem Nutzer noch
einmal die Möglichkeit, vor dem Löschen zustimmen zu müssen. All
diese 4 CRUD-Operationen für jeden Datensatz umzusetzen ist eine
WAHNSINNS Arbeit. Doch Entwickler, die auch nur eine davon
weglassen, produzieren damit schlechte Software. Als Entwickler
solltest du lieber schauen, dass du dir ein einheitliches System
überlegst, mit dem du für jeden beliebigen Datensatz deine
CRUD-Operationen AUTOMATISCH bekommst. Ein solches System ist die
FOP-Programmiersprache. Beim FOP entwickelt man ein Datenschema und
bekommt eine Oberfläche zum Manipulieren der Daten gratis dazu.
Wenn du wissen willst, wie man FOP benutzt, wie man damit
unheimlich schnell Web-Portale und komplexe Software-Projekte
erstellt, dann abonniere diesen Podcast.
Mehr
22.02.2021
4 Minuten
Bei der Softwareentwicklung gibt es ein magisches Dreieck: Der
Kunde will gleichzeitig Hohe Qualität, niedriges Budget, schnelle
Fertigstellung. Es gibt ein geflügeltes Wort: Hohe Qualität,
niedriges Budget, schnelle Fertigstellung - Das sind die 3
Eigenschaften, die du willst. Suche dir 2 davon aus. Bei
technologischen Schulden entschied man sich für niedriges Budget
und schnelle Fertigstellung unter Aufopferung der Qualität.
Faktoren, die führen zu technischer Schuld führen können, sind: •
Unwissenheit • Faulheit • Zeitdruck • Geldmangel • die bewusste
Entscheidung, unreife Prototypen zu produzieren, um sie zu testen
Technische Schulden drücken sich insbesondere durch schlecht
strukturierte IT-Lösungen aus. Daraus folgen: • Sicherheitslücken •
Nach Updates funktionieren einige Dinge nicht mehr • Neue
Funktionen hinzuzufügen wird sehr teuer/aufwendig Technische
Schulden muss man abbauen – aber nicht immer. Denn der Grund, warum
man Technische Schulden überhaupt macht ist, dass das Projekt
schneller voran geht. Oft weiß man nicht, ob der Kunde ein Feature
später behalten oder wieder wegwerfen will. Auch will man die Zeit
nicht direkt investiren, alles „ordentlich“ zu machen, da man noch
genügend andere Sachen zu tun hat. Technologische Schulden fordern
Zinsen, aber auch Zinseszinsen. Und genau um die Zinseszinsen soll
es gehen: Ist eine Software oder ein IT-Projekt schlecht
strukturiert, kann man den Fehler am Anfang noch einfach beheben.
Je mehr darauf aufbaut, desto schwieriger wird es aber, die Fehler
aus der Vergangenheit zu korrigieren. So entstehen zum Beispiel auf
den Provisorien weitere Übergangslösungen und Hacks, die die
Komplexität des IT-Projekts unheimlich in die Höhe treiben. Zu dem
ursprünglichen Ziel, Zeit zu sparen und schnell nutzbare Ergebnisse
haben, kommen nicht nur die Kosten des “Aufräumens” hinzu, sondern
es werden komplett neue Systeme um das schlecht Strukturierte
System herum gebaut, die im Falle einer Korrektur wieder obsolet
werden – sprich: Verlust durch Abschreibung. Für den Entwickler
können wir folgende Faustregel mitgeben: Bevor man ein System um
eine Funktion erweitert, wird das System geprüft, ob es für diese
neue Funktion geeignet ist oder umstrukturiert werden sollte. Das
ist zwar etwas mehr Arbeit, während der Kunde auf die schnelle
Umsetzung seines Features wartet. Es lohnt sich aber: Der
Implementierungsaufwand für die neue Funktion sinkt drastisch, wenn
das darunterliegende System besser geeignet ist. Veranschaulicht
heißt das: Bevor man neue technologische Schulden aufnimmt, muss
man die alten Kredite abbezahlen Damit man Herr über seine Schulden
bleibt, sollte man diese in einer Art „technischem Schuldenbuch“
dokumentieren. Dazu eignen sich prinzipiell zwei Techniken: In der
ersten Technik schreibst du alles, was du noch nicht implementieren
willst, als Kommentar in den Code: Ausgelassene
Sicherheitsprüfungen mit /* TODO: sanitizen */ - an eine Klasse
konkrete Infos: TODO: Diese Klasse mit Klasse Y zu gemeinsamer
Klasse Z zusammenführen. In der zweiten Technik nutzt du dein
Issue-Tracking-System, um die TODOs zu organisieren. Wenn du ganz
schlau bist, kombinierst du beide Techniken: Im Code machst du
einen Kommentar TODO: #1337: Refactorn und unter der 1337
hinterlegst du dann genaue Beschreibungen, was du dort genau
weggelassen hast. Wenn dich diese Sachen weitergebracht haben, dann
abonniere diesen Podcast.
Mehr
15.02.2021
3 Minuten
Quellcode kann unheimlich redundant sein. Wir haben bereits in
einer älteren Folge darüber gesprochen, dass man durch geschicktes
Refactoring Code-Duplikation entfernen kann. Quellcode ist
Information. Wenn ich in der Lage bin, ein- und dasselbe Programm
einmal mit 1000 Zeilen Code und einmal mit 300 Zeilen Code zu
implementieren, dann hat das Programm nur einen Informationsgehalt
von 300 Zeilen! Kurzer Code ist schön. Die restlichen 700 Zeilen
verkomplizieren das Programm nur. Dabei gehe ich von sauber
geschriebenem Code aus und zähle die Kommentare nicht als
Codezeilen mit. Es geht rein um die Anzahl an Anweisungen,
Ausdrücken, Schleifen und Funktionen im Code. In der Folge 4
„Kurzer Code ist schön“ habe ich bereits angedeutet, dass zum einen
weniger Code weniger Probleme bedeutet: Weniger Bugs, weniger Code
zu warten, weniger Code zu lesen. Außerdem habe ich eine Technik
vorgestellt, mit der man durch ein Zwischen-Interface aus m*n
Codezeilen m+n Codezeilen umschreiben kann. Diesmal geht es um eine
andere Technik: Projektübergreifendes Refactoring.
Projektübergreifendes Refactoring ist das mächtigste Werkzeug, wenn
man jedes einzelne Projekt mit minimalem Aufwand umsetzen will.
Mehr
10.02.2021
9 Minuten
Diese Folge in meinem Programmier-Podcast ist heute ein bisschen
anderer Natur. Ich will euch zeigen, wie einfach es ist, sein
eigenes Git-Hosting und Projekttool zu entwickeln. Git ist aus der
heutigen Programmierlandschaft nicht mehr wegzudenken. Früher hat
man ZIP-Dateien mit Quellcode per E-Mail versandt, wenn man im Team
arbeiten wollte. Dann gab es das erste Versionskontrollsystem: CVS.
Man konnte Ordner für seine Kollegen sperren. Damit waren schon mal
Konflikte unter Kontrolle, dass zwei Nutzer dieselbe Datei
bearbeitet haben. Bei der Freigabe der Datei wurde dann die neue
Version der Datei verteilt. Blöd nur, wenn der Kollege, der eine
Datei gesperrt hat, gerade im Urlaub war. Es gibt 1-2 Self-Hosting
Git-Tools, z.B. das auf Go basierende Gogs, welches wir verwendet
haben. Außerdem gibt es in der Cloud noch github.com von Microsoft.
Uns hat das Gogs irgendwann nicht mehr ausgereicht, Alternativen
waren zu klobig und mit Features überladen und in die Github-Cloud
wollten wir auch nicht mit unseren Firmendaten. Die Anforderungen
an ein neues Git-Tool waren: • Projektübergreifende Issues, die man
von egal-welchem Projekt lösen konnte • Suchfunktion für Issues •
Kunden-Zugriff mit sichtbaren und unsichtbaren Issues • Eine
intelligente Issue-Priorisierung – wir haben uns entschieden, die
Priorität in € zu messen • Issue-Abhängigkeiten und damit
verbundene Priority inheritence: Die Priorität einer Issue in €
wird einfach auf die abhängigen Flaschenhals-Issues aufaddiert Ein
eigenes Git-Tool ist im Prinzip nicht schwer zu bauen. Man benötigt
einen SSH-Server, auf den man pushen und von dem man pullen darf,
sowie ein Web-Frontend für das Projektmanagement und die Issues.
Mehr
01.02.2021
4 Minuten
Oft schaut man als Entwickler Code von früher an und fällt erst
einmal aus allen Wolken: Dort ein Bug, dort schlechte
Variablenbenennung, außerdem hat sich der Kunde beschwert, dass da
etwas nicht funktioniert. Außerdem ist die Software-Architektur des
Projekts nicht so ausgereift. Dann überlegt man – wenn schon, dann
richtig. Wäre es nicht einfach bessser, das Projekt noch mal neu zu
starten und mit einem klar strukturierten Architektur anzufangen?
Kurze Antwort: Nein! Lange Antwort: In jedem Projekt stecken, bis
es wirklich funktioniert, tausende kleine Anpassungen. Natürlich
gibt es eine optimale Systemarchitektur – quasi ein „Ideal“. Doch
dieses Ideal erreicht man nicht, indem man das Projekt von vorn
anfängt. Die Kosten dafür sind einfach zu hoch. Was ist also die
Alternative? Die beste Lösung ist, das Projekt Stück für Stück auf
die Zielarchitektur umzubauen. Dazu bedient man sich des
Werkzeugkastens des „Refactorings“. Denn Code hat immer 2
Dimensionen: Eine High-Level- und eine Low-Level-Dimension.
Arbeitet man auf der Low-Level-Dimension sauber, wird das Programm
nicht abstürzen und sich in jeder erdenklichen Situation richtig
verhalten. Außerdem stimmt dann auch die Performance. Auf der
High-Level-Ebene sind andere Dinge wichtig: • Ist die Software auf
mehreren Betriebssystemen lauffähig? • Lässt sich die Software an
neue Kundenbedürfnisse anpassen? • Lässt sich die Software auch für
andere und ähnliche Anwendungsfälle einsetzen? • Lässt sich die
Software gut von Menschen bedienen? UI-technisch • Lässt sich die
Software gut von Maschinen bedienen? Ich rede hier von
API-Anbindung und ähnlichem Einfache Bugs fixt man, indem man 1-2-3
Zeilen im Code abändert. High-Level-Änderungen benötigen oft
Code-Anpassungen quer über das gesamte Projekt: Umbenennungen, neue
Parameter in Interfaces, neue Aufteilung von Klassen…. Oberstes
Ziel eines Refactoring sollte immer sein, so viel wie möglich Code
zu entfernen, ohne die Funktion des Programms dabei einzuengen. Das
bedeutet in erster Linie: Code Duplication aufspüren und anhand der
gefundenen Duplikate verallgemeinern. Oft ergeben sich durch diese
Zusammenführung unterschiedlichster Code-Abschnitte zu
Hilfsfunktionen ganz neue Sichtweisen auf das eigene Werk:
Plötzlich muss man einen neuen Namen oder Begriff für eine Funktion
finden, die zum Beispiel Angebote und Rechnungen gemeinsam haben.
Was haben denn Angebote und Rechnungen gemeinsam? Sie besitzen
beide eine Nummer aus einem Nummernkreis, sowie eine Liste von
Positionen mit jeweils Bezeichnung, Menge und Preis. Doch die
Struktur allein gibt uns noch keine guten Ideen für eine Benennung
der Funktion. Wir haben die Funktion am Ende „Vertriebsvorgänge“
genannt. Dazu zählen Angebote, Rechnungen, Lieferscheine, aber auch
Einkäufe / Einkaufslisten. Allein die Benennung hat uns einen
unheimlichen Schub an Ideen gegeben, was Vertriebsvorgänge
eigentlich alles tun können. Einmal deduplizierter Code ist
awesome. Er lässt sich nicht nur an den 2 deduplizierten Stellen
verwenden, sondern man findet in der Regel noch zig weitere
Anwendungsfälle für allgemeinen Code. Noch ein Nachtrag: Ich habe
vorhin behauptet, High-Level-Code-Anpassungen erstrecken sich über
das komplette Projekt. Das mag stimmen für traditionelle
Programmiersprachen. Es gibt aber eine neuartige Programmiersprache
namens FOP, bei der ist das etwas anders – zumindest für bestimmte
Fälle. Bei der FOP-Programmiersprache kann man zum Beispiel in
einem einfachen 5-Zeiler dafür sorgen, dass jede Funktion, in der
PDFs generiert werden, eine Kopie des PDFs in einem
Dokumentenmanagement ablegen. Wie genau diese Sprache solche
abstrakten Anpassungen lokal halten kann, erfahrt ihr, wenn ihr den
Podcast abonniert.
Mehr
Über diesen Podcast
Podcast by Carl-Philip Hänsch
Kommentare (0)