Ja, hallo liebe Hörerinnen und Hörer, willkommen beim Python-Podcast Episode 37.
Wir wollen heute ein bisschen über Refactoring reden und natürlich ist wieder Jochen dabei.
Hi Jochen.
Jo, hallo auch Dominik.
Und wir haben heute auch Ronny da.
Hi Ronny.
Hi.
Jo, hi Ronny.
Kennt ihr vielleicht auch noch.
Grüße.
Jo.
Ja, vielleicht erstmal ein bisschen News.
Ich weiß nicht, so viel Neues gab es noch nicht.
Ja, haben wir News?
Ich weiß nicht genau.
Also am 6.
Nikolas, das ist noch nicht so lange her, zwei Tage oder so, gab es Python 13.1.
Ach, okay.
Das ist an mir vorbeigekommen.
Das habe ich gerade nicht bekommen.
Ja, cool.
Habe ich bei mir jetzt überall eingebaut und
stable. Ich glaube, das war
vorgestern oder so,
oder gestern, ich bin mir gar nicht sicher.
Vielleicht gestern ist Django 4
released worden. Ja, stimmt, genau.
Ja, das ist auch eine ganz gute Neuigkeit.
Ja.
Es ist gar nicht so viel Neues dazu gekommen,
ehrlich gesagt. Aber es ist super viel weggefallen.
Also die Backwards-Incompatibility-List,
oh mein Gott,
die ist ungefähr fünfmal so lang wie die
neuen Features. Das ist echt krass.
Das ist super, ja.
ein paar Sachen rausgeflogen, die man nicht mehr braucht oder die gefährlich
sind oder so, schon gar nicht so schlecht.
Ja, ansonsten
weiß nicht genau, machen wir auch
News in anderen, für andere Sprachen?
Ja, ich glaube hier
PHP 8.1 ist irgendwie released
und da gibt es ein neues interessantes Feature
mit dabei und zwar
async await
so wie in Python halt auch
nur anders, also
also die Keywords
aber es
ist ein bisschen anders, man kann das halt
man kann halt Async-Funktionen auch so callen
ohne Await, was ganz
interessant ist. In JavaScript übrigens auch so.
Man muss
halt nur, wenn man Await sagen will
innerhalb von einer Funktion, irgendwie die Async
definiert haben, aber man kann die auch
einfach so aufrufen und
ja, dann passiert irgendwie magisch das Richtige oder
was Falsches oder was.
Aber man hat halt daher, also was
in Python tatsächlich ein bisschen nervig ist, ist man halt
dieses Farbigkeitsproblem der Funktionen hat,
dass man halt, wenn man irgendwo
Async was machen möchte, dann muss
alles Async sein.
Man kann natürlich auch hingehen und sagen,
okay, async.io.run
oder so, aber das ist natürlich...
Man muss dann erstmal den Event-Loop immer rausführen
oder wenn man im Jupyter gerade ist, dann ist das auch immer
ein bisschen doof und so, ja.
Ja, also in Python ist es expliziter
als in JavaScript und in PHP,
aber es ist halt auch so ein bisschen
unhandlicher zu benutzen vielleicht, aber
naja, gut. Ja, aber das ist vielleicht
auch noch erwähnenswert, weil damit wird in PHP
auch dann irgendwann das möglich, was ja jetzt in Python
jetzt, das kommt ja jetzt in Python, ist das
jetzt in den ganzen Frameworks halt irgendwie so
oder zumindest Django,
ich kann nicht so genau, FastAPI halt auch, aber das
war ja schon immer so angekommen, dass man halt
irgendwie Async-Kram da machen kann
und dann eben, ja, kann man halt solche Sachen machen
wie auch Filesurfing vom Applikationsserver aus
oder halt auch Websockets, relativ
einfach und so und das geht dann halt, weil ich weiß
gar nicht, wie das in PHP ist, da normalerweise eben
Sachen, PHP, Filesurfen,
das geht halt einfach nicht so richtig gut, weil
üblicherweise hat man nach irgendwie
einer Minute oder so werden die
Prozesse gekillt, weil
bei den meisten Hosern.
Da brauchst du mich jetzt gar nicht fragen, ich kriege nullkummer gar nicht aus,
wenn ich es ja sprache.
Naja, aber genau, da geht es halt auf jeden Fall auch voran.
Also sowieso per letzten Version
viel dazu gekommen und ja.
Ich kenne mich noch vom Gegenschubsen,
um umzutreten.
Tja, kann man natürlich auch machen.
Ja, haben wir noch andere News?
Haben wir noch was?
Was war denn in Django 4
drin alles Schönes?
Wisst ihr das noch?
Ja, neuer, also Django Redis
ist irgendwie, also Redis-Kind
wird da reingekommen. Automatisch, das gab ja immer sonst
ein Redis-Package und jetzt kam es direkt als
Default-Sets oder so, ne? Ja, es ist jetzt
halt drin, weil es gab irgendwie eine Umfrage,
was verwendet ihr denn so für Caching und
Alle nehmen Redis. Genau,
Memcachedie war eingebaut,
aber alle nehmen Redis, daher
macht es irgendwie nicht so richtig viel Sinn,
das nicht eingebaut zu haben und ja,
deswegen ist das jetzt halt drin.
Ja, ansonsten, naja,
war's nicht. Die anderen Sachen waren...
Halt, die Set ist rausgeflogen, glaube ich.
Genau.
Aber ich glaube, das war echt mehr ein Aufräumen-Release.
Gefühlt.
Was ja auch eine gute Sache ist
und was auch sehr gut zu unserer Refactoring-Session passt.
Ja, absolut.
Genau, das ist nämlich das Thema, glaube ich.
Genau, das Thema.
Ja, was ist denn das überhaupt, Refactoring?
Was sagt ihr denn, was das ist?
Also ich sage mal so, ich baute oft meinen Code um,
aber ist das schon Refactoring?
Also immer dann, wenn man halt ein bisschen später wieder draufguckt.
merkt man halt so, oh, wie war ich doof oder
oh, ist das aber hässlich oder schlecht, was ich
vorgemacht habe. Mach ich das doch mal nochmal oder
pass ein bisschen an oder mach es ganz von
neu oder was heißt Refactoring
für euch?
Nimmt man sich da extra Zeit für? Gehört das in
einen Sprint oder so?
Ich würde jetzt mal sagen,
meiner Verständnis nach gehört das
halt schon dazu,
wenn man sich
der agilen Softwareentwicklung
bedient als
Prozessmethode,
was auch immer, wie man das nennen möchte, dann würde
ich sagen, ich sage mal so Definitions of Done,
zum Beispiel bei Scrum, sagt,
wann ist was fertig und dann würde
aus meiner Sicht halt dazugehören,
normalerweise, dass man sagt, man hat das auch irgendwie mal
refactured oder so. Wie viel
Prozent der Zeit würde in sowas wie? Och, keine Ahnung,
das kommt drauf an, also. So ein Tag?
Je nachdem, was man macht, nee, das kommt
halt, also, und manchmal muss man es vielleicht
auf das komplette System refacturen, weil.
Wer refactort das denn, man selber, ein anderes Team,
das eigene Team mit vier, fünf, sechs Augen
im Prinzip? Nee, immer der, der fragt.
Okay, also bei uns
bin ich, also ich bin, weil ich mag
das irgendwie, Code umzubauen, ich weiß auch nicht
das ist so ein bisschen blödes Hobby, also es gibt
ja Zen of Python, das ist ja eigentlich
eher für andere Dinge da, da
wollten wir auch nochmal eine Folge drüber machen, aber der erste
Satz ist natürlich, beautiful is better than
ugly
und ich mag das irgendwie, wenn es hübsch ist
aber ist das ein guter Grund
zum Refactoren, dass es dann nachhübscher aussieht
es tut halt dasselbe
ist das wartbarer?
Aus meiner Sicht eigentlich schon,
aber da ist natürlich irgendwie
quasi, ja, aber ich meine
Man kann unendlich viel Zeit damit zu verbringen,
immer wieder dran rum zu feilen und zu gucken, dass
immer alles ein bisschen hübscher ist. Das macht halt kein
einziges Feature mehr. Aber das ist auch vielleicht so ein bisschen,
das hat man schon ein paar Mal erwähnt, so dieses
warum Programmierer irgendwie
Programmierer sein irgendwie nicht so
Business, dass sich das wie. Wie ist nochmal
dieser Talk, da hatten wir schon mal drüber gesprochen.
Weiß ich gar nicht, welchen meinst du?
Ja, ja, du kennst den auch noch, den hast du auch gesehen.
der war auf der DjangoCon irgendwie ganz
entspannt. Ach, der, der erste,
der erste Talk auf der DjangoCon
EU, ja,
weil man mag halt programmieren
und deswegen macht man das halt
und ob es irgendwie am Schluss
dabei was rauskommt oder nicht, ist eigentlich dann auch
so ein bisschen egal, genau. Ich glaube, ganz
wichtig ist halt, wie in allen Bereichen
überall ist halt Pareto-Prinzip, also
dass man einfach schauen muss, dass man
also 80% der Sachen kriegst du halt
einfach in 20% der Zeit refactored und die Details,
die kosten dann richtig viel
und da muss man abwägen.
Die ganz wichtigen Details, darf man das weglassen? Ich weiß nicht.
Es kommt immer ganz drauf an, würde ich
sagen. Also ich meine, wenn man jetzt irgendwie an einer
Software bastelt und da geht es gerade
irgendwie um die, weiß ich nicht, Zahlungsschnittstelle
oder Auftragsabwicklung, dann
sollte man schon schauen, dass das vernünftig funktioniert
und dass man da vielleicht auch eher einen Schritt
weiter denkt, als einen Schritt zu kurz
denkt. Aber es gibt doch in jedem System
Bereiche, weiß ich nicht, irgendeine
eine Administrationsseite, die zweimal im Jahr aufgerufen
wird oder so und wenn die jetzt nicht ganz perfekt ist,
jo, ich meine.
Du sagst ja, der Business-Use-Case,
das ist eigentlich, glaube ich, eine sehr gesunde Einstellung,
wenn man sagt, es geht darum, Business-Value,
also zumindest aus der Business-Sicht
ist es eine sehr gesunde Einstellung.
Aber ich würde nicht nur sagen das,
also zum Beispiel, ich habe jetzt in einem
Projekt, habe ich jetzt,
ich habe ja vor
einiger Zeit mir mal so ganz tolle Class-Based
E-Mails für Django ausgedacht und
habe jetzt in einem Projekt mal wirklich, weil
ich jetzt Internationalisierung eingebaut habe, habe ich jetzt
dann direkt alle E-Mails, weil ich
da eh dran musste, weil ich die Templates halt anpassen musste
und gucken musste, was halt die Sprache reingegeben wird, etc., etc.,
habe ich halt dann direkt gesagt,
okay, ich refactor jetzt direkt alle E-Mails zu Classbase,
was ist natürlich viel,
also das war definitiv in den 20%,
ja, und nicht in den 80%,
aber trotzdem weiß ich jetzt halt, dass wenn ich irgendwas
mit den E-Mails machen muss und vielleicht mal auch
generell was anpassen, zum Beispiel nochmal irgendwie das Layout
überarbeiten, was eh für irgendwann ansteht bei dem Projekt und so was,
habe ich halt danach einfach weniger Arbeit
und das bohrt sich halt an, wenn ich das Ding ja eh gar
auseinandernehme, dann mache ich das halt einfach noch mit.
Gut, aber das ist jetzt auch wieder aus dem Effizienzgedanken heraus.
Das heißt, du machst Refactoring deswegen, weil du später
Arbeitszeit, Wartungszeit
oder neue Feature-
Entwicklungszeit sparst.
Okay, das wäre auch so ein Effizienzgedanken.
Also quasi extrem wichtig, dass man das dann tut.
Und es schont dann auch meine Nerven,
wenn ich das dann nächstes Mal entspannter
machen kann. Ja, das finde ich auch. Also ich finde so
Refactoren aufgrund von, wir brauchen das vielleicht
nochmal und wie das da so steht,
das versteht ja keiner. Das ist ein
Eine Spaghetti-Band irgendwie hat irgendwas gebaut, weil er noch gar nicht wusste, wie das ging, hat das dann alles hingeschrieben.
Das ging dann irgendwie, aber so richtig nutzbar und schön ist das alles nicht.
Das ist irgendwie so, wie man es so kennt, so zusammengezimmert.
Ich finde auch ein ganz wichtiger Punkt ist, dass halt die meiste Software, die funktioniert, wird ja konstant weiterentwickelt.
Das ist ja einfach so.
Da frage ich mich auch ehrlich gesagt immer, warum, aber okay.
Und immer wenn neue Anforderungen dazu kommen, dann hat man die ja logischerweise vorher nicht bedacht, weil man ja nicht wusste, dass die kommt in den meisten Fällen oder in vielen Fällen.
Und das heißt, man fängt dann an in etwas, das nicht dafür gedacht ist, mehr Sachen reinzubauen.
Und das ist immer der Punkt, wo, glaube ich, intrinsisch einfach schon der Bedarf von einem gewissen Refactoring besteht.
Vielleicht nicht bei der ersten oder zweiten Änderung, aber irgendwann gibt die Struktur das einfach nicht mehr her.
Das ist halt genau die Frage. Wird was moderner? Muss man das dann, diesen modernen Stil, dann auch refactoren?
Das ist aber eine Stilfrage. Das heißt, ich habe eine schönere Skulptur, die Skulptur hat eine andere Mode als vorher.
Und deswegen mache ich es jetzt auf die gleiche Art ein bisschen neuer, ein bisschen anders.
Das gibt ja jede Menge Dinge, die man neu machen kann.
Ein schönes Beispiel finde ich Google.
Google hat unheimlich viel Energie reingesteckt
in das Gmail-Programm oder so.
Und eigentlich würde ich fast setzen,
das ist so quasi feature-complete zu dem, was man sich so wünscht.
Man kann alles damit machen, was man mit zum E-Mail-Client
eigentlich so machen will. Und die haben auch schon
so viel Zeit draufgeschmissen, dass so viel Neues
nicht kommt. Was ich jetzt immer sehe, da kommen irgendwelche
Änderungen am Style, an der Grafik, die
irgendwas eigentlich einfach nur anders machen.
Die mich dann zum Beispiel eher nerven, weil ich brauche
die einfach nicht. Ich will es so haben wie früher oder so, weil ich
veränderungsresistent bin oder so.
Und das ist aber dann
mit Refactoring verbunden? Warum macht man das?
Vielleicht, weil die Abteilung dann denkt so, okay, wir haben jetzt noch
diesen Sprint, wir wollen nicht aufgelöst werden,
wir wollen irgendwas machen und dann refactoren die da irgendwie rum.
Ist halt eigentlich schon fertig, die Software.
Und ja.
Naja, du hast halt dann normalerweise irgendwelche Metriken,
die halt an irgendeiner Stelle nicht so gut aussehen
und dann machst du halt was, um das zu verbessern.
Und manchmal wird das dann besser und manchmal wird das dann schlechter.
Und dann nur schlechter
für manche Leute und dann hast du halt
vielleicht einfach Pech.
Ja, genau.
Naja, ist halt die Frage. Also ich meine, ja, man könnte auch sagen,
Software ist irgendwann fertig.
Also irgendwann ist halt der Wert,
die neue Features bringen halt unter den Kosten,
wenn du das halt priorisiert hast,
nach irgendwie, was es reinkommt,
irgendwie minus Kosten es zu entwickeln.
Irgendwann wird das halt negativ.
Und aus einer Business-Sicht
müsstest du dann einfach aufhören zu entwickeln.
Ja.
Aber ja, ja, was stimmt?
Mit diesem Schritt tun sich viele schwer.
Ja, genau.
Und dann wird er sagen, okay, gehen wir jetzt fertig,
wir machen jetzt was anderes.
Würde ich auch sagen,
das wäre eigentlich, irgendwann ist es halt durch.
Und dann, na klar,
kann man irgendwann in zehn Jahren
nochmal einen Designer draufsetzen und sagen,
hey, wir machen das ein bisschen moderner, aber dann
muss die API vielleicht im Hintergrund, bleibt halt gleich.
Und was ich aber als Entwickler jetzt auch
sehr super finde, ist tatsächlich
Code schöner machen, weil man lernt immer was.
Also ich kann ja eigentlich nicht so viel mit den Sachen,
die ich neu mache, die kann ich vorher eigentlich
meistens nicht. Also sonst sind die immer relativ schnell fertig
und dann, aber wenn die neu sind, dann
baue ich irgendwas neu, dann muss ich mir ein Konzept überlegen,
ich weiß gar nicht, wo ich hin will und am Ende
sehe ich halt immer, oh, auf dem Weg dahin
bist du irgendwelche Sackkassen gelaufen,
irgendwelche Abkürzungen gegangen, die du eigentlich gar nicht gehen solltest
und hast voll irgendwas vergessen und das
muss man dann nach und nach irgendwie einbauen. Aber das
sorgfältig zu machen, das dauert halt viel mehr Zeit.
Den ganzen Code kann man fast wieder neu schreiben und dann hat man
am Ende was viel Schöneres da stehen.
Und ich weiß nicht, ist das Refactoring?
Und in einem halben Jahr später
fasse ich es wieder an und es ist wieder irgendwie so.
Ich denke, ah, das hättest du irgendwie schöner machen können.
Also ich habe,
ich kann das ja gleich mal direkt schon mal
spoilern. Ich habe so ein Buch gelesen,
das nennt sich
A Philosophy of Software Design von
John Osterhut oder so.
Keine Ahnung, ob ich den jetzt richtig ausgesprochen habe.
Das wurde mir empfohlen
in der Hacker-News-Diskussion
und deswegen werde ich jetzt ganz viel daraus
zitieren oder beziehungsweise Dinge
sagen, die da drinstehen, weil ich davon jetzt noch
eine Menge weiß und dann demnächst habe ich das wieder alles vergessen.
Vielleicht habe ich jetzt schon eine ganze Menge vergessen.
Aber
da ist ein schöner Satz. Am Anfang steht
da sowas wie, ja, also Software
schreiben ist ja eigentlich toll, weil es ist halt so eine der
puresten, eine der
reinsten kreativen Tätigkeiten,
weil man halt nicht so...
schaffen. Genau, weil man hat kaum
Begrenzungen durch irgendwelche Dinge.
Also alles, was man sich vorstellen kann, kann man
im Grunde machen. Deswegen ist es halt sehr rein.
Man ist nicht
abhängig von irgendwelchen Dingen.
Und
da ist was dran. Ich weiß jetzt nicht, ob die meisten
Leute das so sehen würden, aber das ist halt
jetzt auch relativ weit auf der
Entwicklerseite schon. Auf der Seite
das ist halt
ein Wert, wenn das schön ist.
Sozusagen. Wenn es schön
ist und rein ist und keine Ahnung, dann ist
Ist das irgendwie eine wertvolle Geschichte?
Und die andere Seite wäre halt, ist doch egal,
Hauptsache es tut. Also Hauptsache die
Features sind entwickelt und der Kunde ist glücklich
und ich habe möglichst wenig Zeit dran im Rechner
gesessen an der blöden Kiste, weil ich eine andere Sache machen kann.
Der Product Owner hat es abgenommen
und nach mir diesen Flut
irgendwie so ein bisschen, also
eher so ein pragmatischer Ansatz.
Ich glaube, beide haben so eine gewisse
Berechtigung.
Ja, total. Also gerade wenn ich jetzt
meinen Nutzen maximiere, dann will ich
möglichst wenig Zeit am Rechner verbringen, weil ich ja
damit mein Geld verdienen? Also, tu mir so, ich werde
per Auftrag bezahlt oder sowas, ja? Dann würde ich
möglichst wenig Zeit daran sitzen, weil ich möchte
ja irgendwas andere Sachen machen. Und was dann
unten drunter, wie das aussieht, ob es hübsch oder hässlich ist,
ist einem dann völlig egal. Hauptsächlich sind sie schnell damit
fertig und können das abhaken,
den Auftrag erfüllt. Das sieht ja quasi
der Manager eh nicht, weil der guckt ja eh nicht unter
die Haube. Der guckt ja nur, was am Ende dabei rausfällt.
Du zahlst es halt beim nächsten,
bei der nächsten Aufgabe. Genau, aber
das passiert mir egal. Und ob ich dann selber dann was Neues
dranflatschen muss, kann ja sein. Also, man
merkt es tatsächlich, aber erst, wenn man so Speed aufnimmt.
Das heißt, wenn man das ordentlich macht, dann kann man diese Erweiterung, die Skalierung immer schneller machen und das Deliveren von neuen Sachen, wenn man es ordentlich gemacht hat, ist dann einfacher.
Oder man kann halt Copy-Pasten aus dem anderen Projekt, wenn man es ordentlich gemacht hat und kann es ganz einfach auf die neuen Sachen generalisieren.
Das sind halt aber so Sachen, die nicht ziehen, wenn man halt immer was anderes machen muss.
Ja, sagen wir mal so, also der, wenn man jetzt rein aus der Business und auch aus der, sagen wir mal so, agilen Methodologie-Sicht da drauf guckt, dann ist der, es muss halt irgendwie funktionieren und ob das Feature fertig ist oder nicht, ist halt das, was man von außen sieht und das ist halt das Relevante.
Das ist der deutlich dominantere, der deutlich dominantere Punkt, was halt dazu führt, dass der halt auch oft sehr stark betont wird in so, ja, kommerziellen Entwicklungen.
Ja, ja, also der Manager, der interessiert sich nur für das KPI-Feature, fertig oder nicht, User-Story, das ist halt sehr atomar gesehen, also wenn man jetzt sagt, im Endeffekt, jedes Feature ist, also wenn man sich das wie so, weiß ich nicht, eine Menge von Commits im Branch oder sowas vorstellt, jedes Feature ist ja irgendwie ein Teil auf dieser Strecke zum Produkt, das irgendwann fertig oder irgendwann an einem Release-Punkt ist und wenn man das halt sehr atomar sieht, dann stimmt das natürlich, aber wenn man das halt über das große Ganze sieht, dann insbesondere bei langlaufenden Projekten, die halt wirklich konstant weiterentwickelt werden
Und wo vielleicht dann auch irgendwie ein Geschäftsprozess oder irgendwas so wirklich dann Firmengeld drüber läuft, glaube ich, ist das halt viel zu kurz gedacht. Also ich kann da, ich habe letztens mit ein paar Entwicklern gesprochen und die waren in ihrem Projekt halt so ein bisschen, nicht wirklich schlimmer, es ging so ein bisschen, fing an Richtung Zombiescrum zu werden. Es war eine relativ hohe Bugquote, das Team ist sehr viel Sachen hinterhergelaufen generell.
Backquote, ganz kurz, ist Anzahl an Bugs pro 100-Seilen-Code?
Backquote ist quasi die Anzahl der Bug-Tickets an allen Tickets im Sprint.
Ah, okay.
Oder Bug-Story-Points auf die insgesamt Sprint-Story-Points gezogen, berechnet.
Und das Team war halt latent frustriert.
Der Product Owner hat so ein bisschen die Fähigkeit des Teams irgendwie angezweifelt,
weil irgendwie da waren die Bugs und Sachen, die abgesprochen waren,
haben dann plötzlich nicht mehr funktioniert.
Das war halt insgesamt so eine latente Unmut auf allen Seiten. Es lief halt einfach nicht wirklich rund. Und dann haben die halt angefangen, halt so ein paar größere Sachen einfach mal anzugehen, weil dann war halt gerade so der eine große Release durch.
Okay, wir machen irgendwie Coverage rein, also wir zwingen Coverage in der Pipeline, also sprich, neuer Code muss getestet sein, sonst kann ich nicht deployen, kann ich nicht, well, Commitment schon, aber nicht deployen, dann einfach mal geschaut, dass man einfach so Streamlining, wie kriegen wir alle möglichen Variablen beim Prot-Deployment, das immer wieder mal auf die Nase fällt, wie kriegen wir das raus und immer mehr solche Sachen halt, haben die halt dann angegangen und damit hat sich dann, also nicht nur, dass halt dann plötzlich die Backquote enorm gefallen ist,
Also man glaubt nicht, was so ein simples Maß wie ich erzwinge Courage in der Pipeline, das ist so trivial, aber es hat total geholfen und auch die anderen Sachen und auf einmal hat sich dann, haben sie mir erzählt, einen ganz neuen Drive entwickelt, das ist echt faszinierend zu sehen gewesen und ja, da hätten die selber nicht drüber nachgedacht, dass das wirklich so einen großen Effekt haben kann, aber auf einmal ist auch so diese ganze Lethargie raus, wo man plötzlich mit hey cool, da geht was weiter, es klappt wieder, man hat plötzlich wieder auch Energie oder
Musse, irgendwie Sachen anzupassen, zu refactoren,
weil man halt eh das Gefühl hat, okay, es geht jetzt
wieder nach oben. Wir versuchen nicht irgendwie dieses Haus
immer so lange zusammenzuzimmern, dass es bloß
nicht auseinanderfällt, sondern man macht halt wieder
das Kreative, das Schöne halt.
Ich finde das so ein bisschen schwierig,
weil du hast auch was sehr Interessantes
gesagt. Also, weil der,
wenn es halt nur um diese User-Stories geht, ne, und
dann möchtest du da irgendwas
Schönes entwickeln,
das funktioniert dann irgendwie, und dann hast du langfristig
Ziele, die du erreichen kannst,
wenn du am Anfang von Anfang an auf gute Qualität
achtest oder halt viele Tests schreibst oder ein bisschen
TDD machst, also je nachdem das, was so dein
Overall Quality so ein bisschen, also wenn man ein bisschen mehr nachdenkt
vielleicht am Anfang und ein bisschen mehr
Know-how sich von Anfang an zum Holt, ist das glaube ich auch
was, was dich langfristig austeilt, ja,
weil man sich irgendwie alles von vorne neu machen muss.
Aus Business-Sicht
ist das aber so ein bisschen komisch, weil die, es ist eher so,
die meckern immer die ganze Zeit rum, so, ah, warum läuft
das denn noch nicht und warum sind da noch so viele Bugs und das verstehe ich alles nicht
und es muss alles fertig sein und so,
dann aber später sind die dann gewohnt, dass sie
genauso viel Zeit und Geld aufwenden müssen für Neuentwicklung
und du denkst so, ja, aber eigentlich ist das ja in zwei Tagen
fertig, weil wir haben ja ordentlich
am Anfang den Faktor und schön gemacht, das heißt, wenn man es richtig
macht, könnte man die neuen Features alle direkt
rausknallen, weil die super schnell gehen dann,
aber das versteht dann keiner und das kann man auch nicht
kommunizieren und ich sag mal, ist auch eher
gefährlich, das zu kommen, weil dann so eine
Erwartungshaltung entsteht, dass das halt immer
so wäre und dass das auch
nicht irgendwie clever dann vielleicht, ne, so
für so ein ganzes Team. Ich glaube,
Und da ist es halt super essentiell, dass man halt einfach eine gute Vertrauensbasis mit dem Product Owner hat.
Tja.
Genau, oder überhaupt diese Kommunikation zwischen irgendwie eben, ob das jetzt Product Owner ist oder, oft ist es ja so, der Product Owner ist ja noch so irgendwie quasi mehr oder weniger Teil des Teams.
Ja, wäre gut.
Genau, Product Owner und, also sagen wir mal Team irgendwie und dem Product Owner mit einem bezogen und halt irgendwie im weitesten Sinne das Management oder so.
Wenn es da kein Vertrauen gibt, ist es schlecht.
Ja, genau. Und auch ganz wichtig ist eigentlich, dass die Entwickler mit dem Kunden irgendwie eigentlich so viel zu tun haben oder mit dem Gedanken der User-Stories, dass sie halt da selber so committed drin sind auch.
Weil wenn halt die immer nur irgendwie ihre Tickets wegschubsen, dann ist das dann irgendwann wurscht. Das ist halt genau so eine Kommunikationssache.
Was der eigentliche Clou wäre, gutes Refactoring zu machen, von Anfang an das richtig zu tun, ist halt ein gutes Teamgespräch immer am Laufen zu halten, auch mit dem PO.
Und zwar nicht nur über Tickets und Leistungen und KPIs, sondern halt auch …
Aber tatsächlich, also ich meine, das ist halt auch das, also zu dem ganzen Agile-Kram gibt es halt auch einen kleinen Absatz in dem Buch, wo da halt so gesagt wird, ja, okay, Agile, voll gut, iterativ super, irgendwie, dass die Fachkompetenz nicht an den Reichen gekommen ist, also es gibt viele gute Sachen dabei, aber irgendwie, was nicht so toll ist, ist, dass diese ganzen Agile-Geschichten einen großen Wert auf diesen Was-bringt-es-fürs-Business-Punkt legen, was ja auch nicht unbedingt falsch ist,
aber sozusagen sie tendieren dazu, das deutlich überzubetonen, weil es gibt halt auch diesen anderen Punkt, ist das denn jetzt gut designt zum Beispiel, ist das denn schön, ist das denn mit der geringstmöglichen Komplexität irgendwie gebaut worden und da gibt es jedenfalls auch meiner Ansicht nach nichts in dem, zum Beispiel bei Scrum, was eine Rolle, die dafür zuständig wäre, das durchzusetzen.
Simpeles Better than Complex, ne?
Ja, genau.
Du kriegst halt, wenn das durch die Review
beim Produkt-Oner, der da aber nicht aus einer technischen Perspektive
drauf guckt, sondern aus einer Business-Perspektive
durchgeht, dann ist das ja gut.
Und das Team ist halt, wird immer dazu gesagt,
ist dafür verantwortlich, dass halt das fertig sein muss,
getestet sein muss und, aber
tatsächlich, es gibt niemanden,
der dann sagen kann, okay, das lasse ich nicht live gehen,
das geht so nicht, das ist Kacke.
Ich habe aber super Lust, bitte,
Red zu Ende, dann. Ja, und das gibt's
halt nicht und das ist halt etwas, was so ein bisschen
fehlt und was man, wo man sagen
würde, okay, aus der taktischen
Perspektive ist das irgendwie, also es führt halt
sehr, das Buch sagt, es gibt halt Unterschied
zwischen taktischer Softwareentwicklung und
strategischer und taktisch macht das
irgendwie Sinn, die Features rauszukriegen, ja, und man
hat halt auch ein Problem, wenn man das nicht hinkriegt,
weil dann wird einem ja möglicherweise auch der Hahn zugedreht
irgendwann, wenn man auf Reflection nicht so lange
dauert, aber man muss halt
diese strategische Perspektive auch berücksichtigen, weil
ansonsten hat man halt irgendwann später ein Problem.
Und diese Dinger summieren
sich halt auf und machen Sachen halt am Schluss
sehr, sehr teuer, um unerwarteter
Weise auch, ja.
Und ich würde jetzt sagen, so Refractoring ist halt
auch so ein Ding, was halt im Grunde dafür da ist,
die Komplexität von
so einem Software-System halt zu reduzieren.
Das wäre so, würde ich denken, das wäre ein Ziel.
Ja.
Wenn die Frage, was ist Komplexität? Komplexität
würde ich jetzt auch so mal definieren, wie es in dem
Buch wurde, dass er pragmatisch definiert als
alles, was dazu führt,
dass ein System schwerer zu ändern ist
beziehungsweise dazu führt, dass man es nicht
so gut verstehen kann, ist Komplexität.
Also entweder Abhängigkeiten
oder zu hohe Abstraktionsniveaus
oder zu verschachtelte Namen, falsche Namen.
Also ich finde, das ist relativ nah an diesem
Code-Review-Gedanken dran.
Ja, also kann ich den Code gut lesen?
Sind die Namen so, wie ich sie
haben will? Ist die Dokumentation schön?
Sind halt die
Designs so implementiert, wie man
es erwarten würde vielleicht? Oder
ist das irgendwas ganz anderes? Oder
macht das Sinn?
Auch ein bisschen
Style? Ist das auch eine Frage? Du hast irgendwie,
Er sagt, du wolltest den Unterschied zwischen Design und Style
an der Stelle vielleicht erklären, was Design
gemeint ist.
Design ist tatsächlich, damit ist tatsächlich
das quasi, wie funktioniert
das System gemeint? Nicht so sehr, wie sieht's
aus oder wie sieht der Code aus?
Das ist alles nicht so, sondern eher wie
funktionieren die Teile
miteinander? Also tatsächlich so Pattern?
Nee,
also wie ist, also du hast
ja, also ich meine, nimm mal sowas wie Design
Patterns, da sieht man vielleicht, was damit gemeint ist.
Ja. Das ist halt so,
Das ist halt die Art, wie dein System
designt ist.
Also da gibt es mittlerweile
so ein paar logische
Strukturen, an denen man
sich orientieren kann für Lösungen von
bestimmten Problemen. Genau, aber
man kann natürlich auch selber was machen, außer wenn man
irgendwas tut. Ich meine, es ist ja die Frage, ob man sich an diese
Patterns hält oder nicht oder die benutzt.
Aber man hat auf jeden Fall hinterher ein Design.
Interessant wäre, dass wenn man selber was baut, wo man keine Ahnung hat
und dann immer mehr Ahnung davon bekommt und das dann
refactored, ohne mal, dass man jetzt die Pattern kennt, ob
jetzt die Lösung, die man hat, selber Richtung dieser Pattern
konvergiert. Ja, genau, Design-Pattern, das ist genau
das, worauf es dann halt irgendwie immer hinausläuft, genau.
Das ist eigentlich die Idee dabei, ja.
Ich wollte noch gerade eine Sache
einwerfen zu der Sache mit der fehlenden
Rolle im Scrum.
Das ist auch eine Sache, über die ich jetzt in letzter
Zeit relativ viel nachgedacht
habe, weil wir ja auch
ganz viele Scrum-Teams haben und im Endeffekt
es ist natürlich schon so, dass
wenn du einen guten Entwickler hast, dass der natürlich schon irgendwie
darauf achten sollte, dass der
jetzt irgendwie gute Arbeit abliefert. Das ist ja schon irgendwie auch
Teil des Jobs. Aber diese
Sache, dass man halt so eine Ebene höher denkt,
dass man überlegt, okay, wann
ist denn jetzt der Zeitpunkt gekommen, dass ich jetzt nicht das
18. Feature noch da reinbauen kann, sondern dass ich es halt mal irgendwie
besser refactoren muss,
umstrukturieren muss. Oder
zu überlegen, wie setze ich denn jetzt
die Sachen so um, dass es in einem Jahr auch noch
funktioniert. Das sind ja Sachen, die stehen ja nicht
in der User-Story drin, die stehen nicht mehr in den Epics drin.
Der Product Owner hat davon keine Ahnung,
weil er ja kein Techniker ist.
Der Scrum Master ist
vielleicht Techniker, aber vielleicht auch nicht.
Das heißt, der kann es auch nicht beurteilen. Dann hast du ein Team, das ja meistens gemischt aus Seniors und Juniors ist. Bei den Juniors kann man es eigentlich nicht erwarten, dass jemand, der ganz frisch im Job ist, schon irgendwie drei Jahre im Voraus denkt.
Und es gibt tatsächlich auch super viele Artikel dazu im Internet, die genau versuchen, diese Idee des IT-Architekten aus dem klassischen Wasserfall irgendwie in dieses, ich habe jetzt ein Gänsefüßchen gesagt, IT-Architekt, das irgendwie in dieses Scrum reinzubringen.
Und da gibt es halt auch wirklich lange Artikel und so dazu, wo halt wirklich dafür auch gesagt wird, dass man das braucht, wie du es gerade auch gesagt hast. Und das ist auf jeden Fall ein Muss. Und dann gibt es Artikel, die sagen, nein, braucht man nicht, weil und so weiter. Und ich glaube, dass die Wahrheit liegt wie immer dazwischen. Und ich glaube, eine Sache, die im Scrum nicht vorgesehen ist, aber eine Lösung dafür könnte sein, halt jemand, der sich halt, sage ich mal so, als Lead-Entwickler im Team sieht. Das ist im Scrum ja explizit eigentlich nicht gewünscht, weil ja alle gleich sind. Ja, und alle haben gleich die Verantwortung. Aber ich glaube, so zumindest, soweit man das gedacht hat.
Sonst sind die Teams ja auch immer nicht, ne?
Genau, aber ich glaube, wenn du jemanden hast, der sich dafür verantwortlich fühlt und der das technische Know-how hat und wie gesagt, wichtig auch, dass er erstens weiß, dass er diese Rolle hat und zweitens auch, dass er das machen kann, dann glaube ich, kann das diese Brücke schon ganz gut überspannen, also diese Brücke spannen.
Und wenn der PO dieser Person auch vertraut und wenn die Person sagt, nee, sorry, aber wir müssen das Technik-Ticket vorher machen, bevor wir das umsetzen, weil sonst wird sonst nichts, dann glaube ich, ist das so der Weg, den man da gut gehen kann.
reden, wie immer. Aber du hast gerade vom klassischen Wasserfall-Software
Architekten gesprochen, den musst du vielleicht nochmal kurz erklären, weil
den kennt vielleicht auch nicht jeder.
Also ich bin da jetzt auch kein Experte,
ich bin auch mit agiler Entwicklung
nicht aufgewachsen, aber schon die,
wir haben nie wirklich nach klassisch Wasserfall
gearbeitet.
Die Idee dahinter ist eigentlich, dass ein
T-Architekt, der
im Agilen ist es ja, dass man iterativ
und kleinteilig arbeitet und im Wasserfall
ist die Idee, dass man am Anfang alle Informationen,
die man hat, sammelt. 80% Planung
und dann wird umgesetzt. Genau und also darum auch
Wasserfall, du fängst halt quasi oben an und danach geht das
diese Stufen einfach immer runter und am Schluss kommt halt
in Gänsefüßchen eine fertige Software raus
und da sind halt einfach ganz viele Probleme, weil
wie gesagt, Software ist nie fertig
und Wasserfall macht auch keinen Sinn und
der IT-Architekt ist halt derjenige,
der unter anderem halt
dieses Lasten- oder Pflichtenheft
schreibt initial, also sprich,
der sich überlegt. Das ist der Entwickler dann aber auch,
der quasi der Entwickler ist, ein
IT-Architekt in dem Falle und
baut. Nicht zwingend, nicht zwingend, also
ich glaube, es ist tatsächlich auch eine eigene Rolle,
gewesen oder ist es noch, also je größer die Firma, umso mehr Rollen hast du da separat, logischerweise. Aber ich glaube, die Idee ist wirklich, das ist jemand, der gar kein zwingender Entwickler sein muss, der aber trotzdem halt technisches Know-how hat und der versucht, alle Abhängigkeit und Eventualitäten, die dieses System betrifft, also alles, was man an Setup, Surroundings und so weiter hat, alles bedenkt und das alles niederschreibt.
Ja, dann braucht der eigentlich relativ viel Ahnung vom
eigentlichen Business und vom Kunden.
Und halt auch technisch. Das ist das Wichtige.
Dass man zum Beispiel sagt, weiß ich nicht, wenn ich
jetzt irgendwas habe mit asynchronen
Prozessen und Mailing, dass ich halt sicherstelle,
dass irgendwo drüber nachgedacht ist, dass ich irgendeine
Art von asynchronen Processing auch drin habe und
nicht, dass das halt dann nachher irgendwann auffällt.
Ups, blöd. Wie machen wir das denn jetzt?
Blöd gesprochen.
Blockiert leider den Prozess.
Ja, also genau.
Software-Architektur ist natürlich auch so ein verwandtes Thema.
ja, genau.
Aber ja,
wer ist dafür zuständig, gibt es dann meistens, also
es kann sein, dass sie dann halt nicht
in den Teams immer mit drin sind, sondern übergreifen.
Die gucken sich das dann halt mal an und
machen dann irgendwie Vorschläge oder so. Aber ja,
es ist unterschiedlich, wie das
gehandhabt wird, aber genau. Also, dass
da irgendwie sich jemand drum kümmern müsste,
ist eigentlich schon, glaube ich,
relativ offensichtlich.
Ja, aber was, was, genau,
was, was, ähm,
was denkt ihr denn so, genau, was
macht man denn, wenn man versucht, so ein Software-System
einfacher zu machen?
Was könnte man denn da tun?
Muss man das refactoren?
Ja gut, Refactoring ist
jetzt sozusagen das, was man dann tut, aber
wenn man, was wäre
denn das Ziel von so einem Refactoring,
wenn es darum geht, die Komplexität zu senken?
Also ich würde
tatsächlich mit diesem Schönheitsansatz
ausreden.
Ja, das ist ein bisschen abstrakt.
Wahrscheinlich wisst ihr alle, was man damit meint,
wenn ihr schon mal ein bisschen guckgeschrieben habt.
Kennt ihr was, was agil ist, was stinkt irgendwie?
Oder was, wo ihr denkt, oh, das ist aber hübsch.
Was wir da am Anfang irgendwie dann so um die Ohren,
ich habe das am Anfang nicht so richtig verstanden,
ich werde vielleicht, geht es ja anderen Leuten auch so,
immer wenn dann jemand draufgeguckt hat und meinte so,
okay, vielleicht nicht so toll, dann hieß es immer so,
ja, da muss man vielleicht mal so ein bisschen modularisieren oder so.
Modularisierung, weiß nicht, ob euch das schon mal so,
genau, da gibt es ein ganz berühmtes Paper von 1972, glaube ich, ist das,
jetzt habe ich den Titel vergessen,
naja, von David Parnas,
genau, wo er zum ersten Mal
diese Idee
formuliert hat, dass, wenn du jetzt
ein komplexes System hast,
wo viele Abhängigkeiten sind oder so,
dann ist es vielleicht eine gute Idee, das System so
zu teilen, dass
man nur noch einzelne Teile quasi
verstehen muss und nicht alles auf einmal.
Microservices. Und ja,
wie man das dann macht, ist eigentlich relativ egal. Du kannst es mit
Microservices machen, du kannst es aber auch
mit Funktionen machen, mit Klassen,
mit Modulen, Paketen, was auch
immer. Völlig egal. Das ist letztlich
nicht der wichtige Teil,
sondern der wichtige Teil ist quasi
kannst du
dein System so aufteilen,
dass
sich die Komplexität deines Gesamtsystems
reduziert auf die Komplexität
des komplexesten
Moduls sozusagen.
Im Idealfall. Also weil zum Beispiel in Django
gelingt es mir nicht immer, dass man so die Sachen
voneinander trennt, weil viele Sachen sind von User's App abhängig
oder sowas, das ist nicht so einfach,
dass du irgendwie... Das ist nicht so einfach, das ist auch
richtig, ja.
Das ist genau das, ja, genau, ich wusste dann auch nicht so genau,
was macht man denn dann da genau und so,
das ist sehr schwierig, ja, ist es tatsächlich,
ist auch sehr schwierig, finde ich immer noch
schwierig, aber ja, also
im Grunde ist das halt so die
Idee, dass man das halt tatsächlich
vielleicht irgendwie so hinbekommt
und
ja, das ist im Grunde auch,
im Grunde jetzt rausfinden, wie sind diese Module
und was soll damit was reden und wie sind die
Interface ist, das ist eigentlich im Grunde das, was Software-Architektur
macht, beziehungsweise was man halt auch
macht, wenn man jetzt Design macht
irgendwie. Also nochmal,
Interface ist halt die Schnittstelle, quasi eine
API, wo ein Modul mit dem anderen interagiert.
Ja. Und dann muss man quasi
definieren, welches Protokoll reden die miteinander und
mit welchen Feldern und welchen
Datentypen, welche wollen die denn haben.
Und im Grunde ist,
also das ist jetzt wieder,
aus mir spricht dieses Buch,
geht es da,
ist der interessante Teil gar nicht da,
wie man das jetzt technisch umsetzt oder so,
sondern im Grunde ist
die interessante Frage,
naja,
also man hat halt Abstraktionen.
Also ein Modul ist ja auch so eine Abstraktion
und eine Abstraktion hat immer
das Ziel, dass
man etwas,
also quasi nur
einen bestimmten Aspekt von etwas
tatsächlich wissen muss und
die ganze Komplexität dahinter ist halt versteckt.
Und deswegen hat man diese Abstraktion
und wenn die Abstraktion gut ist, dann
muss man den Rest auch nicht wissen.
Oder meistens nicht wissen. Wenn die Abstraktion
schlecht ist, dann liegt die halt
und dann muss man daran doch wissen und das ist dann schlecht.
Aber wenn man eine gute Abstraktion
gefunden hat, dann
braucht man sich sozusagen mental
nur mit dieser Abstraktion beschäftigen und gar nicht wissen,
wie das im Detail alles funktioniert. Zum Beispiel Python.
Ja, also eine Sprache,
die so ein relativ hohes Abstraktionslevel hat,
hat vielleicht auch schon über viele Probleme.
Also das ist ja vielleicht auch der Grund, warum wir sowas benutzen
und nicht mehr so alles in C schreiben oder so.
Ja, natürlich. Also, obwohl C ist ja auch eine High-Level-Language schon, im Gegensatz zum Zabler.
Ja, gut. Dass wir jetzt nicht mehr in Registern rumspringen wollen, wenn wir irgendwie ein Web-Service schreiben, ist ja schon mal gar nicht so schlecht vielleicht.
Ja, C ist ja schon eine Hochsprache.
Ich habe da tatsächlich ein ganz schönes Beispiel. Ich hatte letztens eine sehr undankbare Aufgabe.
Es sollte in einem Projekt, sollte ich bei, also quasi eine Sache, die sich durch das gesamte System gezogen hat, das hat relativ viel mit Zeitberechnung zu tun, also wo irgendwelche Tage und irgendwelche Uhrzeiten Tage berechnet werden.
Da sollte eine Sache, die vorher statisch war, also es gab halt im Endeffekt nur Tage, sollten diese Tage dann nach Regionen aufgeteilt werden.
Also jetzt beispielsweise halt Feiertage, die halt jetzt nicht nur irgendwie, es gibt nicht fixe Feiertage, sondern es gibt halt die Feiertage je nachdem, wo halt jemand dann ist, also wie ein Zeitberechnungssystem.
Und das hat halt wirklich querbeet eigentlich alle Bereiche des Systems betroffen, weil vorher war es halt einfach, du machst halt einen Abfall in die Datenbank, ist an diesem Tag ein Feiertag fertig.
Danach musste aber gefragt werden, na gut, welche Leute betrachte ich denn gerade, ob jetzt Feiertage sind und wann haben die denn in dieser Region gewohnt und wann nicht mehr.
Und auf einmal wurde das halt, war es halt super kompliziert, eine Sache, die vorher halt wirklich trivial war, wie die mit einem einzigen Select oder ORM, Abstraktion Select, halt super einfach abzufragen war.
Und dann habe ich halt auch lange darüber nachgedacht, wie ich das überhaupt hinbekomme, weil, wie gesagt, ich habe nachher, glaube ich, an 300 Stellen im System irgendwas angepasst.
Und die Lösung war tatsächlich dann ganz, ganz blöd Abstraktion.
Also sprich, jetzt war halt ein Django-Projekt, ich habe dann einfach mir Custom Query Set und Manager-Methoden geschrieben, die das halt komplett wegkapseln, wo ich dann trotzdem einfach nur das Datum und vielleicht noch den Nutzer reingebe und darunter liegt dann halt irgendwie ein Riesenapparat mit irgendwas, da halt alles dann passiert, um das halt zu bestimmen, aber von oben verwendet es sich fast genauso wie die triviale Datenbankabfrage und damit habe ich es wirklich geschafft, also ich habe das quasi das ganze Ding umgebaut, ist ja auch irgendeine Art von Refactoring eigentlich,
nur, dass es halt in dem Moment das Ticket war.
Und ich habe wirklich nur drei oder
vier kleine Bugs gehabt, weil halt
wie gesagt, die ganze Komplexität an einer einzigen
Stelle war und ich halt danach nur noch schauen musste,
dass ich halt die Methoden austausche.
Und das war, es hat
mich selbst total überrascht, wie gut das funktioniert hat.
Also das hätte ich mir selbst nicht zugetraut,
dass die Idee dann doch so gut trägt.
Ja.
Wenn man so eine High-Level-App hier hat, die man
gut bedienen kann, dann ist das schon echt was wert.
Ja, also genau, und was sind
gute Abstraktionen? Also
nach dem Buch ist es halt so,
ja, wenn Module tief sind,
ist das gut und wenn die
API halt klein ist, ist das auch gut.
Also je kleiner die API und tiefer,
je kleiner und tiefer, desto besser. Genau, du kannst mit einfachen
Worten viel erreichen.
Ja, also als sozusagen Beispiel
für, das ist
irgendwie eine schöne API, ist halt
die File
API von Unix benutzt, das ist halt auch tatsächlich
eine sehr schöne, also das ist ja im Grunde
Unix ist nichts,
wir hatten das letztes Mal, in der letzten Episode,
was wenn alles ein Dict wäre, Unix ist halt
so, was wenn alles ein Pfeil wäre.
Das ist irgendwie die Antwort darauf.
Dann fällt halt Unix dabei raus.
Und die Pfeil-API ist
halt tatsächlich, die ist halt sehr, also man kann
nicht, es gibt nicht viele Obterationen, die man machen kann.
Also was heißt denn Open, Seek
und Close?
Es gibt Open, Seek
und das war es eigentlich schon fast, ja.
Also Close, weiß ich gar nicht, ob das ein eigener, ja doch.
wahrscheinlich. Ja, aber stimmt.
Genau. Und
ja, es gibt noch I.O. Control,
aber... Also wahrscheinlich Read&Write oder so, aber ja.
Was ist I.O. Control? Ja, ja, man kann
jetzt noch Spezialoperationen machen, da wird's dann auch
allmählich hässlich. Aber
tatsächlich eigentlich so mit Pfeil
aufmachen, irgendwie drin rumzieken,
lesen, schreiben,
kommt man halt schon sehr, sehr weit.
Und ja,
das ist halt eine schöne Abstraktion, während
zum Beispiel die
Abstraktionen, das ist dann so ein Negativbeispiel
gewesen, halt so, wenn man jetzt
in Java irgendwie
Dinge lesen will aus einem File, dann macht man
erstmal irgendwie so einen Input-Reader
auf und dann macht man so einen Buffered-Input-Reader auf,
wenn man das vergisst, hat man ein Problem, das ist alles ganz langsam,
man weiß nicht so genau warum und dann muss man die
Dinger konfigurieren und die Exposen halt ganz
viele Sachen, die man halt setzen muss und der
Default-File ist halt, den man halt eigentlich
immer hat, der ist halt nicht der,
also wenn man es einfach nur so aufmacht, ein File, dann
hat man halt keine
gebufferte I.O. und das ist halt alles
ganz schrecklich. Und man muss
halt sehr, sehr viel Detailwissen in der
API schon, also man konfiguriert
da schon sehr viel rum und also
man hat halt, die API hat eine große Oberfläche und
es ist schwer zu benutzen
und eigentlich, was sie macht, ist relativ
trivial. Also es ist super flach.
Also sowas wie in Python, with open
filename is file, file.read.
Genau, oder ja,
for line and file oder sowas.
Das ist halt irgendwie, und das macht halt
auch bei der Default alles richtig.
Wenn du das in Python machst, dann ist das halt direkt
schnell und macht alles schon so, wie man
das eigentlich normalerweise haben will. Für die Fälle,
in denen man das nicht so haben will, kann man das ja immer noch
konfigurieren, dass es sich
anders verhält. Aber genau.
Und das ist halt gutes versus schlechtes
API-Design quasi.
Und ja.
Aber die richtige
API für ein Problem, das man hat, oder
überhaupt die richtige Abstraktion zu finden, ist natürlich
nicht so einfach. Das ist halt richtig schwierig.
Vielleicht auch einer der Gründe für PHP, warum das
immer so schlecht angesehen wird an so zwei Stellen
sich lange brauchte, bis es ein bisschen besser wurde.
Also wie gesagt, ich habe immer noch keine Ahnung davon. Aber ist das
einer der Erfinder, der irgendwie gesagt hat am Anfang so, ja, eigentlich
kenne ich mich mit Programmiersprachen eigentlich gar nicht aus
und ich wollte eigentlich auch nie Sprache machen. Aber hey,
jetzt bin ich hier irgendwie und wir müssen jetzt irgendwie das
wieder retten.
Ja, aber ich meine, es ist schon
einen langen Weg gekommen sozusagen, also
mittlerweile ist der PRP.
Aber ja, vielleicht einer
der Gründe dafür, dass man sich über sowas noch keine Gedanken gemacht hat.
Während Guido ja, glaube ich, von Anfang
an, glaube ich, sehr auf diesem Level war, dass er schon
so ein bisschen wusste, warum er
Sachen wie machen wollte.
Ja, ja, der hat
viel Absicht mit dabei, ja.
Ja,
ja, keine Ahnung. Also ist da auch die Frage,
ist da so eine neue Sprache, ein Refactoring
von neuen Gedanken, die man
auf dem Computer hat?
Ja.
Naja, ja, aber ich meine, es ist halt,
es ist wirklich schwer zu sagen, also man kann
das nicht unbedingt vorher,
also ich glaube nicht, dass das, eben auch
im Sprachdesign ist ja, also das wäre jetzt sozusagen,
wie ist eine Sprache designt?
da die richtigen Abstraktionen zu finden, auch
super schwierig. Und da würden
Leute dann auch direkt am Anfang schon
unterschiedliche Ansichten vertreten und würden halt
sagen so, okay, also es gibt dann
halt ein Lager irgendwie, das
sagen würde, so, ach, dieses
dynamisch getypte, das ist alles
nicht gut. Irgendwie statisch getypt,
bestes getypt, voll gut.
Muss alles statisch,
ja, und an der Stelle
wird man sich ja schon, und das ist bis heute nicht raus,
was jetzt nun besser ist.
Ja, aber typisieren ist auf jeden Fall anstrengender,
wenn man halt einfach mal so was
schnellstens hinhotzen muss. Ich habe heute eine kurze
Übung in Rust geschrieben,
du musst halt jedes Mal an jeden
kleinen Witzel dran schreiben, was das eigentlich sein soll
oder sollte und dann beschwert er sich
der Compiler immer, wenn es halt nicht stimmt, was
ja auch gar nicht eigentlich schlecht ist, weil in der Benutzung will man ja, dass es
eigentlich stimmt, weil man weiß,
es ist halt dann egal, aber es funktioniert irgendwie trotzdem und das ist
ein bisschen...
Ja, aber das ist genau so ein Punkt.
Genau, also wenn du
du kannst ja jetzt auch zum Beispiel
in Python Type Annotations
machen.
Ich habe jetzt
erst so vor kurzem damit angefangen, mich so ein bisschen
zu beschäftigen, weil vorher dachte ich mir so,
Type Annotation schreiben,
keine Lust.
Und ach, mich interessiert das alles nicht.
Ich bin ja nicht deswegen zu Python
gegangen, damit ich irgendwie überall
Typen
dran schreiben muss.
Aber mit FastAPI,
Obwohl, das wir übrigens auch noch eine Folge machen wollen.
Das ist cool benutzt zu haben. Aber dann macht das sogar
dann Dinge, wenn du die Typen verwendest und so.
Ja, ja, ja.
Aber gut, da passieren auch Sachen dynamisch.
Genau, ja.
Das ist halt auch nochmal so ein, das geht ja schon fast
darüber, die reinen Typ-Annotationen hinaus.
Typ-Magie. Ja, also je nachdem,
was für Typen man dann da hat,
passieren halt unterschiedliche Sachen,
aber dann auch zur Laufzeit.
Das ist nicht nur für einen statischen
Typ-Checker.
Ja, aber natürlich, genau.
das ist halt so ein Problem beim Sprachdesign.
Will man jetzt Typisierung haben oder nicht?
Weil natürlich fängt es halt
Bugs. Ich habe das jetzt auch gemerkt, ich mache das seit einiger
Zeit, mache ich auch Fast API und
habe jetzt auch, dachte mir, oh gut, wenn
ich das schon mache, dann schreibe ich die Annotation halt auch mit
dazu. Und tatsächlich sind mir schon ein paar Mal
Sachen aufgefallen, wo ich
dann gemerkt habe, so, oh,
da hat mir jetzt,
ich lasse dann auch MyPi drüber laufen,
wo mir dann MyPi auf die Finger haut
oder halt eben Pylense oder was auch immer.
So, da ist irgendwas nicht richtig.
Und ich denke so, okay, also meistens ist es tatsächlich nur, ich habe es nicht richtig hingeschrieben, ich habe das irgendwie nicht richtig bedient. Und deswegen, und man muss es ein bisschen anders hinschreiben und dann stimmt es, aber das, was ich vorhatte, war schon richtig. Und dann ab und zu kommt dann doch so ein Ding, wo ich dann drüber nachdenke und dann so, oh Mist, tatsächlich, an der Stelle kann irgendwas nannen werden oder so. Das ist meistens sowas. Und wenn man ein bisschen drüber nachdenkt, dann wird einem klar, dass das auch tatsächlich so sein kann.
Aber mir war das vorher gar nicht klar.
Den Fall habe ich, ich dachte, das kann überhaupt nicht passieren.
Ach doch, kann doch passieren.
Und dann habe ich tatsächlich im Grunde einen Fall übersehen
und da wäre ein Bug gewesen eigentlich.
Ja, sowas hat er, ich glaube auch.
Also die meisten Bugs, die ich irgendwann entdecke,
sind wirklich viele Type-Bugs irgendwann.
Ja, also viele sind es nicht gewesen, ein paar waren es.
Also ich habe zum Beispiel, ihr kennt ja Antwerpen auf Code.
Also Antwerpen auf Code ist so ein tolles Spiel,
was man in der Adventszeit spielen kann,
wo man halt so Coding-Rätsel macht, ganz süß immer gemacht.
Diesmal ist es ein U-Boot.
Und auch da, also ganz einfache Aufgabe, erste Aufgabe, iterieren über so ein Array vergleichen. Es gibt einen unheimlich großen Unterschied, ob man halt den Typ, das ist eigentlich nur eine Liste, also in einer Datei, von Zahlen, ob man da ein Int drauf castet oder halt nicht, weil halt der Vergleich, den man machen muss zwischen Zahlen, halt ein anderes Ergebnis hat, aber nur an zwei Punkten.
Das heißt, man kommt am Ende irgendwie auf 1.300 Treffer
und dann kommt man auf 1.301 Treffer,
wenn man halt den Typ ändert oder sowas.
Und das ist halt nur eine Sache richtig.
Und das halt zu finden, dass man halt überhaupt so einen Bug hat,
wenn halt das meistens stimmt.
Ja, also in 1.299 Fällen ist das richtige Ergebnis da.
Das geht halt nur wirklich, wenn man tatsächlich weiß,
warum und welche Typen man da hat.
Und wenn man das irgendwie sicherstellen kann.
Und das geht halt mit Type-Ins ganz gut,
weil du weißt halt, oh, da muss halt ein Int rein oder so.
Und wenn man das vergisst, dann funktioniert das halt nicht.
Und das ist mir auch erst klar geworden,
als ich jetzt zum Beispiel die Lösung auch in Rust oder in Go
geschrieben habe, weil dann
klar ist, welchen Typ er hat und weil es halt
immer das falsche anzeigt, wenn man halt den Typen nicht
konvertiert.
Ist aber auch, glaube ich, eine super Sache, wenn man
so interne
APs hat, also entweder, wenn man irgendwie
so zentrale Funktionalität hat,
die irgendwo liegt oder Sachen, die halt von vielen verschiedenen
Seiten irgendwie verwendet wird oder
von vielen verschiedenen Entwicklern,
gehe ich inzwischen auch immer hin und versuche die
so weit wie möglich zu typisieren in
Python. Einfach, dass dann
Und dass der nächste Entwickler, auch wenn ich das bin, einfach weiß, okay, da kommt jetzt, weiß ich nicht, vielleicht ein Nun raus oder eine Liste oder ist das ein Dictionary?
Weil das sind halt wirklich so Sachen, meistens findet man es, bevor es wirklich auf Production geht.
Aber selbst dann sucht man nochmal irgendwie fünf oder zehn Minuten, wenn man nochmal denkt, hey, ich hab doch und warum, was soll das denn?
Und wenn einem dann die IDE dann direkt anzeigt, nee, nee, du machst die Äpfel mit Birnen, das ist einfach super praktisch.
Und umso tiefer das bei mir drin ist, umso mehr versuche ich auch dann wirklich die Type-Ins zu machen.
Ja, mit dem Nun ist halt echt ein Problem, ne?
Aber, ja, da fällt mir auch gerade so eine Anekdote zu ein, da gibt es noch ein Buch, JavaScript, The Good Parts, glaube ich, auch ein relativ bekanntes Buch.
Das muss halt dünn sein.
Das ist tatsächlich relativ dünn.
Da gibt es doch diesen Witz mit dem dicken Buch, der JavaScript.
Genau, die Reference, das ist irgendwie zu tausend Seiten und dann irgendwie Good Parts ist halt irgendwie so ein Heftchen, ja, das stimmt.
Und der Autor davon, ich glaube, das ist David Crockford oder ich weiß nicht genau, der ist auch in diesen Standardisierungsgremien drin und so und der schrieb dann halt auch irgendwo, weiß gar nicht, meinte so, naja, also irgendwie diese, ist eigentlich kein Wert oder ist irgendwie nix, Dinger sind ein Problem bei Sprachen, ja, also Python halt none, da gibt es halt ein Ding und es ist halt immer wieder in diesen, wenn man sich über so Standardisierungsfragen, ist immer die Frage, ist das eine gute Idee, sowas in der Sprache zu haben oder nicht?
zum Beispiel SQL, ja, ist ja auch, Null
ist für einen Großteil der
wirklich hässlichen Sachen im
Sprachstandard und auch für viele Bugs in
Datenbankimplementationen, die dann halt
auch irgendwie, und für viele Inkompatibilitäten
in den Standards und so, also Null
spielt da eine große Rolle, ja, wenn man jetzt sagt, so ein harmloses
Ding wie Null, das kann ja nicht so viel kaputt machen,
das Ding macht irgendwie dauernd und seit
Jahrzehnten und konsistent irgendwie ganz viel Probleme
und, ja, er meinte
da so, ja, also es ist immer so, unter Leuten,
die sich mit Sprachdesign beschäftigen,
in Frage, will man sowas in der Sprache haben oder nicht?
Und dann gibt es immer so einen einen Teil der Leute,
die sagen, ja, doch, ist eigentlich schon gut, wenn man das hat.
Ein anderer Teil sagt, nee. Aber absolut
niemand, absolut niemand vertritt die Ansicht,
es ist voll gut, zwei davon
in einer Sprache zu haben. Und da was gibt, hat halt zwei.
Das hat halt immer null und undefined.
Und das ist halt wirklich, ah.
Ja.
Das ist halt irgendwie so.
Ja.
Und das macht Dinge wirklich komplizierter.
Aber das Problem ist jetzt auch,
die Type-Annotationen
selber machen Sachen natürlich auch komplizierter.
Ja, zum Beispiel zirkuläre Importe oder so was,
das ist ja ein bisschen nervig.
Nee, die Annotationen, also, achso, gut,
okay, klar, da kannst du auf das Problem natürlich auch stoßen,
ja klar, oder
leichter, aber ich meine, wenn das
jetzt eben, also entweder man macht
halt, wenn man jetzt die Typen annotiert
und man macht es jetzt so
quasi einfach,
man muss halt dann auch seinen Stil ändern,
wenn die Typannotationen
einfach bleiben sollen, dann muss man halt irgendwie
das auf so relativ primitive
Datentypen runterbrechen und kann dann
eigentlich auch nur noch so relativ primitive
Datentypen verwenden.
Ja, man will ja eigentlich schon komplexere Daten,
also so ein Pathentic-Objekt oder sowas
hinten. Ja, gut, okay, also Pathentic ist nochmal,
aber das Problem dabei ist halt,
also wenn man das macht, dann hat man
halt im Grunde, kommt man dann irgendwie so
und wenn das Typsystem relativ einfach ist,
was man so verwendet, dann kommt man halt
bei einem Dialekt von Java raus, der halt super langsam
ist. Was halt, und es sieht
überhaupt nicht mehr aus wie Python eigentlich.
Das ist halt irgendwie doof,
aber wenn man jetzt Python
idiomatisch schreibt, so Pythonisch
irgendwie, dann
wird das mit den Typ-Annotationen
ziemlich schwierig. Also weil zum Beispiel
so eine, da gab es letztens auch eine
Podcast-Episode mit
Luciano Ramaglio,
der hat für Python geschrieben, das Buch,
kann ich nur empfehlen. Es gibt jetzt, im Frühjahr kommt
eine zweite
Ausgabe, zweite Edition,
Second Edition,
wo er auch viel über Type-Annotationen und so schreibt.
Und der hat sich das auch dann halt mal so richtig angeguckt und so und hat dann die Typ-Annotationen für die Max-Funktionen sich angeguckt.
Und das Problem bei Typ-Annotationen ist jetzt auch, die können ja auch falsch sein.
Die können ja richtig sein, falsch sein.
Die können uns dann False-Positives geben.
Es kann sein, dass etwas dem Typ zwar entspricht, aber tatsächlich ist es inkompatibel und innen knallt es irgendwo.
Das sollte natürlich nicht passieren.
Typ-Annotationen sollten so sein, dass es keine
False-Positives und keine False-Negatives gibt, also auch keine
das ist halt das, was mir immer
passiert, wenn ich versuche, das hinzuschreiben, ich habe halt
ganz oft False-Negatives, das heißt, mir sagt
irgendwie MyPi oder so, da hast du
was falsch gemacht und ich sage so, ne, das ist eigentlich nicht
das ist eigentlich schon richtig, aber ich habe es irgendwie falsch
hingeschrieben und bei
einer Funktion wie Max ist das halt extrem
schwierig und hat er halt in den
Type-Annotationen dafür halt Fehler gefunden
eben False-Positives, False-Negatives
und hat dann versucht, das richtig zu machen, also es gibt irgendwo
Type-Chat oder so
da steht die Annotation für Max
drin und das wurde dann
richtig, richtig gemein, weil Max ist halt auch
so eine komische, also es gibt so diverse Funktionen, so Max
Len und so, die halt schön sind
irgendwie, weil du kannst halt, es ist eine sehr
generische Funktion, du kannst da alles reinwerfen und es macht
eigentlich immer das Richtige,
aber das jetzt zu annotieren ist halt
die Hölle, also er hat dann irgendwie
so, naja, also die
eigentliche Implementation von Max sind halt
irgendwie so 25 Zeilen oder so
und allein die
Typ-Annotationen waren hinterher, du musst halt
sechs Overloads
dafür irgendwie definieren, der Funktion
und es waren viel, viel mehr
Zeilen in den Typ-Definitionen als hinterher in der
Annotation. Und dann ist natürlich die Frage, und es war
sehr schwer zu verstehen und
also irgendwie diverse
subtile Fehler drin. Also dann ist
halt die Frage, okay, wenn das so schwierig ist,
die Typen hinzuschreiben, ja,
macht das dann, ist dieses Verhältnis
zwischen, und es
ist halt komplett, es ist auch sehr schwer zu lesen, ja.
Also es ist halt die Frage, ja, ist das dann wert noch?
Und ja, das ist halt so die Frage.
Und das gibt es genauso, weil das war auch aus dem Podcast.
Da meinte er so, es gibt so ein Buch zu Java.
Ich habe vergessen, welches das ist.
Auf jeden Fall ist auch einer, der in der Sprache mitgearbeitet hat oder so,
der schrieb dann halt zu, als die Generics eingeführt wurden,
selber sagt er
dazu, also die Generics waren ein Desaster
in Java und
es gibt diverse Geschichte, Konstrukte,
die sie da gemacht haben, wo es
dann, wo sie dann gesagt haben, so wir haben
das jetzt irgendwelchen Professoren, die sich mit Typtheorie
beschäftigen, gezeigt
und die sagen, das stimmt,
aber wir können das nicht
bestätigen oder
weil wir verstehen nicht,
was das macht.
Und das ist dann halt einfach so, ja gut, wozu macht man es
dann jetzt, wenn man es nicht mal verstehen kann?
Und also was man da sieht, ist halt, das Problem ist, dass die Sprache ist halt, also bei Python ist es halt auch so, die Sprache ist halt expressiver als die Sprache, die man verwendet, um die Typ-Annotationen zu machen. Und das hat ja schon in diversen Sprachen zu Katastrophen geführt. Also bei C++ mit den Templates, ja, ganz furchtbar, das ist ein Turing vollständig. Irgendwie, wenn man davon genug verwendet, versteht man auch nicht mehr, was da los ist. Der Compiler braucht ewig lange viel Hauptspeicher und schrecklich. Java, Generics, ganz furchtbar.
Wie macht man das so, zum Beispiel mit einem JSON-Objekt?
Wie würde ich das type-contentieren?
Das ist so ein bisschen...
Genau, das kann man.
Das kann man tatsächlich.
Also ich beschäftige mich ja gerade auch so ein bisschen mit TypeScript.
Und da gibt es, also da kannst du,
du kannst tatsächlich solche Sachen machen wie...
Rekursiv definieren.
Du kannst rekursive Typ-Definitionen machen, wenn es geht.
Das geht in Python, glaube ich, bisher nicht.
Ja, das kann gut sein, dass das in Python nicht geht.
Also die Type-Definition für einen JSON,
wo dann hinterher der TypeScript, der TypeScript-Compiler,
auf die Finger haut, wenn du da auch
bliebig rekursiv irgendwo etwas reinschreibst,
was jetzt nicht mehr welches JSON wäre,
wo du eine rote Klingel kriegst,
das sind so 25 Zeilen rekursiv
Type-O-Notationen in TypeScript. Das geht.
Und das ist natürlich schon sehr cool, dass das geht.
Auf der anderen Seite,
ich beschäftige mich
jetzt seit einer Zeit damit, also ich kann
diese 25 Zeilen sehen.
Ehrlich gesagt, ich verstehe sie nicht so ganz.
Das ist halt auch wirklich, wirklich schwierig.
Ja, da können ja rekursiv
irgendwelche Dinge drin, irgendwelche Listen drin liegen,
irgendwelche Dicks drin liegen, irgendwelche Listen drin liegen, wo vielleicht noch ein
Zwingl ist und irgendwie Null oder irgendwas.
Ja, es ist halt wieder eine Sprache
für sich, also allein schon, dass du
in Types, dass du halt sagst,
okay, es gibt ja eben
diese Generics, sag ich mal,
du kannst halt nicht nur,
du definierst die Typen nicht fix, sondern du sagst
halt, also du kannst
jetzt in der Funktion
sagen, welchen Typ
du zurück erwartest und den dann
als Typ-Annotation verwenden.
Du kannst also sozusagen Typen parametrisieren,
die du irgendwo setzt. Du kannst eine generische
Funktion haben und dann sagen,
während du sie aufrufst, im Aufruf
kannst du dir sagen, und die gibt jetzt das und das
zurück. Und dann kann der Compiler
das überprüfen, dass das stimmt. Und das kannst du dann
auch noch rekursiv machen. Und das kannst du dann mit
beliebig verschachtelten Sachen machen.
Sollte man das vielleicht ein bisschen refactoren?
Naja,
also es wird halt
Ich meine, es ist schon cool. Auf der einen Seite finde ich es
voll cool, dass es geht. Auf der anderen Seite denke ich mir so,
mein Gott, was haben wir getan? Wir müssen ja mal ein Monster
erschaffen. Aber ja,
es ist...
Also ist das eine Mode? Also ich habe auch
das relativ oft benutzt. Ich benutze das auch gerne
und ich versuche auch, das relativ vollständig so
zu benutzen. Aber halt,
ja, es hat halt irgendwie seine Grenzen auch.
Also manchmal nutze ich das einfach nicht, weil es einfach keinen
Sinn macht. Also für so ein Int oder String,
okay, aber dann so komplexe Objekte...
Ja, aber bei komplexeren Sachen wird es halt dann sofort ziemlich schwierig.
Ja. Also eine
Geschichte, die wohl cool ist, ist halt
Protocols. Damit kann man halt
also Typing.Protocols
mit Python 3.8 glaube ich dazu gekommen, damit kann man
dann viele der Probleme, die man sonst hat
irgendwie gehen dann weg, weil man dann
sagen kann, okay, ich erwarte hier nur ein Ding, dass
also Protocols sind immer so kleine Sachen, wo du eine
Methode hast oder vielleicht zwei oder so
und dann musst du halt nur diese Methoden implementieren.
Du kannst halt überprüfen, ob das so ist,
ob das konform ist
und dann fällt ein Großteil
der Schmerzen weg, aber
also wirklich, ja,
Also wenn das zu komplex wird,
vielleicht muss man dann refactoren, dass man einfachere Dinge
macht, wie zum Beispiel nach Strings zu realisieren oder sowas.
Nee, nee, nee, aber das Problem ist ja, also das willst du
ja eigentlich vielleicht nicht. Du willst ja vielleicht sowas, so generische
Funktionen haben wie Max oder so.
Aber die kannst du praktisch nicht mehr gut annotieren, also außer
du machst halt, es ist halt schwer, die zu annotieren.
Das gute ist, wir müssen es ja
nicht im Python, von daher vielleicht.
Ja, genau. Und vielleicht ist es für die Fälle,
einfach dann nicht typisieren,
sondern sagen, okay, wir machen es an den Stellen, wo es halt was
bringt und nicht so viel Arbeit ist. Und an den Stellen, wo
es halt nicht gut geht, dann lassen wir es halt weg und dann schreiben wir halt
eine generische Funktion. Magic Python.
Genau.
Das ist vielleicht irgendwie so der richtige
Weg. Das haben wir kommen hinterher zu Tyson.
Ja.
Eine Sache,
die mir noch aufgefallen ist, jetzt
in
den letzten Monaten beim Arbeiten
bezüglich Refactoring, ist,
es geht auch so ein bisschen Richtung Modularisierung,
aber mehr Richtung
die Semantik, denn wirklich die Sachen physisch
irgendwie zu trennen. Und das ist,
Wenn man relativ viel, also in meinem Beispiel relativ viel Business-Logik hat, also wenn man meistens fängt, also wenn man agil arbeitet, fängt so ein System mit MVP an, also sprich man hat, weiß ich nicht, irgendeinen Online-Shop, da kann irgendwer was kaufen, dann kriegt er vielleicht eine E-Mail, da gibt es irgendwie eine Bestellung und das war es im Endeffekt.
Und dann kommt vielleicht noch ein anderer Fall dazu, noch ein Fall und noch ein Fall und irgendwann wird ein neuer Geschäftsbereich dazu gebaut und irgendwann hat man halt dann da ein riesiges Konstrukt von irgendwie E-Mails, die hin und zurück geschickt werden und irgendwelche Order-Objekte in der Datenbank, die riesig werden, wo hunderttausend Felder drin sind.
Und das eigentliche Problem ist, dass dann an einem gewissen Punkt, das habe ich jetzt schon mehrfach gesehen, weder der Kunde noch die Entwickler eigentlich noch genau wissen, was eigentlich der Geschäftsprozess ist.
Das System macht zwar ungefähr das, aber dann kommt plötzlich irgendwann mal ein Fehler, dann schickt man sich eine E-Mail und hat irgendetwas Falsches geschickt und dann stehen die Leute dann da und sagen, ja, was passiert da eigentlich genau?
Und das finde ich einen total interessanten Refactoring-Ansatz, weil das halt nicht so, also keine Ahnung, wenn ich jetzt irgendwie merke, okay, das ist irgendwie ein schlechtes Pattern oder keine Ahnung, das ist nicht Lind-konform oder keine Ahnung was, dann geht man hin und refactort es halt, weil das schreit einen quasi an, das ist das Hässliche, was du meintest.
Das ist ein Code-Review, wenn man relativ sehen kann, wie gesagt, Kommentare stimmen nicht oder Docs sind falsch oder es sieht hässlich aus, es ist zu lang, man kann es so ein bisschen umbauen, Namings sind komisch, dann kann man das schnell machen.
Genau, aber so eine Sache, wenn man sagt, okay, ich habe jetzt da dieses Konstrukt und es ist auch alles vielleicht auch gar nicht so schlecht an sich für den Pattern, also man hat das vielleicht alles in Klassen drin und Services und du hast auch irgendwie Models gebaut, wo das auch alles irgendwie die Datenstruktur ist.
Interessant ist immer noch Services, da müssen wir auch nochmal drüber reden, was das eigentlich ist.
Aber wenn halt irgendwann dieser ganze Business-Prozess halt nicht mehr offensichtlich ist, da muss man halt einfach diese Art von Abstraktion, einfach eine neue Art von Abstraktion finden und da ist eine sehr interessante Sache, mit der wir uns jetzt beschäftigt haben, sind halt die Final-State-Machines.
Dazu gibt es auch einen sehr coolen Vortrag von 2019. Ich habe vergessen von wem, aber da gibt es Django FSM. Das Problem ist, das Package ist leider deprecated und die neue Version ist noch in Alpha. Also man kann die schon nutzen, aber die Doku hat Lücken. Wen es interessiert, wir haben beim letzten Django Meetup in Köln haben wir länger drüber gesprochen. Das ist bei YouTube.
Vielleicht nochmal ganz kurz dann erklären, was ist denn eine Finite State Machine?
Also Final State Machine ist im Endeffekt relativ simpel, dass man sagt, ich habe ein Objekt und dieses Objekt kann in verschiedenen Status sein. Also sprich, ich habe einen Auftrag, der kann neu offen sein, der kann in Bearbeitung sein, der kann in Lieferung sein, der kann abgeschlossen sein, der kann bezahlt sein.
Und dass es eine endliche Menge von Wegen gibt, wie ich von jedem Status, also nicht von jedem zu jedem, aber wie ich von einem Status zum anderen komme. Kann man sich im Endeffekt einfach wie ein Graf mit Pfeilen, also Kringeln und Pfeilen vorstellen. Und man hat halt im Endeffekt fix definiert, also erstmal auf dem grafischen Level, dass ich zum Beispiel von, ich kann nicht von offen direkt nach geschlossen kommen, weil davor muss es erstmal irgendwie bearbeitet, bezahlt und geliefert werden. Ja, oder so, das geht halt sonst nicht, so könnte man sich jetzt vorstellen, ja.
Und der Vorteil an diesen, also das ist nur eine von vielen Möglichkeiten, um sowas anzugehen.
Und wir haben das jetzt halt ausprobiert und es hat halt wirklich, wirklich gut funktioniert.
Weil das Schöne ist, diese Graphen sind sehr, also die werden natürlich auch immer komplexer, wenn man halt sehr viel Business-Logik hat, aber trotzdem, die versteht halt wirklich jeder.
Also der komplette Non-Techie kannst du das auf den Tisch legen und der weiß sofort, um was es geht.
Und das Schöne ist halt, das geht mit der neuen Version glaube ich nicht, sondern mit der alten Version, wenn man diese Flows implementiert in Django, mit diesem Package,
dann konnte man sich die Graphen auch rausrendern lassen.
Also sprich, die Business-Logik,
die man einerseits für als Entwickler sinnvoll ablegen kann,
weil man halt auf einmal nicht mehr überall irgendwo langwurschtelt
und irgendwie in jedem Service das irgendwie ein bisschen anders macht,
je nachdem aus welcher Ära vom Projekt das dann halt gebaut wurde.
Sondern man sagt, okay, ich habe einen Flow
und hier definiere ich jetzt genau, was passiert,
wenn Auftritt von offenen Bearbeitungen geht.
Zum Beispiel, da geht eine E-Mail raus oder da geht keine E-Mail raus
oder da muss jemand irgendwas machen damit, ja,
und welche Variablen gesetzt werden.
Und erstens ist es halt im Code sauber gekapselt
Und die alte Version konnte, wie gesagt, direkt die Graphen rausrennen. Das heißt, wenn man ein hinreichend komplexes Business-Modell implementiert hat und dann kommt der Kunde und sagt, ich würde da gerne was dran ändern, dann kann man im Endeffekt auf den Knopf drücken, kriegt dann ein wunderbares PDF raus, kann darüber dann mit dem Kunden reden und sagen, okay, welche Pfeile sollen wir jetzt umbiegen und wo soll was anders passieren?
Und das ist halt, also das ist halt wirklich auf einer ganz anderen Ebene und es ist halt so trivial, also ich bin eher schockiert, dass mir sowas noch nicht, also dass ich da so spät im Endeffekt drüber gestolpert bin über solche Sachen.
Ja, ich glaube, was eigentlich schwierig ist, ist tatsächlich diese Dinger aufzumalen, weil ich glaube, selbst die Kunden kennen nicht immer ihren Flowchart, weil die halt nicht wissen, was passiert denn da und bevor sich das nicht jemand angeguckt hat und vielleicht mal das in der Realität getestet hat, oh, da ist aber noch ein Problem, dann tauchen diese einzelnen Ereignispunkte oder auch die States, die irgendwas haben kann, gar nicht auf.
und das, bei uns hat das so einen ganz bösen
Bug geführt. Ja,
die Tests waren eigentlich ganz gut, also die haben eigentlich das getestet,
was getestet werden soll, das heißt, Carbide war hoch,
also der Code, aber es gab halt den Fall einfach nicht
und das führte halt einfach dazu, dass fälschlicherweise
beispielsweise, wir haben so 4MN-Quatsch
gemacht, an ein paar hundert Vertriebler
einfach so E-Mails rausgingen, die gar nicht rausgehen sollten
oder so, oder zu oft und sonst halt so ein bisschen
so, okay, ups
und das böse schreit halt dann, man denkt sich
halt so, nein, wir können den nur und total
doof und das macht ja gar nicht, dass wir es sollen, das ist falsch
Aber eigentlich ist halt nur der Fall, dass man halt nicht bedacht hat, dass es einen besonderen Fall geben kann, der halt nicht abgebildet wird.
Genau, aber das Schöne ist halt, wenn man halt mit solchen Tools vielleicht auch direkt konzeptionell, also auch im Agilen einfach mal, wenn man die Tickets überarbeitet, sagt, hey, wir haben hier dieses Modell und wir arbeiten immer an diesem Modell, dann kann man halt vielleicht über solche Sachen auch schon viel früher stolpern, weil der Kunde dann plötzlich merkt, so ja, Moment mal, oder wenn der Kunde es an seinen Stakeholdern zeigt, also der Kunde an den Stakeholdern zeigt und sagt vielleicht, ja, Moment mal, aber ich arbeite doch die ganze Zeit an einem Pfeil, den es ja gar nicht gibt, da stimmt doch was nicht.
Weil wenn das halt implementiert ist, dann ist es halt für die Non-Techies halt quasi weg. Das ist dann nicht mehr einsehbar. Und als Entwickler, natürlich sollte man das grob verstehen, wie du halt gesagt hast, das System ab einer gewissen hinreichenden Komplexität ist es halt vorbei. Dann kann man nicht mehr alles verstehen.
Dann sind die Sachen hoffentlich irgendwie gekapselt und dann will man auch gar nicht mehr wissen, was da hinten passiert. Vielleicht muss ich das wissen für meine Sache, weil es irgendwas gibt, was halt noch keiner weiß.
Vielleicht nochmal die Definitionsdinge. Finite State Machine.
Deutsch ist endlicher Automat.
Genau, also einen endlichen Automaten kann man quasi auf alles dann abbilden.
Was ist denn mit unendlichen Automaten?
Nein, du kannst damit nicht alles machen.
Also endliche Automaten zum Beispiel, also etwas, was quasi äquivalent ist, sind reguläre Ausdrücke.
Das ist halt auch eigentlich, wobei reguläre Ausdrücke, je nach Implementation, da gibt es auch noch ein bisschen mehr, was man machen kann.
Aber das ist halt, ja, also wenn man endlich einen Automat hat, die Sprachen, die theoretische Informatik, hoffentlich rede ich nicht allzu großen Unsinn, das ist alles schon sehr lange her, aber im Grunde, wenn du endlich einen Automaten hast, dann sind die Sprachen, von denen akzeptiert werden, heißen regulär und deswegen auch reguläre Ausdrücke, weil es halt Ausdrücke sind, mit denen du reguläre Sprachen parsen kannst halt.
aber du kannst damit nicht alles machen.
Zum Beispiel, was du damit nicht machen kannst,
sind halt so, also das
ist immer so Informatik 1
oder bei mir war das glaube ich
tatsächlich Informatik 1 Klausur,
musst du dann beweisen, dass eine bestimmte
Sprache nicht mit einem endlichen Automaten
passbar ist. Normalerweise
nimmt man dann irgendwas, wo es so Klammer gibt.
Du hast dann eine Sprache, die halt so Klammern hat,
wo halt, ob du hinten eine Klammer zumachst, davon abhängt,
ob du die vorne aufgemacht hast. Und dann gibt es
dann so ein Pumpkin-Lammern, heißt das.
Das kann man dann benutzen, um zu zeigen,
dass man
in keinem endlichen Automaten das parsen kann,
weil man sich nicht merken kann,
wie das...
Dafür braucht man dann halt so einen Stack-Automaten
oder irgendwie sowas.
Was ist ein Stack-Automat?
Wie gesagt, ich kenne keine theoretische Informatik.
Was ist ein Stack-Automat?
Ja, so ein Ding, was halt einen Speicher hat.
Also einfach noch tatsächlich einen Stapel, den es gibt.
Okay.
Warum ist das Ding Automat?
Ja, ich weiß gar nicht, ob das Stapelmaschine
vielleicht auch, ich weiß es nicht genau, ich weiß gar nicht, ob das Automat heißt.
Also alles, was halt dann ein unendlicher Automat quasi ist,
das hat halt dann States, die du vorher nicht kennst oder sowas.
Oder worum geht es da, dass du das nicht vorher wegdefinieren kannst?
Nein, du musst dir halt sozusagen merken, was passiert ist.
Das kannst du im eigentlichen Automaten nicht machen.
Da hast du halt Zustände, die sind endlich und du kannst zwischen denen wechseln.
Aber du kannst dir jetzt nicht merken, wo du schon überlang gelaufen bist oder so.
Oder ob du Klammern aufgemacht hast oder nicht.
Das geht halt nicht.
Und genau, das nächste, also
gehen wir mal die Dinger durch
bei der theoretischen Informatik.
Das zweite ist halt dann sozusagen Stackmaschinen.
Damit kannst du halt dann kontextfrei Grammatiken
parsen und dann gibt es halt noch
Kontextsensitiv. Dafür brauchst du dann schon
Loop-Rechenbar oder
sowas und dann irgendwie gibt es noch
irgendwie alles
irgendwie und
dafür brauchst du dann Turing-Maschinen. Oder halt
ein While-Programm oder ein Vorprogramm oder was auch immer.
Okay, also nochmal jetzt vielleicht
zum Abschließen, was eine Turing-Maschine ist.
Oh Gott, eine Turing-Maschine, ein Siebentuppel aus Sprache, Grammatik, Terminalsymbolen, Nicht-Terminalsymbolen, keine Ahnung, weiß ich nicht, Alphabet.
Ja, also im Grunde das Ding, was halt sozusagen die Informatik als Fach irgendwie so ein bisschen begründet hat damals, 1937, gab es das Paper, glaube ich.
Von Neumann-Architektur?
Nein, nein, nein.
Nein, nein, nein, du weißt was anderes.
Das war ganz anders.
Was ist das?
Das ist, von all meinen Architekturen ist das halt Hauptspeicher, also dass der Speicher für Daten und Programme der gleiche ist, mehr oder weniger. Aber das ist halt wie eine Rechnerarchitektur, aber das ist halt Hardware, das ist Turing-Maschine, das ist ein theoretisches Konstrukt.
Wie gesagt, das hat Turing da
1930 veröffentlicht.
Ich glaube, das Paper hieß
On Computable
Numbers with an Application to the
Entscheidungsproblem oder sowas.
Da hat er das Ding halt vorgestellt
und in dem Paper bewiesen, dass
das Problem
nicht entscheidbar ist.
Also ja, und genau.
Das hat eigentlich die Informatik begründet.
Beziehungsweise
es gibt da halt noch irgendwie
ein Paper zu Lambda-Kalkulus
von Church. Das ist ein bisschen später rausgekommen.
Das ist eigentlich ein Stückchen eleganter, aber
ja.
Ja.
Aber genau, also das
Typ 0 Sprachen,
also mit der Turing-Maschine kannst du halt
alles parsen, was du auch parsen kannst.
Und mit einem regulären, also mit
einem regulären
Automaten, also
mit einem endlichen Automaten halt nicht, sondern nur
ganz spezielle Sachen. Aber
trotzdem kannst du wahrscheinlich eine Menge damit abbilden.
Ja, ich meine, so ist es nicht.
Ja, vor allem in meinem Case ging es ja wirklich auch tatsächlich um Business Flows.
Ja.
Und ich glaube, das Interessante an Business Flows ist, weil das halt wirklich eine Sache ist, man muss ja dann im Endeffekt die gelebte Realität von dem Kunden oder von demjenigen, für den man das baut, muss man ja halt wirklich eins zu eins spiegeln, ohne dass man wirklich genau weiß, was die da eigentlich tun.
Also wenn man jetzt, keine Ahnung, wenn es darum geht, verschicke E-Mails, dann ist das Ergebnis wichtig. Aber bei der Geschäftslogik, beim Geschäftsmodell, muss man tatsächlich das nachbauen. Also da kommt irgendwas daher, da werden irgendwie Daten reingegeben, dann wird mit den Daten irgendwas gemacht, dann wandert das irgendwo weiter hin.
Und das ist, glaube ich, so der spannende Punkt, warum da halt zum Beispiel, ich meine, es gibt doch bestimmt noch 50 andere schlaue Ideen, wie man da umgehen kann, aber halt damit mit diesen endlichen Automaten halt schon mehr Struktur reinbringen kann.
Ich glaube, wenn man das halt auch von Anfang an sich für irgendwas entscheidet und nicht halt sagt, wir machen das halt, wie ich halt den ganzen normalen Code programmieren würde, glaube ich, da kann man sich sehr viel Knater sparen und hat bestimmt zwei, drei Jahre Entwicklungszeit Entspannung vom, also quasi ein bisschen Schutz vor tiefgreifendem Refactoring.
Ja, nee, klar, also es ist ...
Um Refactoring zu vermeiden, aber das wäre jetzt aber auch nur Refactoring vermeiden, was quasi Bugs entfernt und die Features sicherer macht.
Aber das wäre jetzt nicht das Refactoring, was keinen Style schöner macht, Namenskonventionen besser einhält, dokumentierbarer macht.
Ja, okay, stimmt, das ist natürlich auch eine Art von Refactoring, ja.
Ja, man kann auch quasi irgendwas, also wenn man das übergibt, also wenn ich jetzt selber was geschrieben habe, was ich mich gut mit auskenne, ist es ja was anderes, als wenn jetzt jemand anders das benutzen muss.
Und wenn man halt seinen Krug in einen Zustand versetzt, in der er halt irgendwie auch gut übergiebbar ist, dass halt jeder damit arbeiten kann.
Ja, wobei man da ein bisschen vorsichtig sein muss. Ich meine, da geht es dann quasi um, würde ich mal sagen, Konsistenz.
Und da ist leider, also meine persönliche Ansicht dazu ist, konsistent ist es dann so, ist es dann, wenn es mir gefällt.
Taste kann man nicht schreiten.
Aber das Problem ist halt,
das habe ich ja auch mit...
Wenn man seinen eigenen Code anguckt,
der einem selber nicht mehr gefällt.
Ja, aber wenn man so in Codebasen guckt,
die es da so gibt
und sich denkt so,
oh, das ist alles ganz schrecklich,
dann habe ich so den,
dann zuerst fängt das Augenlid an zu zucken
und dann irgendwann lasse ich Black
über alles drüber laufen.
Ja, ich kenne das aber auch von Jochen,
das ist immer ganz super.
Also er hat ja immer netterweise
ein paar Sachen von mir mal korrigiert und so.
Und ganz am Anfang war es so,
äh, was ist das denn?
Das geht ja überhaupt nicht.
Alles wegschmeißen, neu machen.
Nee, nee, kann man nichts mehr retten.
wieder angefangen, neu gemacht und das ging dann so ein paar
Mal, wieder wegschmeißen, nochmal weg. Und dann irgendwann
hat er gesagt, ah, was ist denn das?
Ja, das habe ich von dir kopiert.
Ja, das mag sein, dass das
vorkommt.
Manchmal ist es auch einfach Quatsch.
Da hat man sich so dran gewöhnt, dass irgendwie
und dann macht man hinterher
irgendwas dann falsch, wenn man
davon ausgeht, dass es sowieso irgendwie nicht richtig ist.
Man muss aufpassen, das ist nicht so einfach.
Aber genau, also
Also ja, ich tendiere dazu, das dann so zu machen.
Ich glaube aber, es ist falsch.
Ich glaube es ist, und eben auch da das Buch würde sagen,
ja, Konsistenz wichtiger, weil es halt für Leute wichtiger ist,
das zu verstehen und dass es genauso ist, wie sie das halt kennen,
als dass es richtig ist.
Weil richtig ist halt kein guter Wert quasi.
Oder es senkt halt nicht die Komplexität.
Also es kommt darauf an.
Also ich meine, es gibt natürlich Situationen, in denen es so schlimm ist,
da muss man halt was machen.
Aber wenn es
jetzt sozusagen nur unschön
ist, aber halt in sich konsistent, dann ist
es wahrscheinlich besser, das so zu lassen,
weil es senkt halt
nicht, also die Konsistenz
zu brechen, erhöht halt die Komplexität
ganz sicher, während
das anders zu machen
verringert die Komplexität vielleicht ein bisschen,
aber wahrscheinlich
gleicht das nicht das aus, dass man das dann halt
inkonsistent gemacht hat und damit dann komplexer.
Also, ja, es ist blöd.
Das ist ja generell auch ein Problem,
dass wenn man jetzt ein altes, gewachsenes Projekt hat,
das man dann vielleicht im schlimmsten Fall übernimmt,
aber vielleicht auch, wo man halt auch schon selber lange dran arbeitet
und irgendwann kommt dann jetzt der Impuls,
wir müssen da jetzt mal irgendwie anfangen, Sachen besser zu machen,
das geht so nicht mehr weiter.
Und da ist dann ja auch bei vielen motivierten Entwicklern,
wie das bei mir früher auch so war,
man geht dann und sagt, okay, machen wir irgendwie so gefühlt alles neu.
Und dann fängt man irgendwie sieben Baustellen an
und das klappt halt einfach nicht.
Also ich glaube, die größte Kunst,
wenn man wirklich so ein altes Projekt retten möchte,
ist wirklich
sich zu überlegen, wie kriege ich
die Patterns, die ich möchte,
unter den Nebenbedingungen meines
Projektes, ohne dass ich quasi alles anzünden
muss und ...
Oh oh, lieber die Finger vorn lassen,
das ist zu viel. Also ich habe tatsächlich
mal jahrelang auf einem
wirklich komplett von der grünen Wiese
gewachsenen Plain-PHP-Projekt gearbeitet.
Das war halt einfach, das war vorne und hinten
eine Katastrophe. Also die Code-Basis war
wirklich, wirklich schlimm. Da gab es nie irgendjemand,
der drüber geguckt hat. Das waren alles,
im Endeffekt alles von Freelancern gebaut, die, genau wie
du es gerade gesagt hast, halt die dafür bezahlt wurden,
möglichst schnelle Feature abzuliefern und dann nach mir
die Sintflut. Böse, ich meine, nicht bei
allen, aber es gab auf jeden Fall Leute und wenn du halt
einen so im Team hast, dann ist halt schwierig.
Ich habe einen Freund,
einen Entwickler aus Malawi, der halt so
versucht, günstige Aufträge ranzubekommen und
weil die Kunden, die er hat, dann relativ wenig Budget
haben und immer ausgeben, merkt man halt auch, welche
Entwickler sich halt dann leisten können und
wenn er halt dann so sieht, so die Leute, die
von denen er das aufräumen
muss, dass wenn er selber nicht weiß, worum es geht und die haben dann teilweise
Panda selbst implementiert, weil sie nicht wussten, was das dann gab
und hat so Sachen selber geschrieben und
vorne auseinanderfallen, unheimlich viel Spaghetti-Zeug
und das dann neu zu machen.
Also die Arbeit, die hat, er ist
die ganze Zeit am Limit und weiß überhaupt nicht, was da passiert.
Das ist unheimlich schwierig, das besser zu machen
und das zu refactoren, aber ich glaube, da ist dann
gotische Knoten besser gelöst, indem man
manchmal tatsächlich dann durchschneidet
oder halt einfach verbrannte Erde hinterlässt und das
neu anfängt oder so. Also es gibt es
auf jeden Fall, aber
es ist ja leider, zum Beispiel
bei vielen Firmen, die so vor
vor, weiß ich nicht, 10 Jahren, 15 Jahren
angefangen haben und einfach ihr Geschäftsmittel
irgendwie implementiert haben. Da wurde ja die
meistens, oder vor allem auch so Frühzeiten des Web,
da sind ja einfach sehr, sehr viele schlimme Dinge
passiert. Da gab es auch teilweise noch keine
Frameworks, das waren Leute, die dann
nicht so richtig wussten, was sie da tun.
Und
das Problem ist aber, dass halt, weil
halt auch da in der Firma dann nie jemand ist, der dann wirklich
da versucht, das
kontinuierlich besser zu machen. Dann kommt halt irgendwann,
okay, es geht nicht mehr, ja, weiß ich nicht,
ein Formular anpassen dauert eine Woche,
wir müssen irgendwas machen.
Und das ist halt dann, dass diese Firmen dann halt
in so einem Deadlock sind, dass die halt nicht das Budget
haben, diese riesige gewachsene Software mit
28.000 Sonderfällen neu implementieren
zu können, aber es geht auch nicht weiter.
Und das ist halt genau der Fall und ich glaube, das ist ein sehr
häufiger Fall, insbesondere
wenn das halt so eine Software ist, die halt wirklich
in-house dann für sich selbst entwickelt wurde,
dass man da, da ist
super wichtig, dass man reflektiert, das ist super wichtig, dass
man, also vor allem, ich finde in solchen Fällen
das Einzige, was einen irgendwie motivieren kann, an diesem
Projekt zu arbeiten, dass man halt versucht, die
Herausforderung halt anzunehmen und das irgendwie besser zu
machen kontinuierlich. Und da ist es halt einfach
super wichtig, dass man sich Patterns überlegt. Also beispielsweise
bei diesem alten Plain PHP Ding
war halt auch, das war halt einfach
eine Kette von Skripten, die eingebunden
wurden. Eine N-lange Liste.
Niemand wusste genau, was da oben
kommt und was unten kommt. Du hattest keinen Variablen
Scope. Also das kann man sich nicht vorstellen, was das
für ein Segen ist, dass man einen Variablen
Scope hat. Und im Endeffekt
habe ich dann, das war das, wo ich
dann so mich am meisten darüber gefreut habe,
dass es funktioniert hat. Ich habe mir im Endeffekt
Django Class-Based Views in klein nachgebaut
und es war ein Segen. Und es war
im Endeffekt, das halt einmal zu bauen,
also mir im Endeffekt grob abzugucken und dann
halt ein bisschen fein zu schleifen, war ich in zwei, drei Tagen
durch. Das war jetzt echt nicht viel Arbeit.
Jedes Mal, wenn ich halt an irgendeinem View
dran war, also View in Gänsefüßchen,
letzte Skript der Reihe,
habe ich halt dann einfach, okay,
jetzt stelle ich das einfach oben. Habe ich dann mit dem Kunden noch
abgesprochen, das hat dann auch meistens nicht rasend
viel, weil es meistens nur einsortieren war. Ich habe gar nicht
zum Code wirklich gemacht, aber da ich das dann
plötzlich Scope hatte, konnte auch die IDE
plötzlich mit Variablen arbeiten, hat einem
plötzlich zum Beispiel gesagt, ey, da sind ganz viele, da ist ein
ganzer, weiß ich nicht, 100-Zeilen-Zweig in diesem
Dings, die Variable wird gar nicht gesetzt,
die kommt nirgendwo her, das gibt's
gar nicht, das kann man einfach rauswerfen, ja, also
das war im Endeffekt mehr oder weniger eine
Kleinigkeit und das war
so ein Gewinn für dieses Projekt,
weil, wie gesagt, man wusste
was diese Views, man hat angefangen, man konnte,
man wusste auch erst mal, wie ich überhaupt anfangen soll, aufzuräumen,
ja.
Ja, so unterschiedlich ist die, ne, ich hab
da gehört. Also es gibt Leute auf der Welt,
programmieren unterschiedlich.
Zum Beispiel, ich habe jetzt von einem Freund gehört, der
mit Ukrainen relativ viel zu tun hat,
also wirklich, die dann lange Jahre schon
so Auftragsarbeit machen für europäische Kunden
oder sowas und die sich jetzt halt
auf internationalen Vergleich da irgendwie gucken,
wie das dann so aussieht. Und da gibt es Firmen aus
anderen Teilen der Welt, irgendwo aus Asien oder sowas,
die entweder nur genau das machen, was sie aufgeschrieben haben
und halt nur genau
Definition, das heißt, du brauchst ultra lange, wenn du
mit dem zusammenarbeitest, um diese Definition aufzuschreiben,
weil alles, was da nicht drin steht, das wird
halt nicht gemacht. Das ist halt blöd.
Oder die halt
diese Abstraktions-Levels nicht benutzen.
Auch vor allem aus dem anderen asiatischen
Raum, wo du halt dann da stehst und
anstatt, dass du so einen Pattern
jetzt halt hast und eine abstrakte Klasse,
dass du schreibst, werden halt alle
100 einzelne Möglichkeiten
einzeln implementiert. Und dann so, ja, kommen ja
noch weitere, ja, 900 dazu,
vielleicht wäre ein Abstraktionsniveau sinnvoll.
Nur, nur, die 900 machen wir dann auch ganz schnell.
So halt.
das ist halt dann schwierig. Also wenn man das halt dann refactored,
dann ist halt unheimlich viel Fleißarbeit auch dann.
Wie man das irgendwie dann versucht
zu modulisieren, auseinanderziehen.
Ist Refactoring auseinanderziehen
oder Extraktion? Ich weiß nicht.
Ich glaube, es sind halt viele Facetten,
oder? Ja. Ist auf jeden Fall eine davon.
Ja. Ich würde sagen,
eben, das ist halt, letztlich sollte es halt
dazu führen, dass die Komplexität vom Gesamtsystem
geringer wird. Und wenn du halt,
dann ist halt die Frage, was ist Komplexität
eigentlich? Ja, don't repeat yourself vielleicht auch.
Genau, wenn du das jetzt so implementierst, also nehmen wir diesen Fall, du machst halt nicht eine generelle Lösung für irgendwas, sondern du hast halt dann 900 Spezialfälle, dann sieht das ja erstmal gar nicht so schlimm aus, aber tatsächlich, wenn du jetzt etwas hast, was all diese Fälle betrifft, quasi etwas, was du zum Beispiel immer tun musst, dann musst du die alle anfassen.
Das heißt, du hast eine Abhängigkeit
zwischen allen,
die nicht sichtbar ist.
Wir sind schon wieder bei Sennoff Heißen
und können jetzt hier die Liste wieder runterbieten.
Das Beispiel hier
in dem Buch ist sozusagen, wenn du eine Webseite
mit ein paar tausend Seiten hast und du hast
halt irgendwo einen Banner da drin, das halt
eine Hintergrundfarbe hat und
du hast die jetzt halt einfach von Hand
gesetzt in allen Seiten.
Dann hast du halt eine
implizite Abhängigkeit zwischen allen Seiten,
weil du kannst diese Farbe nicht mehr ändern,
ohne alle anderen Sachen anzufassen.
Besser ist es halt,
nur eine Abhängigkeit zu haben zu einem
Modul irgendwie, wo du
diese Farbe setzen kannst.
Und dann hast du eine explizite
Abhängigkeit, das heißt, du siehst auch, dass es die gibt
und du kannst es an einer Stelle ändern
und dann ist es halt für alle geändert.
Das wäre ein Refactoring quasi.
Es gibt ja so Sprachen, wo das nicht ging,
zum Beispiel mit Variablen setzen oder so was.
Also in HTML oder alten CSS oder so was
waren Variablen ja nicht so einfach zu setzen.
Keine Ahnung, ich weiß aber auch noch nichts über CSS.
Das war zum Beispiel dann ein Problem,
wenn du quasi eine
Variable, also eine Farbe
gesetzt hattest, auf eine Farbe, die es schon gab.
Von zwei verschiedenen Komponenten.
Weil, wie willst
du denn jetzt, also das sind, ich weiß nicht, ein paar hundert
Stellen, wo das auftaucht und die Farbe ist aber immer dieselbe.
Wie kriegst du denn jetzt raus, was dann war jetzt vorher
der Hintergrund 2, was war der Hintergrund 1 oder so?
Solche Dinge,
das ist halt ziemlich hässlich.
Ja.
Aber genau, also ja,
Das Buch sagt dazu, wo kommt diese Komplexität
eigentlich her und wie kriegt man sie klein?
Es gibt eigentlich im Grunde nur zwei Quellen von
Komplexität. Das eine ist halt solche
Abhängigkeiten.
Und das ist halt,
wenn man viel davon hat, ist halt doof, weil
das bedeutet halt, wenn du etwas änderst,
musst du viele andere Sachen, die von allen Abhängigkeiten
ja auch anfassen.
Und die zweite Geschichte ist
Obscurity.
Ich weiß gar nicht, wie man das am besten übersetzt.
Undurchsichtigkeit.
Undurchsichtigkeit, ja.
Nebel. Obskurität,
ja, ich weiß nicht, genau.
Unklarheit, Unklarheit vielleicht, ich weiß
nicht, naja. Jedenfalls, das ist halt,
das passiert,
also, und das sorgt halt für noch schlimmere
Probleme, das sorgt für so
Unknown-Unknowns, dass du halt
gar nicht, also wenn du viele Abhängigkeiten
hast, ja, nehmen wir an,
du hast halt irgendwie, du weißt
halt, wenn du das jetzt änderst, dann musst du das an 100 Stellen
auch noch anfassen, ja, dann weißt du halt so, oh mein Gott,
das dauert jetzt lang. Aber was
dann diese 100 Stellen eigentlich alles machen, das weißt du halt
nicht vielleicht. Ja, aber wenn du
genau, zum Beispiel, nehmen wir an, du hast jetzt
diese eine Abhängigkeit, die sagt, wenn
du die Hintergrundfarbe von diesem Banner ändern willst, dann
machst du das hier. Und jetzt hast du aber
in 10 Dingern, hast du es halt von Hand
überschrieben. Aber das
weißt du halt nicht mehr, das ist nicht dokumentiert.
Dann, das sind halt diese Sachen,
wo dir dann hinterher auffällt, dass
ein Kunde sagt dann halt irgendwann so,
oh, da stimmt aber die Farbe nicht. Wir hatten das
doch geändert. Wieso ist denn die jetzt da an der Stelle falsch?
Und dann kriegst du das sozusagen
als Bugs wieder zurück,
was du nicht wusstest, dass es
diese Abhängigkeit gibt, aber die
war halt nicht so gut.
dokumentiert. Ja, und dann
das sind die Schlimmsten, weil
das Problem ist halt,
du weißt halt gar nicht, dass du das
eigentlich hättest machen sollen.
Ja, was implizit dann tatsächlich einem nicht auf die Füße fällt.
Ja, und dann ist halt
die Frage, wo kommt das her und wie kriegt man das
verhindert? Und oft ist es halt vielleicht Dokumentation.
Das ist auch etwas, das
fand ich nett,
dieses Buch hat meine Einstellung zu
Kommentaren und Dokumentationen so ein bisschen verändert.
Jochen schreibt übrigens nie Dokumentation.
Nein, das wäre nie
wäre zu hart, nein.
Ja, der Code erklärt sich selbst und so.
Ja, okay.
Aber tatsächlich, ich würde auch sagen, also ja,
ich meine, es gibt ja da unterschiedliche Ansichten zu, eine
auch verbreitete, jetzt wenn man mal
so Clean Code nimmt, auch ein Buch, was sich ja mit solchen
Themen beschäftigt, von Robert
Martin, Uncle Bob genannt,
der sagt ja immer, ja, so
wenn du einen Kommentar schreibst, gut,
manchmal lässt sich das nicht vermeiden, musst du halt machen oder
manchmal musst du halt, aber sei dir
bewusst, wenn du das tust, das ist im Grunde ein Fehler,
es ist im Grunde ein Versagen.
Du hast versagt. Weil,
wenn du es richtig gemacht hättest, dann hättest du es
so hingeschrieben, dass man das nicht hätte kommentieren müssen.
Ein paar Kommentare sind
natürlich blöd, weil man muss sie halt aktualisieren und anpassen,
wenn man sie... Ja, du hast halt eine mögliche
Inkonsistenz auch erzeugt. Ja, genau. Das ist schon doof.
Also man muss halt echt schon aufpassen. Aber
es ist einfach an vielen Stellen sehr, sehr hilfreich,
auch gerade, wenn man kollaborativ arbeitet,
einmal kurz hinzuschreiben, was denn da passiert,
warum denn da irgendwas passiert. Ja, absolut.
Anstatt das halt einfach
nicht zu machen, weil dann die Leute fragen sich,
Da wird irgendwo schon abgerufen, warum.
Oder so, sei es, wenn der Name toll ist und so.
Ja, absolut.
Ja, ja.
Ja, ich muss auch sagen,
also genau, dieses Buch hier nimmt das auch relativ detailliert auseinander.
Und da sagt er halt so Sachen wie,
ja gut, selbst wenn der Code selbst dokumentierend ist,
dann einmal, du kriegst das Problem,
die Variablen und die Funktionsnamen werden handelang.
Du hast das Problem, du schreibst dann,
wenn das die Dokumentation von deinem Ding ist,
dann schreibst du die ja an jede Stelle, wo du die verwendest.
Das ist ja auch Quatsch. Das sollte man ja nicht, also
das ist ja auch irgendwie offensichtlich Quatsch. Das kann ja
nicht sein. So, das sollte ja reichen, wenn man
das an einer Stelle schreibt und dann
ja, und
hat halt noch so viele, viele Punkte
und aber der allerwichtigste
Punkt eigentlich, wo ich dann auch gedacht habe, okay, ich
glaube, ich muss meine Einstellung dazu überdenken und vielleicht mal
anders probieren und mal gucken, vielleicht funktioniert es dann ja anders
besser, ist
ja, also eigentlich
das, was dein Code tut,
ist eigentlich, oder das
das Entscheidende beim Design
von so einem System ist eigentlich nicht so
sehr, der Code ist eigentlich gar nicht das
Entscheidende, weil der Code ist halt die Implementation davon,
aber das ist halt...
Magie, Call, Call, Magie,
Call, Magie, Call, Magie, aber was dabei
rauskommt, ist wichtig.
Die Abstraktionen sind wichtig und die stehen aber,
Code ist möglicherweise gar keine so gute
Art, um das, um diese
Abstraktionen sichtbar zu machen oder
irgendwie zu dokumentieren.
Also natürliche Sprache ist dafür deutlich
besser geeignet und man
Eigentlich sollte man sich Gedanken über die Abstraktionen machen.
Dann schreibt man in natürlicher Sprache hin.
Und wie man das dann implementiert, ist ja nochmal eine andere Sache.
Ja, das ist sehr schön.
Weil bei Python, finde ich, von meinem Empfinden her,
ich habe natürlich auch keine Ahnung,
aber die Sprache ist, mit der man am nächsten an natürlicher Sprache
schreiben kann, entwickeln kann und dass das irgendwie stimmt.
Bei Sonic, es hört sich für mich irgendwie so ein bisschen mehr nach,
ich schreibe wirklich was dahin, was ich auch so sagen könnte vielleicht.
Also ein bisschen.
Und das ist nicht immer bei allen anderen Sprachen.
Nö.
Eigentlich nie.
Nie.
Ja, naja, es gibt da ganz unterschiedliche Philosophien. Ich finde das sowieso auch interessant. Bei Go zum Beispiel gibt es auch bekannte, ich weiß jetzt nicht mehr, wie der Talk ist, aber einer, der auch die Sprache mitdesignt hat, der ist halt ein Verfechter von kurzen Variablen-Namen-Nehmen.
Ja, aber letztens irgendwann
ein... A, B, C, D und E.
Auf einer Frostcon.
Ja, also...
Ja, also es ist nicht immer gut.
Es gibt auch einen auf der Frostcon,
da hatte ich letztens einen getroffen, der hatte
einen sehr extremen Standpunkt und meinte, das muss mal lang sein.
Kurze Variablen-Namen, schrecklich.
Ganz furchtbar, geht gar nicht.
Das ist schrecklich.
Manchmal ist das schon nett, also gerade wenn man jetzt
komplizierte Logik hat,
dann kann das sein, wenn man lange Variablen
hat, dann stehen einem die Variablen-Namen im Weg,
dann sieht man überhaupt nicht mehr, was passiert.
Das ist ja auch in der Mathematik so, da schreibt man auch eigentlich immer nur ganz kurz Sachen und Formeln so kurz hin.
Das hat halt auch den Vorteil, dass man das dann auch überblicken kann, wenn man das alles ganz detailliert ausschreiben würde.
Was ich dann manchmal mache, an der Stelle tatsächlich vorher die Zuweisung, zum Beispiel ED gleich Data vor irgendwas.
Und dann mache ich dann nicht immer Data vor irgendwas, sondern nur das D.
Irgendwie so, dann wird das so ein bisschen dadurch klar.
Ja, genau. Und da macht das Buch auch einen interessanten Vorschlag und sagt so, ja, also der Name sollte umso länger sein, je weiter weg die Variable quasi von ihrem ursprünglichen Ort, wo sie mal definiert wurde, verwendet wird. Also je weiter das weg ist, desto eher musst du halt einen langen Namen nehmen oder desto länger muss der Name sein.
Aber je näher du da dran bist,
dann
kannst du auch kürzere Namen nehmen
oder sehr kurze.
Weil
dann ja immer noch alles im Blick ist.
Du siehst halt, was da passiert
irgendwie sofort.
Also Readability Counts, das ist ja auch wieder
so eine Sache, außer auf Python.
Naja, also
ja, das ist schon faszinierend.
Genau, aber auch so was
Obscurity kommt halt auch,
da ist auch ein sehr schönes Beispiel beschrieben,
wo Variable-Namen
an böse, böse
Überraschungen bescheren können.
Also der Autor von dem Buch,
der hat TCL mal diese Scripting-Language
geschrieben, also diese Sprache designt.
Vielleicht kennt man das auch von früher,
da hat man so User-Interfaces
damit gebaut, in Unix
häufig TickleDK, ist das?
Ja, TickleDK gibt's, ja. Genau, das ist
die Python-Geschichte, mit Python kann man das
auch machen, das ist die einzige UI-Geschichte,
die in der Standard-Bibliothek drin ist.
Und der hat aber noch diverse andere,
der hat zum Beispiel ein Cloud-Dings gebaut,
ein quasi verteiltes Betriebssystem
und ganz viele coole, interessante Dinge.
Und in diesem Dings gab es ein Fallsystem auch
und in der Fallsystem-Implementation gab es irgendwie eine Variable,
die hieß Block.
Und da hatten sie einen ganz fiesen Bug,
wo sie irgendwie Monate gebraucht haben, um den zu finden.
Und der lag dann letztlich daran,
Und das ist dann halt eben das, was dann diese Obscurity tatsächlich so schlimm macht.
Der lag daran, dass sie Block subtil unterschiedlich in der Bedeutung verwendet haben.
Also sie haben Block als Variablen-Namen benutzt, aber in dem einen Fall bedeutete er etwas leicht anderes als in dem anderen Fall.
Und wenn du das liest, dann sieht es aber so aus, als ob das irgendwie das Gleiche ist.
Aber wenn du es dann halt verwendest, so als wäre es das Gleiche, dann hast du halt einen subtilen Fehler gemacht.
in ganz obskuren Fällen
hat das dann halt irgendwie mal
irgendwie zusätzliche Daten in irgendwie
Files reingeschrieben oder so, weil irgendwas nicht richtig
allein war oder so. Ganz Horror
Bugs.
Ja, ja, irgendwie so Magie, die passiert im Dunkeln, aber
schwarze Magie macht irgendwas kaputt und du weißt
nicht genau was.
Ja, ja, schwierig. Und das
halt dann, ja, das lag halt einfach daran, dass
der Variablename halt
zu generisch war. Also sie können halt zu generisch
sein, sie können halt aber auch zu speziell sein.
Also ich meine irgendwie, keine Ahnung,
der Java-File-Input-Buffer-Stream-Schlag-mich-tot-Reader
ist halt auch irgendwie dann nicht mehr so der Sinn.
Das ist auch nicht so schön.
Ja, aber das ist vielleicht ein Geschmacksfall,
vielleicht auch anwendungsfrei spezifisch.
Ich glaube, eine Sache, die man ganz generell festhalten kann,
ist, wenn man irgendwas refactoren möchte,
also jetzt nochmal ganz generell gesprochen ist,
dass einem der Unit-Tests oder funktionale Tests
oder was auch immer für Tests sehr, sehr helfen können.
Und nicht nur, dass man quasi das, was man refactored hat, dass man das vernünftig testet, das sollte eh klar sein, sondern wenn es hinreichend kompliziert ist, dass man auch einfach mal Test schreibt für den Bestandscode, dass man einfach sicher sein kann, was macht das eigentlich und dass sich das nicht verändert hat.
Ich habe letztens, ich weiß nicht, ob das mit euch war, ob ich mit euch darüber gesprochen habe, mit dieser Oracle-Implementierung, wo die dann auch gesagt haben, das Ding war irgendwie dermaßen alt und verbuggt, dass die dann quasi alles komplett mit Unitests zementiert haben. Also jeden Bug und jedes merkwürdige Verhalten, das das System hatte, haben die mit Unitests zementiert. Die haben irgendwie ein Jahr lang, glaube ich, nichts anderes gemacht.
Und dann haben die angefangen, das zu refactoren, weil die halt einfach Angst hatten, weil also teilweise war es wohl auch so in der Community, dass die Leute halt auch auf diesen merkwürdigen Verhalten oder Bugs, wie man es halt nennen möchte, halt aufgebaut haben und Features draufgesetzt haben.
Und die konnten das den Leuten nicht einfach wegnehmen, weil dann halt irgendwie ganz viele Sachen zerbrochen wären, weil das halt irgendwie so Teil der impliziten API gewesen ist und sowas.
Und das kann tatsächlich auch helfen.
Also ich habe das jetzt einmal gemacht, als ich jetzt ein größeres Teil angefangen habe zu refactoren, also einfach Tests für den Bestandscode zu schreiben.
Das macht keinen Spaß.
Ja, aber das mit den Tests ist auch ein gutes Stichwort.
Das ist halt auch so, also natürlich, es gehört, dass man Sachen testet und das ist auch auf jeden Fall super.
Also das ist eine der Dinge, die viel gebracht haben.
Auf der anderen Seite, muss ich sagen, Test Driven Development, weiß ich nicht so genau.
Da würde mich jetzt doch nochmal allmählich interessieren,
ob es wirklich Leute gibt, die das so durchziehen
und die das gut finden.
Vielleicht müssen wir mal jemanden suchen.
Es kommt drauf an, wenn man es selber schreibt
und wenn man weiß, was man tut.
Wenn man halt
tatsächlich weiß, was man raushaben will, dann schreibt man
einen Test, der das quasi,
die Logik, die man implementiert, die zwei Methoden, quasi
mit einem Testcase so
das Ergebnis hat. Also zum Beispiel
du hast halt einen Datensatz und
du kennst das Ergebnis, das heißt, du machst einen Beispiel-Datensatz
und am Ende weißt du, das Ergebnis kommt raus
und dann weißt du ja quasi schon
implizit in der Stelle wahrscheinlich
oder explizit so ein bisschen, also du kannst
auch hinschreiben in
Logik, wie das
aussehen soll, was muss passieren, damit das passiert,
dass das stimmt und dann kannst du den Methoden schon die
richtigen Namen geben, die du dann irgendwie füllen musst,
die am Ende rauskommen sollen,
wenn das jetzt nicht zu komplex ist und dann kannst
du das implementieren und dann, wenn das für
dein Testcase stimmt, wirst du ziemlich sicher sein, dass das
auch für die anderen Fälle laufen
sollte.
Ja, aber ...
Und wenn du das halt so machst, das ist halt so ein TDD-Fall,
wo ich sagen würde, das kann dann ganz gut sein.
Du kennst quasi einen Testfall.
Wenn du genau weißt, was passieren soll.
Genau, du kennst den Testfall.
Du weißt den Testcase, den kennst du schon.
Du weißt, okay, das sind meine Testdaten
und du weißt, das Ergebnis von dem Test ist so.
Und dann kannst du dafür dann eine Methode schreiben,
die diesen Testfall richtig macht.
Und wenn du quasi alle Testcases hast,
dann ist dein Code schon richtig.
Und das ist ein cooler Fall, wo man das machen kann,
wo man dann halt für generische Fälle
Code hat, der funktioniert und wo TDD Sinn macht.
Wenn du es aber nicht hast, weil du nicht weißt, ob die Testcase
vollständig sind, ob du irgendwelche Edge-Cases hast oder so was,
dann ist es halt super nervig, weil dann
muss ich Testhausen mal umbauen, irgendwas wegmocken.
Aber das ist ja auch Teil des Prozesses,
dass du halt die Tests auch ständig anpasst.
Ja, genau. Also ich glaube,
ich glaube, TDD, der größte
Vorteil davon ist einfach,
dass man erstens Code so schreibt,
dass er testbar ist, weil das
habe ich früher auch nicht so gemacht. Wenn man keine Unitest
schreibt, dann schreibt man Code anders.
Und das ist schlechterer Code.
Das ist einfach eine generelle, richtige Aussage.
Und das Zweite ist,
du wirst, du kommst, wenn dann plötzlich
der PO oder irgendwer Stress macht, dann lässt
man die Tests nicht weg, weil die sind schon da.
Ich glaube, das sind die beiden Hauptverkaufsargumente
dafür.
Ja, du kannst halt keinen ungetesteten Code
schreiben. Das ist halt irgendwie natürlich so ein bisschen,
das ist halt schon vielleicht gut.
Aber eben,
das gab es auch in der letzten Django-Chat-EP
so, ich weiß nicht, letzte, vorletzte,
keine Ahnung, da gab es auch, ging es auch
um das Thema Test-Development und auch alle
da meinten so, ja, ganz gut,
ist eigentlich vielleicht nicht so schlecht, aber
der Konsens in der Runde war halt auch so,
naja, so wirklich machen, macht das dann doch keiner.
Und auch mit dem Argument
und das,
was wir, glaube ich, auch schon mal gemacht haben, dass halt
das Problem ist, wenn man
jetzt, wenn klar ist, was zu tun ist,
dann ist das vielleicht machbar, aber
ich hatte auch heute wieder so einen Fall, wenn man nicht
weiß, was man machen will, dann ist das
ganz blöd, weil
das hilft einem überhaupt nicht, dass man
dann mit dem Text Test anfängt, weil man muss sowieso
irgendwie rumprobieren und das dann
in einem Test zu machen, macht irgendwie nicht so viel Sinn.
Das Buch
macht da auch einen interessanten
Punkt und sagt halt, naja, also
wenn du Test
development machst, dann zwingt
dich im Grunde das
das Vorgehen,
dir von Anfang an ganz
viele detaillierte Gedanken
über die Implementation zu machen, an der
Stelle, wo das vielleicht überhaupt nicht
zielführend ist, sondern du willst vielleicht
am Anfang die erstmal Gedanken über das Design oder
Abstraktionen machen und nicht über die Implementierung
und das geht mit Test Driven Development
gar nicht so richtig. Und was
er dann vorschlägt, ist zu sagen, mach doch lieber
Document
oder
Implementierst die Methoden, schreibst den Document dazu,
weil das tut toll und schreibst dann
sondern du schreibst halt nur
in natürlicher Sprache sozusagen, was die
Abstraktionen sind, was die ungefähr machen sollen
und mit denen spielst du so lange rum, bis dir das
Design gefällt und dann fängst
du erst an, das zu implementieren.
ehrlich gesagt, also ich versuche das jetzt,
mal gucken, keine Ahnung. Okay, dann die Tests schreiben
und dann implementieren vielleicht. Ja,
aber genau, also ich weiß
es nicht so genau, ob es wirklich funktioniert, weil ich habe immer so einen
Verdacht, also bei mir ist es oft so, wenn ich irgendwie
ich merke erst beim Rumprobieren
damit und Rumspielen und Umstellen irgendwann
ach, wie das Design eigentlich hätte sein
sollen. Ich finde mir auch so. Ich kann das nicht
gut mir vorher irgendwie,
also, dass ich
mit einem Design, dass ein
gutes Design dabei rauskommen würde, wenn ich nur so
mit abstrakten Geschichten rumspiele,
das ist bei mir irgendwie nicht so.
Man merkt ja auch mal ein paar Mal, wenn man auch das erweitert hat,
also ist auch doch nicht so toll, dann musst du doch nochmal anders
und für sich selber. Oft kommt halt die Idee für das
Design aus der Implementation.
Also dass ich merke so, okay, an der Stelle
mache ich zwei, drei Umstellungen und dann merke ich so, okay,
das ist jetzt alles, jetzt brauche ich gar kein Objekt mehr, das nehme ich da einfach
und dick oder so und dann, oh, dann kann ich das ja so ausdrücken
und dann kann ich so, oh, und jetzt ist das
Design auch klar und
das kommt halt aus dem, mit den
Datenstrukturen rumspielen. Nicht so sehr
aus dem sich abstrakte Gedanken machen.
ich weiß es nicht. Ich probiere es mal aus, mal gucken.
Also es klingt auf jeden Fall ganz interessant und es ist halt
nochmal ein bisschen was anderes als Test-Driven
Development. Und ja, ich glaube
auch, das habe ich bisher einfach unterschätzt und
irgendwie nicht richtig gemacht mit den
Dokumentationen und Kommentaren. Das ist wahrscheinlich
doch deutlich wichtiger, als ich gedacht habe. Da muss ich mal
mehr machen.
Ja, das klingt gut. Also tatsächlich
dokumentierter Code. Sehr zen, sehr zen,
sehr zen auf Weißen.
Ah, ja.
Ja, ich glaube, wir haben bei Refactoring
ich habe nicht mehr so viel auf meinem Zettel,
was ich hätte. Ich kann mal gerade gucken,
ob ich habe, ich habe mir, was habe ich mir denn aufgeschrieben,
was ich dazu noch? Ich muss natürlich sagen, mein
Thyssen kaputt hatte ich am Anfang schon erwähnt, aber das ist nicht so schlimm.
Ja, übrigens, ach so, genau,
ich meine, das ist jetzt
das, was ich mir aufgeschrieben habe,
Red Flag, irgendwie extensive Dokumentation
schreibt er auch, obwohl er eigentlich sagt,
voll gut, er sagt, ja, wenn Leute
viel, viel dokumentieren,
ist auch ein Zeichen für schlechtes Design,
weil das ist ja etwas, was
nicht, ist ja nicht gut, dass man das hat, sondern
Je mehr man dokumentieren muss ...
Man muss viel erklären, ist auch ...
Ja, wenn du viel erklären musst, ist nicht gut.
Eigentlich sollte es offensichtlich sein
und man sollte es mit wenig ...
Ja, so ein oder zwei Sätze am Anfang,
was machen, was behaupten,
dann muss man die ganze Funktion nicht lesen,
wenn das stimmt.
Aber das finde ich auch so eine Sache,
warum ich Type-Ins gut finde.
Jetzt nicht, weil es unbedingt
so die Typensicherheit alles sicherstellt,
aber wenn ich halt den Funktionsnamen lese,
der gut gewählt ist,
die Type-Ins, die dazu passen,
zu den Parametern, die die Funktion hat
und dann den Dockstring,
der idealerweise mir erklärt, was das macht,
dann habe ich ja den Return-Wert,
dann muss ich gar nicht in die Funktion reingucken, um dir alles genau
angucken, sondern ich weiß halt, was sie tut, ah ja, okay,
und kann zum nächsten übergehen. Das ist super,
super schön zum Arbeiten. Ja, das ist dann halt
beispielsweise eine gelungene Abstraktion, wenn du halt
sozusagen der Interface
Dokumentation schon ansehen kannst,
also alles, daraus alles
erfährst, was du brauchst, um das benutzen zu können.
Ja, genau, also du kannst einfach die Docs
skimmen, ja, und kurz gucken, ja, okay, jetzt mach das
und das und das, musst gar nicht so genau den Code hier angucken,
dann ist das auch egal, ob die Leute da so
ordentlich gearbeitet haben irgendwann, ne? Ja.
Ja, absolut.
Ja, ja.
Ich habe jetzt gerade noch mal geguckt, ich habe auch sonst nichts mehr
eigentlich, was ich unbedingt unterbringen wollte.
Nein, bei mir ist auch ab alles untergebracht.
Oh, jetzt sind wir auch, wir sind ja schon relativ
weit dran, wir haben immer viele Leute, die ab dann
abspringen, jetzt kann man
eine Meinung
von Leuten, die sich
die bis hierhin durchgehalten haben,
wäre ganz interessant vielleicht.
Und zwar habe ich, das war letztens
im Stream, hat dann irgendjemand geschrieben, meinte so
ach, es wäre doch voll gut, wenn ihr sowas hättet wie ein Discord
oder so. Wollen wir sowas
haben. Ich meine, wir haben Slack, aber Slack ist
irgendwie, wie hat das jemand dann genannt? Ah, Slack ist ja
eher so ein Boomer-Discord.
Ja. Also Discord habe ich übrigens auch.
Habe ich auch für meine eigenen Zeugs schon
online einmal und so. Also ja,
wir gucken uns den Teller an, aber ist ja kein Problem.
Ja, oder ich meine, welche Plattform
sollte man da verwenden? Discord. Discord,
echt? Ja. Weil, also die Firma
dahinter ist auch so ein bisschen unsympathisch, ne?
Ja. Ja, die machen auch so NFT-Kram
und Krypto...
Dass das sagt jemand, der
Werbung für VPNs macht.
Spoiler, nein, ich weiß nicht.
Ja, es ist alles so ein bisschen,
ich weiß nicht so genau.
Ja, okay, also Discord wäre gut.
Ja, weil ich meine, dann könnten halt auch Leute da
irgendwie mal, man könnte mit Leuten chatten
und so, also könnten Leute live,
wir machen jetzt noch nichts live.
Also Discord würde ich auch
sagen, ist cool.
Was cool an Discord ist,
das nutzen halt alle von früher
und so vom Gaming und so weiter.
Man kann halt super easy da halt irgendwie reingehen.
Man hat halt Video, man hat halt Chat, man hat halt
alles eigentlich, was man so will.
Die Firma kenne ich gar nicht. Du hast irgendwas Böses über die Firma gehört?
Ja, also
es ist halt nicht so, dass man das selber betreiben könnte.
Du bist halt dann abhängig von der Firma, genau wie bei Slack.
Ja gut, du machst halt einen Channel auch für dich.
Ja, ich weiß so ein bisschen, was du meinst.
Also ich würde das natürlich,
mir ist schon sympathisch zum Beispiel auch,
was sie technisch machen. Die haben ja auch irgendwie
da Rekorde
aufgestellt, mit wie viel Clients
an einem Server hängen können, mit Erlangen
und so. Die machen halt
das ist alles schon cool,
aber irgendwie, ja, das ist halt
eine Firma, also ich würde es gerne selber hosten können
oder sowas. Ja, aber diese ganzen Indie-Lösungen,
die es für sowas halt gibt, ich weiß nicht, die sind halt von
der Nutzerbasis, glaube ich, gar nicht so interessant.
Ja, man muss
wahrscheinlich dahin gehen, wo die User sind, ne? Ja, genau.
Hey, wir haben einen Instagram-Count.
Gefällt mir gar nicht, aber gut.
Sind wir doch nicht auf Instagram, schade.
Ja, gefällt mir nicht. Genau, ja,
Dann lass es doch noch auf Facebook.
Nee, aber Discord finde ich ganz okay, es geht.
Also bei mir ist eh immer an.
Ja, gut, okay.
Johannes auch da.
Ja, ich weiß, der hat ja da auch irgendwie
ein eigenes Ding aufgemacht, aber da ist auch gar nicht so wahnsinnig viel los.
Ja, aber das liegt auch ein bisschen daran,
also unter anderem,
dass er das halt auch so wie seine Sachen
benutzt, wie seine Spielfirma.
Ja.
Naja, aber wie auch immer.
Nutzst du auch Discord auf der Arbeit?
Nein. Okay, also ich habe meine eigene
mit Leuten, ich würde da auch mit Kunden drüber sprechen,
also ich finde, das ist so die beste
Teams-Alternative zum Beispiel, wenn ich jetzt
so Kundenprojekte habe, wenn die auf meine Plattform kommen
und ich nicht auf deren muss, dann
die Kommunikation ist irgendwie schöner, professioneller,
sauberer, cleaner irgendwie.
Aber es ist noch wieder
so eine ästhetische Sache und keine Ahnung,
alles kommerzieller.
So besser als Teams zu sein, ist jetzt nicht so
furchtbar schwierig, ehrlich gesagt.
Beispiel, weil wir darüber reden, wo die
User sind und so.
Die sind ja auch schon alle leider da, meistens dann.
Ja, ja, ja.
Wollen wir noch Pics machen?
Stimmt, wir haben noch Pics.
Bonny darf anfangen.
Ich habe mich jetzt motiviert von der letzten DjangoCon
jetzt echt intensiver mal mit HTMX auseinandergesetzt.
Oh ja.
Und das finde ich wirklich sehr, sehr cool.
Ja, dann machen wir auch irgendwann eine Folge.
Das ist tatsächlich toll.
Ich bin ja tatsächlich auch nicht so ein Riesen-JavaScript-Freund.
Und dass diese Karotte quasi kleinseitige Weblogik
ohne JavaScript zu schreiben, ist schon sehr, sehr groß für mich.
Ich habe da letztens noch einen sehr interessanten Vortrag
von dem Macher gehört.
Ich glaube, das war von der ...
Das war Packern US oder so.
Carson Cross heißt der irgendwie.
Ja, genau, genau.
Der hat auch sehr schön erklärt, wie REST eigentlich funktioniert.
Genau, und dass es ja eigentlich darum geht,
HTML-Schnipps hin und her zu schicken
und nicht JSON-APIs zu bauen.
Ja.
Und es ist ein super interessanter Vortrag,
hat mir ein Kollege empfohlen.
Und ich habe mich jetzt damit nochmal beschäftigt, habe heute noch ein kleines Feature damit gebaut.
Ich muss gestehen, ich glaube, ich habe es noch nicht so 100 Prozent, also es tut die Beispiele, die da drin sind, relativ simpel.
Also ich klicke irgendwo, dann tauchst du dich was aus, das ist klar.
Aber wenn man halt so ein bisschen darüber hinausgehen möchte und halt, ja, einfach mal irgendwo Daten schicken oder so, also mal Postdaten schicken, die Patterns habe ich noch nicht so ganz raus.
Ich bin leider nicht ganz ohne jQuery ausgekommen, das hat mich persönlich dann sehr geärgert, weil erstens jQuery und zweitens JavaScript.
Ähm, aber, ähm,
ich glaube, wenn, also die Dokumentation
lässt leider in meinen Augen ein bisschen zu wünschen
übrig und googeln kann man auch nicht, weil
Google immer denkt an mein HTML.
Ähm, das ist beides ein bisschen blöd.
Ja, wie HTTPX ist auch mal doof.
Äh, ja, genau. Und, ähm,
ja, aber ich, ich glaube, wenn,
äh, dass das sehr viel Potenzial hat, das macht auf jeden Fall
sehr viel Spaß, damit zu arbeiten. Ähm,
und im Endeffekt die Idee ist halt einfach, dass man halt
Custom JavaScript Code durch
äh, Custom HTML Tags
ersetzt. Mhm. Und, ähm,
Das ist echt cool. Also ich hab da auch
letztens meine Findings, wie man das mit
Django verheiraten kann,
auch in einem kleinen Artikel zusammengeschrieben.
Das hab ich mir noch nicht angeguckt. Ich weiß nur, dass es gibt. Es gibt ein
Paket von Adam Johnson,
also der mit dem
Was tut das Paket denn?
Tatsächlich sind das eigentlich vier Zeilen Code,
man muss dem CSF beibringen und das war's.
Ah, okay. Also das ist
Django HTMX heißt das Paket, glaube ich.
Ah, okay. Ich weiß gar nicht, was das tut.
Weiß ich auch nicht. Aber das ist auf jeden Fall,
Der Autor ist auf jeden Fall
schon mal ein Hinweis darauf, dass man sich das mal
angucken sollte. Auf jeden Fall, ja.
Und ja,
genau. Ja, muss ich echt mal machen, weil wie gesagt,
ich habe es halt einfach zu Fuß gemacht, weil ich wusste, dass das Paket
existiert und sind, wenn man es halt mal einmal gefunden hat,
das sind literally halt einfach vier Zeilen JavaScript,
die man einbinden muss, dass man halt dem
HTMX quasi den CSF-Token injectet.
Ja, der muss auf jeden Fall in unserer nächsten
Folge hören, da werden wir da auch nochmal drauf eingehen.
Joa. Ja.
Jochen?
Ich weiß nicht so genau, was pücke ich denn
Also ich picke Pendulum.
Ich glaube, das hatte ich schon mal gepickt. Weiß ich nicht.
Ich weiß immer, weil ich kann mir immer nichts merken.
Du musst immer so einfache Sachen picken. Ja, kennst du Pendulum?
Nee. Nein. Das ist eine Date-Time-Parsing-Bibliothek.
Cool. Ja, da kannst du so ein bisschen
einfacher, so ein bisschen schöneres Interface, ein bisschen moderner.
Früher hat man, glaube ich, Maya viel benutzt.
Kennst du, wie es irgendwie ist, als du nicht tot bist oder so?
Und ja, aber da kann man so schöne Sachen machen,
wenn man Date-Times irgendwie machen
möchte, in Time-Zone wechseln und
so zu Strings umbauen und sowas.
Okay, interessant. Ich bin letztens
habe ich, das war, nein,
das war gestern, glaube ich.
Irgendwie so einen kleinen,
da war, das mich mit JavaScript
beschäftigt und Zeit.
Ich wollte eigentlich nichts Kompliziertes machen. Ich wollte zum Beispiel
einfach nur ein Date-Objekt einfach darstellen.
Ja. Und
das war
ganz schrecklich. Also
Pendulum ist für Python, für sowas, weil das auch immer
nervt, meiner Meinung nach, sehr schön eigentlich.
Ja, also da ist
das JavaScript-Date-Ding, also
das hatte, also sowas wie
Stove-Time gibt es da halt einfach nicht.
Wenn man jetzt die Differenz
zwischen zwei Dates bildet,
in JavaScript, ja, du hast ein Date-Objekt,
ein anderes, machst eins minus das andere,
was kommt dabei raus? Wisst ihr das?
Ein Integer. Bei Python kommt so ein
Time-Delta raus.
Genau, bei JavaScript
kommt die absolute
Zeit in Millisekunden raus. Ja, tatsächlich.
Was natürlich ein bisschen
blöd ist, wenn man jetzt Mikrosekunden braucht oder keine Ahnung
oder was ganz anderes oder
oder halt an den Tagen
interessiert ist oder so.
Ja, das hat mich
ja, ich kann es so empfehlen,
weiß ich jetzt nicht, aber Pendulum in Python macht genau das
so ein bisschen schöner, so ein bisschen mehr moderner
vielleicht. Okay, gut. Keine Ahnung, ich kann es
nicht mal angucken.
Ist das du noch ein Pick?
Ja, vielleicht picke ich einfach
Blue statt Black.
Macht im Grunde das gleiche, nur halt mit
einem einfachen Tick statt
Doppel-Einführungszeichen.
Wir hätten noch mal letztens irgendwas mit Black, was man
Darker. Darker war auch schön.
Weil Darker macht nämlich inkrementelles Black und zwar
immer nur auf die neuen Änderungen.
Was ganz gut ist, wenn man halt
so, dass es halt immer dunkler wird mit der Zeit.
Und wenn man, weil das macht auch Sinn, dann halt
als Git-Commit-Hook irgendwie einzusetzen. Darker, weil
dann nur die neuen Sachen halt
tatsächlich gelintet werden und das ist ganz schön.
Okay, aber Blue ist ein bisschen, oh warte, was ich auch
noch picke ist Pip-Tools. Da habe ich letztens auf Twitter gesehen
auch jemand, ich habe
angefangen, weil du mir das gezeigt hast, wollte ich gerade
was damit machen und ich komme immer nicht dazu.
weil ich habe nämlich auch, ich verwende ja sonst
Poetry und
genau, dann jetzt für das
neueste Ding mit FastAPI und
Frontend-Dings da, für mein
Deploy-Teil, da habe ich jetzt auch
Pip-Tools verwendet, weil mich Poetry so
genervt hat, weil es so lange braucht und
Also Pip-Tools sind so richtig toll, fand ich es jetzt auch
und weil es halt oft auch irgendwie komisch kaputt
geht und es ist schwer zu installieren.
Pip-Tools gibt eine Empfehlung von dir?
Ja, also genau, heute auf Twitter
meinte jemand so, also Poetry
eigentlich super sexy sieht das aus und so, aber ich bin
durch. Ich nehme jetzt wieder PIP-Tools, weil
es funktioniert einfach nicht.
Und da dachte ich so, ja, und dann habe ich
in diesem Twitter-Thread, den musst du dir mal auffallen,
ganz viele Leute was Ähnliches gesagt haben. Also da
viele Leute sagen so, oh, furchtbar langsam,
geht immer kaputt.
Ja, also es geht auch bei mir ständig, ständig
kaputt und ich muss immer was fixen, das nervt
extrem. Aber es ist schon
eigentlich eine gute Idee und eigentlich sollte es genauso aussehen.
So was sollte es geben, aber es sieht halt nicht richtig aus.
Aber vielleicht sollte man es einfach mal fixen,
anstatt was Neues wieder zu machen, was auch nicht
funktioniert. Vielleicht.
Gutes Schlusswort.
Vielleicht sollte man das mal refactoren.
Danke, Ronne, dass du wieder da warst.
Vielen Dank für eure Aufmerksamkeit.
Für die Einladung.
Bleibt uns gewogen. Schaltet uns gerne wieder ein.
Bis zum nächsten Mal. Bis dann mit Werbung.
Tschüss. Tschau.