Webcafé — Folge 2
Wie benennen und strukturieren wir Dinge?
Heute sprechen wir über die Grundpfeiler unserer Webanwendungen: Entitäten, Namespaces und Services.
Worum geht es?
Heute sprechen wir über die Grundpfeiler unserer Webanwendungen: Entitäten, Namespaces und Services. Diese drei Konzepte, die wiederkehrend in unseren täglichen Code Reviews Thema sind, bilden die Grundstruktur unserer Softwareprojekte.
Im Podcast erklären wir jedes Konzept anhand von Beispielen und geben Tipps, um Anwendungsfälle im Code zu erkennen.
Das Gespräch, Wort für Wort
Kapitel
5.236 Wörter in 7 Abschnitten. Jede Zeitmarke springt an die passende Stelle im Audio. Automatisch transkribiert und maschinell nachkorrigiert — im Zweifel gilt das Gesprochene.
Begrüßung
0:00–1:07
-
0:00
Hallo und herzlich willkommen zur zweiten Folge vom Webcafé und eure Hosts sind auch heute wieder
-
0:10
der Kay. Hallo und ich bin Felix und wir haben heute wieder ein Thema für euch mitgebracht. Kay hat was vorbereitet, aber bevor wir einsteigen, ist natürlich für das Webcafé Tradition in der zweiten Folge schon, dass wir ein leckeres Getränk mitbringen. Und ich habe für meinen Teil heute einen Chai-Tee mitgebracht, wo ich einen Löffel Karamell-Schwarztee reingegeben habe. Und das finde ich ist eine super Mischung, da mit ein bisschen Milch und Zucker. Ganz herrlich. Da komme ich ja immer ins Schwärmen, wenn ich das bei dir höre. Ich habe jetzt auch ja auf losen Tee umgesattelt, also zumindest schon mal in der gleichen Klasse insgesamt. Ich habe
-
0:45
einen Vanille-Limonen-Gras-Tee hier und der ist auch ganz fruchtig. Oh, hört sich richtig gut an. Ja, du bist sowieso ja ein bisschen mehr so in der Fruchtecke unterwegs. Ich ja dann eher so ein bisschen in der cremigen Variante. Hört sich aber richtig gut an. Ja. Ich muss nur aufpassen, da nicht vorab schon den ganzen Tee leer zu trinken, sodass ich in der Mitte von der Aufnahme weg muss. Kay, du hast ein Thema mitgebracht. Da geht es um Benennen von Dingen. Ich würde gerne mit einem kleinen Zitat einsteigen und dann schon endlich übergeben, dass du eine Einladung machen kannst. Ich habe ein Zitat von Phil Carlton mitgebracht, das sich wie folgt liest.
Einleitung ins Thema
1:07–4:11
-
1:21
There are only two hard things in computer science, cash in validation and naming things. Und da haben wir die Benennung schon ein bisschen drin. Da tun sich viele am Anfang schwer mit und damit übergebe ich einfach direkt an dich. Danke. Ja, das kann ich unterstreichen. Man sollte ja eigentlich meinen, Dinge zu benennen, ist ganz einfach. Also ich habe das jetzt extra ein bisschen abstrakt gehalten, das Thema, aber es geht wirklich um Dinge im Code. Also Dateien, Klassen, Variablen, Funktionen und so weiter und so fort. Man könnte meinen, man rollt einfach mit dem Kopf auf der Tastatur und dann steht da schon
-
1:53
irgendwas. Aber wenn man sich dann ein bisschen mehr mit auch so Software-Architektur-Themen beschäftigt, dann stellt man auf einmal fest, dass, wie du sagst, Benennen super schwierig ist und aber auch extrem wichtig für eine gute Software-Architektur. Und wir nehmen das deswegen als zweites Thema, weil das alleine schon bei uns in der Firma, in den Code-Reviews und so weiter, die wir machen, so fortlaufend, glaube ich, das Thema Nummer eins ist, was angemerkt wird. Genau. Wir wollen ja einfach und präzise benennen. Auf der anderen Seite sollen ein Entwickler auch direkt verstehen, was gemeint ist. Und das irgendwie unter einen Hut zu bringen, ist
-
2:32
meistens doch ziemlich schwierig. Genau. Deswegen möchte ich jetzt heute so einen kleinen Ablaufplan geben. Also genau gesagt drei
-
2:43
Konzepte möchte ich vorstellen, die man so bei der Benennung von Dingen daneben halten kann und dann schaut man, okay, welchen Use Case habe ich hier und dementsprechend kann man dann hoffentlich ein Konzept anwenden. Diese drei Konzepte sind zum einen das Konzept der Entity, sage ich gleich was zu, das zweite ist Namespace und das dritte ist Services. Und das Ganze möchte ich anhand von so einem Online-Shop erklären, was es da für Beispiele geben könnte. Und meine Hoffnung ist, auch für die Kollegen, die dann sich hoffentlich nachher diesen Podcast anhören, dass man mithilfe von diesen drei Konzepten schon sehr gut im Alltag Entscheidungen treffen kann, wie man Dinge benennt.
-
3:24
Ja, deine Idee ist ja jetzt, so ein Gerüst zu geben, an dem man sich in dieser grundsätzlichen Benennung erstmal orientieren kann, um, glaube ich, das Thema Naming dann komplett abzudecken. Können wir drei Stunden reden. Aber wir versuchen erstmal so einen Start zu geben und einfach einen Einblick da rein, wie wir das bei uns machen. Und vielleicht hilft das Leuten schon, dann besser in diese Naming-Geschichte reinzufinden. Ja, ganz genau. Da gibt es im Detail natürlich zig Sachen, an denen man sich halten kann. Es gibt auch in allen möglichen Frameworks, die man so verwendet, schon Best Practices, die vorgeben, wie Dinge
-
3:58
idealerweise zu sein sind. Da sollte man sich natürlich auch möglichst dran halten und sowas. Ich möchte jetzt einfach nur hier mit diesen drei Konzepten möglichst grob so Blaupausen bereitstellen. Dann hat man schon mal, glaube ich, eine große Orientierung. Ich habe gerade, oder wir haben gerade schon darüber gesprochen, warum das wichtig ist. Aber abgesehen davon, dass es bei uns wiederholt Thema ist, ist es auch wichtig, um stabile Konzepte für die Software-Architektur zu finden. Weil wenn man dann nicht so stabile Konzepte hat und dann einfach so drauf loslegt, wenn man irgendwelche Dinge implementiert, dann stellt man vielleicht
Warum ist das wichtig?
4:11–5:50
-
4:33
nachher fest, dass man das so ein bisschen an der Realität vorbei entwickelt hat. Und dann kommt es vielleicht, dass neue Anforderungen dazukommen, die sich aber so nicht umsetzen lassen. Das heißt, hier geht es schon wirklich nicht nur darum, Namen für irgendwas zu finden, sondern die Konzepte zu benennen, die dahinter stecken. Ein anderer wichtiger Punkt ist auch, wenn man
-
4:57
so als Team, wie bei uns zum Beispiel in der Firma, die gleichen Konzepte hat, um Dinge zu benennen, dann kann man auch ganz einfach im Team hin und her wechseln, neue Leute in die Software reinstecken, Projekte tauschen und so weiter. Und alle finden sich relativ gut zurecht, weil die Konzepte sehr ähnlich sind und auf den gleichen Ideenfußen. Du sprichst ja jetzt von einem gleichen Verständnis von Begriffen, die man so in einem Team hat. Am
-
5:25
allerbesten ist natürlich, wenn man sogar eine internationale Sprache im Code spricht. Und da sind natürlich sowas wie Design Patterns und so dann ein großer Begriff, sodass wirklich auch andere Leute, die von außen kommen und noch nicht so lange im Team arbeiten, auch direkt verstehen, was los ist. Aber spätestens im Team muss natürlich dann die Sprache eindeutig und klar sein. Ganz genau. Und es geht jetzt auch weniger um die Zeile-zu-Zeile-Code, sondern wirklich die übergreifenden Konzepte, um die es geht. Also ich will jetzt gar nicht weiter um den heißen Brei herumreden. Das erste Konzept und ich glaube auch das Wichtigste, das ich gerne vorstellen
1. Entitäten
5:50–14:16
-
5:57
möchte, ist das Konzept der Entity. Das kennt man wahrscheinlich eher, wenn man so aus dem Backend kommt oder von den Datenbanken. Da gibt es zum Beispiel das Entity-Relation-Diagramm und damit kann man sehr schön aufzeichnen, welche Daten es in der Anwendung gibt und wie die zusammenhängen. Und mein großes Takeaway von heute ist, dass das auch für alle Bereiche der Softwareentwicklung spannend ist, nicht nur für solche, wo es offensichtlich ist. Was meine ich mit Entity eigentlich? Also da geht es darum, Dinge, die es in der Realität
-
6:31
gibt, auch im Code abzubilden. Das bedeutet, statt dass ich mir für etwas, was ich bauen
-
6:40
muss, neu überlege, wie ich das mache, schaue ich, ob es in der realen Welt Dinge gibt, an denen ich mich orientieren kann. Und das Stärke an diesen Entities ist, dass es eben ein Konzept ist, das interdisziplinär ist. Also finde ich idealerweise Dinge, über die ich als Software-Programmierer
-
6:58
reden kann. Ich kann aber auch mit jemandem aus dem Backend über dieses Ding reden und der weiß, was ich damit meine. Die Implementierung ist bei dem vielleicht ein bisschen anders, aber das Konzept ist dasselbe. Und ich kann mit Leuten aus dem Verkauf reden, mit der Geschäftsführung, mit allen Leuten, die mit dem Geschäftsfeld, sag ich mal, zu tun haben. Mit denen kann ich darüber reden und die wissen, was damit gemeint ist. Ich mache das zum Beispiel in Form von einem Online-Shop. Da könnte es ein Produkt sein. Also wir entwickeln einen Online-Shop und darin gibt es ein Produkt. Und das Produkt ist die Entity. Und da gibt
-
7:33
es Leute, die in der Datenbank arbeiten. Die kennen das vielleicht als Datenbank-Eintrag in MySQL. Leute, die in Backend arbeiten, haben da eine, weiß ich nicht, PHP-Klasse zu. Die Sales-Leute können mit dem Produkt auch etwas anfangen, mit der Produkt-Entity, obwohl sie gar nichts mit dem Code oder so zu tun haben und auch Support und so weiter. Und wenn es solche Konzepte gibt, dann ist es auch super mächtig, die so im Code abzubilden. Und das heißt konkret, diese Entity ist die Grundlage für alles, was ich baue in der Benennung. Wieder ein Beispiel von dem Produkt. Es gibt dann eine Klasse, die heißt Produkt und deren Klasseneigenschaften
-
8:13
orientiert sich an den Eigenschaften des Produkts in der realen Welt. Also zum Beispiel einen Namen oder eine Beschreibung oder ein Produktbild. Und wenn ich diese Entity gefunden habe, dann baue ich alles andere drumherum. Und dann heißt zum Beispiel, eine Liste, in der Produkte angezeigt werden, heißt dann Product-List. Oder wenn ich so eine kleine Preview-Karte mache, wo nur das Bild und die Beschreibung drauf ist, dann heißt das Product Preview und so. Die Idee ist dahinter, das Produkt oder das Product in den Online-Shop ist meine Entity
-
8:47
und alles andere, was damit irgendwie zu tun hat, baue ich da drumherum. Und das hilft mir bei der Benennung, weil ich schaue, okay, meine Entity ist Product und wie hängt das damit zusammen? Und ich kann auch ganz einfach in meiner Anwendung alles finden, was irgendwie damit zu tun hat, weil es eben dieses einheitliche Benennungsschema hat. Ja, vielleicht muss man da noch dazu sagen, dass der Name immer eindeutig ist. Das heißt, es gibt jetzt auch nur ein Product im ganzen Shop oder in dem ganzen System, sodass man immer weiß, dass eine Product-List auch genau die Products sind und nicht etwa irgendein anderes
-
9:23
Produkt, was jetzt auf einmal in der Liste auftaucht. Genau. Und es muss eben dasselbe sein. Ich kann nicht im Backend über ein Product reden und im Frontend und dann sind das zwei unterschiedliche Dinge, weil jemand bei der Benennung nicht aufgepasst hat. Die Idee ist, ich rede von einem Product und alle, die mit dem Geschäft zu tun haben, können damit was anfangen, auch wenn die Implementierung ein bisschen was anderes ist. Und das muss nicht unbedingt sowas sein wie ein Produkt, wo es ein physisches Äquivalent zu gibt, sondern das kann auch irgendwelche imaginären Konstrukte sein oder sonst
-
9:54
irgendwas. Wichtig ist, dass das interdisziplinär verstanden wird, wenn ich da von so etwas rede.
-
10:02
Beispiel für was abstrakteres wäre, vielleicht so ein Export oder sowas in der Richtung. Ja, ganz genau. Und das Elegante ist, wenn ich so eine Entity gefunden habe, dann kann ich mich zum einen bei der Benennung daran orientieren, aber auch kann ich mich daran an der Realität orientieren, wenn es darum geht, da Dinge zu unterstrukturieren oder da Dinge abzuleiten. Und das Schöne ist auch, wenn ich da eine stabile Entity gefunden habe, dann fällt es mir auch in der Zukunft leichter, das irgendwie zu erweitern, weil ich üblicherweise in der Software ja nur Dinge abbilde, die es in der Realität schon gibt. Und dann, wenn ich mich an der Entity aus der Realität
-
10:42
halte, dann kommen mir nicht auf einmal irgendwelche Anforderungen da rein, die mir gar nicht in den Kram passen, weil ich es in gewisser Weise schon antizipiert habe. Genau. Das ist meine Einschätzung nach das wichtigste Konzept, was es so gibt. Und wie gesagt, in den Code Reviews, die wir so machen, ist das ein Großteil der Anmerkungen, die so aufkommen und tatsächlich auch die Anmerkungen, die dann die größten Umbaumaßnahmen erfordern. Weil bei so Entities ist eben wichtig, dass so eine Entity das Maß aller Dinge ist. Also alles andere wird dem untergeordnet. Und das bedeutet zum Beispiel, wenn ich eine Funktion habe, die mit zwei von fünf
-
11:22
Eigenschaften von so einem Product nur was anfängt, dann übergebe ich trotzdem die komplette Entity als Variable. Idealerweise heißt die dann auch Product und fange dann nur mit den zwei Eigenschaften was an, mit denen ich was machen möchte, statt dass ich nur die gesondert aufnehme. Also was ich meine ist, stell dir vor, wir haben eine Funktion, die ein Profil oder ein Produktbild zurückgibt. Und dafür braucht sie den Pfad und den Titel für den Alttext. Was ich dann
-
11:52
nicht tun würde, ist eine Funktion zu bauen, so getProduct. Und da übergebe ich den Titel als separaten Parameter und die URL, sondern ich übergebe das Product als Entity, das komplette Objekt
-
12:07
übergebe ich als Parameter, auch wenn ich im Endeffekt nur zwei Felder von 20 daraus brauche oder so. Weil es eben wichtig ist, dass diese Entity durch die komplette Anwendung hindurch gleich bleibt und identisch bleibt und so bleibt, wie alle sich was damit vorstellen können. Ja, finde ich ganz wichtig, auch hinterher für die Erweiterbarkeit. Und wenn man ein bisschen damit gearbeitet hat, weiß man ganz genau, was so ein Produkt kann und was es nicht kann. Und das ist dann natürlich viel einfacher, als immer die Signaturen von den Funktionen wieder anzugucken. Genau. Und das führt auch dazu, wenn man sich ein bisschen auskennt und weiß, mit welchen Entities
-
12:40
man es so zu tun hat. Wenn man dann irgendwo im Code unterwegs ist und so eine Variable findet, in der sowas drinsteht, dann weiß man schon, ah, guck mal, da steckt das und das drin. Und kann sich dann da ganz einfach daran orientieren. Und deswegen auch darf man nicht anfangen, Dinge anders zu benennen. Oder also entweder die Entity umbenennen, dann heißt es nicht Product, sondern ja, Produkt vielleicht oder Shop-Item. Dann kommt schon die Verwirrung auf. Oder andersherum, ich nenne Dinge Product, die aber nichts mit dieser Entity zu tun haben. Das kann auch ein häufiger Fehler sein. Also wichtig ist, wenn diese Entity definiert wurde,
-
13:15
dann muss auch sich drakonisch daran gehalten werden, soll ich sagen. Im Frontend heißt das dann zum Beispiel, dass man ein TypeScript-Interface baut. Im Backend hat man wahrscheinlich eine Klasse in der Datenbank, wie gesagt, den Eintrag und sowas. Die Tabelle, ne? Genau, ja. Aber wenn man eine Sache, glaube ich, für die Software-Architektur lernen möchte, die einen großen Impact hat, dann ist es dieses Entity-Konzept. Und es ist auch gar nicht so einfach, da immer welche zu finden. Und das bedingt auch manchmal, dass man irgendwann mal drauf losgecodet hat, ohne diese Entity im Kopf zu haben oder die zu wissen.
-
13:46
Und dann nachträglich sich die erst ergibt. Dann muss man mitunter große Umbaumaßnahmen durchführen. Aber ich bin der Meinung, das ist in den meisten Fällen der richtige Weg, um eben so ein stabiles Fundament zu haben. Ja, das ist ein guter Punkt, den du nochmal gesagt hast. Wir reden natürlich jetzt über eine schöne Entity, ist eindeutig für so ein Product, wo man sich ganz viele Eigenschaften wie ein Bild und so weiter vorstellen kann. In der Realität ist es dann oft etwas schwieriger, einen knackigen Begriff zu finden. Lohnt sich aber, darüber einen Moment nachzudenken und da was bestenfalls Gutes zu finden.
2. Namespaces
14:16–20:28
-
14:16
Genau, jetzt haben wir schon viel über Entities geredet. Kay, du hast noch zwei weitere Denkansätze mitgebracht, nämlich Namespace und Services. Genau. Wollen wir vielleicht zu den Namespaces hüpfen oder bist du schon beim Service? Nee, Namespace wäre dann das Nächste. Das ist so auf der Strecke, sage ich mal, 30 Prozent zu Entity. Also Entity, das wichtigste Konzept. Wenn ihr das verstanden habt, könnt ihr den Podcast ausmachen. Falls ihr noch mehr wissen wollt, Namespace ist der zweite Schritt. Und da geht es darum, Dinge zu gruppieren unter einem gemeinsamen Namen, die zusammengehören. Also Bausteine zusammenzuordnen innerhalb der Anwendung.
-
14:55
Was ich damit zum Beispiel meine, ist wieder zurück zu diesem Produktlisten-Beispiel. Ich möchte in der Anwendung eine Liste von Produkten anzeigen. Und dafür brauche ich, um das sauber zu trennen, zum einen ein Modul, was sich um die Liste kümmert und zum anderen dann ein Modul, was ein einzelnes Produkt anzeigt. Das möchte ich gerne aufteilen, damit das ein bisschen übersichtlicher ist. Und jetzt frage ich mich aber, wie ich das in der Anwendung denn auch abbilde, weil die gehören ja schon irgendwie zusammen. Eine Liste, da kann man sich zum Beispiel noch Filteroptionen oder Suchoptionen darunter vorstellen,
-
15:27
die funktioniert nicht ohne Kinder. Und gleichzeitig funktionieren die Kinder nicht ohne die Liste. Also die gehören schon irgendwie zusammen. Und das eben kann man in der Software durch Namespaces abbilden. Das hat ein bisschen andere Implementierung, je nachdem, in welchem Code man unterwegs ist. Aber im simpelsten Falle geht es da einfach um Dateien oder Dateifade. Man kennt das vielleicht vom Desktop. Da sortiert man auch Dinge, die irgendwie zusammengehören, unter gleichen Dateien und verschachtelt die dann wiederum in so einen Baum. Und wenn man das sauber macht, dann kann man alleine durch den Pfad der Datei schon ablesen,
-
16:04
wie denn da die Zusammenhänge und Relationen zu anderen Dateien sind. Oder vielleicht klassisch aus so einer URL. Da kennt man das auch so ein bisschen her. Das kommt ja aus dem Dateisystem raus. Aber da kann man auch über den Pfad so ein bisschen nachvollziehen, wie die Zusammenhänge sind. Und für unser Beispiel mit dieser Produktliste hieße das, der Einstiegspunkt ist diese Liste. Und diese Liste benutzt dann intern, um das schöner zu strukturieren, so ein einzelnes, wieder ein einzelnes Modul, was sich um die Darstellung der einzelnen Produkte kümmert. Aber die Liste ist eigentlich das Hauptmodul.
-
16:40
Und dann wäre zum Beispiel der Namespace Product List und dieser im Namespace Product List, also im Verzeichnis, wäre dann zum Beispiel ein Unterverzeichnis mit Product List Item. Und so wäre alleine schon durch den Pfad so eine Hierarchie und so eine Zusammengehörigkeit gegeben.
-
17:01
Und wir haben das bei uns zum Beispiel so benannt, mir wieder mit diesem Beispiel, das Product List Modul ist so public. Das gibt es bei Dateien und sowas ja nicht richtig. Aber unser Ansatz ist, wenn ein Namespace Product List ist zum Beispiel, gibt es da drin eine Datei Product List, die genauso heißt. Und die ist damit public, also wenn ich von außen das benutzen möchte, dann muss ich nur diese Datei einbinden und die kümmert sich selber darum, alle, weiß ich nicht, Helper oder Untermodule oder sowas einzubinden, die es braucht. Und alles, was dann diese Product List braucht, um zu funktionieren,
-
17:38
ist dann in diesem Namespace versammelt. Da gibt es dann zum Beispiel Product List Slash Item. Da ist dann ein einzelnes Item drin. Dann gibt es Product List Slash Filter oder weiß ich nicht was. Und so ist dann, wenn ich mir nur die Dateien im Baum anschaue, klar, okay, das hier ist der Public Export, sag ich mal. Und alles andere machen die Private so für sich. War das halbwegs verständlich, Felix? Ich habe das gut verstanden. Ich kenne das Konzept natürlich von uns auch. Eine Sache muss ich jetzt aber noch nachfragen, weil ich da gar nicht auf dem aktuellsten Stand bin, wie wir das machen. Wenn du jetzt in der Product List, im Ordner Product List,
-
18:12
hättest du jetzt noch ein Item, also Product List Item dann, würdest du das auch Product List Item nennen oder würdest du das nur Item in dem Unterordner dann nennen, weil sich das Product List schon aus dem Kontext, also aus dem Namespace ergibt? Ja, da streiten sich so ein bisschen die Geister, genau. Wir machen es bei uns so, dass wir es nur Item nennen und dass der Namespace selber Teil der Bezeichnung ist. Also, dann kann es durchaus mehrere Item-Komponente im Projekt geben, aber durch ihre Namespace unterteilen die sich dann. Man muss also, wenn man so ein Modul verwendet, nicht nur nach dem tatsächlichen Namen schauen,
-
18:48
sondern auch nach dem Namespace, wo das herkommt. Das führt ja oft dazu, dass man dann mehrere Items in Code hat, die man jetzt zum Beispiel in TypeScript dann oben einmal benennen muss und dann hätte man zum Beispiel ein Product List Item daraus gemacht. Da kann man idealerweise gut über Aliase arbeiten oder sowas. Das machen wir einfach aus dem Grund, weil dieses Item, wenn wir bei dem Beispiel bleiben, ja wiederum Helper und weitere Unterkomponenten benutzen könnte, wenn es ein großes, komplexes Ding ist. Und dann hat man einfach sehr schnell super lange zusammengesetzte Namen, wo es dann Product List Item Helper Filter oder sowas heißt.
-
19:23
Und das finde ich dann nicht so schön. Und die Sachen sind ja auch eigentlich private. Also das heißt, die sollen gar nicht außerhalb dieses Moduls oder dieses Namespaces verwendet werden. Und dementsprechend sind wir bis jetzt ganz gut damit gefahren, diese Best Practices zu fahren, zu benutzen. Genau, wenn man jetzt in einem konkreten Code dann ist und dann da immer die langen Begrifflichkeiten hätte, könnte das auch ein bisschen stören. Ich habe da ein Zitat noch von Kent Beck, der sagt, Sometimes naming concrete classes simply is more important to communication than hiding the use of interfaces jetzt in dem Fall.
-
19:56
Also er sagt auch, in manchen Punkten ist es dann wichtig, einfach zu benennen, anstatt jetzt einen langen Namen zu machen, der dann sehr eindeutig ist, aber der den Lesefluss zum Beispiel stört. Ja, genau. Und was man mit diesem Namespace insbesondere, wenn es dann um Verzeichnisse geht, auch noch als positiver Nebeneffekt hat, dass man da dann auch, wenn man zum Beispiel ein Namespace-Product hat, dann kann man da auch noch Product Test mit unterbringen, Storybook, irgendwelche Mocks, was weiß ich nicht, was es da noch so für Develop-Helper gibt, kann man dann auch so alleine schon sehr schön in den Dateien gruppieren.
3. Services
20:28–25:50
-
20:29
Der letzte Punkt, Services, der bricht das Ganze wieder so ein bisschen auf. Nämlich haben wir ja gerade gezeigt, dass man sich eigentlich an dem Ding orientieren sollte, was man implementiert und daran das benennt. Es gibt allerdings auch manchmal Situationen, in denen man nicht so eine Hierarchie abbildet, wie zum Beispiel Product List und Product List Item, die ja für sich stehen, aber eine Abhängigkeit voneinander haben, sondern dass man Geschwister abbilden möchte, die eigentlich das Gleiche machen, aber mit einer unterschiedlichen Implementierung. Was meine ich damit zum Beispiel? Wenn wir wieder zu dem Online-Shop zurückgehen,
-
21:08
da könnte man sich vorstellen, dass der Online-Shop verschiedene Zahlungsmöglichkeiten anbietet und dann kann man sich entscheiden zwischen Rechnung, Paypal und was weiß ich nicht, was es noch alles gibt. Und die haben jetzt keine Abhängigkeit voneinander, also Rechnung und Paypal funktionieren komplett unterschiedlich, aber das sind Geschwister in dem Sinne, dass sie die gleiche Funktionalität abbilden. Also die kann man nicht in eine Hierarchie bilden, in eine Hierarchie zueinander setzen, wie List und Item, sondern die sind Geschwister. Und wenn man so eine Situation hat, die ist auch sehr schwer zu erkennen,
-
21:42
dann bietet es sich an, da das Service-Konzept zu benutzen. Und das bedeutet, man versucht, eine gemeinsame Abstraktion zu finden. Da kommt dann wieder der Begriff Interface ins Spiel. Und dieses Interface sagt, was die einzelnen Kinder oder was die Geschwister können müssen. Und die Geschwister sind dann aber selber dafür verantwortlich, das umzusetzen. So bei so einem Bezahl-Service, da könnte man sich zum Beispiel vorstellen, dass es ein Interface gibt, das die Methode Handle-Payment voraussetzt. Und der Service-Paypal und der Service-Rechnung erben dann davon und müssen sich dann darum kümmern,
-
22:20
dieses Interface umzusetzen. Genau, es geht ja bei den Services immer darum, dass die eine gemeinsame Schnittstelle, also eine eindeutige Schnittstelle anbieten und eigentlich verschiedene Funktionen in der gleichen Schnittstelle oder mit der gleichen Schnittstelle dann zur Verfügung stellen. Genau, man könnte sich auch vorstellen, dass man einfach eine lange Funktion baut mit der ifPaymentType gleich Paypal, dann machst du diesen Block und darunter machst du diesen Block und diesen Block. Aber die Idee bei diesem Service ist, dass man ganz einfach den erweitern kann. Nämlich durch dieses Interface
-
22:50
muss der Service selbst definieren, was er kann. und irgendwo gibt es dann nur eine Stelle, wo definiert ist, welche Services es alle gibt. Und der restliche Code kann dann damit umgehen, indem er immer durch diese Liste der Services iteriert und auf denen hantiert. Und dann muss gar nicht überall im Code, wenn eine neue Zahlungsmöglichkeit dazukommt, die ergänzt werden, sondern eigentlich nur ein neuer Service. Der kümmert sich selber darum, dass er alles tut, was er braucht. Und er wird irgendwo registriert. Ich hoffe, dass Sie jetzt zwischen den Zeilen überall kommen, dass diese langen if-Bedingungen
-
23:21
nicht der richtige Weg sind. Ja, genau. Es ist einfach sehr viel schöner strukturiert. Also im Code ist es super nachlesbar, wenn man da dann so ein Verzeichnis hat und da ist dann Paypal-Service und weiß ich nicht, Rechnungsservice und Lastschriftservice, statt dass das alles so im Code ist. Und man kann es auch sehr einfach erweitern, wenn es dann nachher heißt, wir nehmen noch, ja, was gibt es denn noch, dritten Zahlungsanbieter. Einfach nur diesen Service kopieren. Vorkasse zum Beispiel. Wir haben das jetzt letztens sehr erfolgreich eingesetzt, als es darum ging, so eine Karte umzusetzen mit verschiedenen Layern.
-
23:53
Da haben wir auch einen Service für diese Layer eingeführt, in dem es dann so eine Funktion gab, so GetLayerName, GetLayerIcon, GetLayerStyle oder sowas. Und die verschiedenen Layer, da wurden dann Autobahnen angezeigt oder Städtenamen oder sonst irgendwas. Alle ein bisschen unterschiedlich, aber doch gleich durch dieses Interface und super einfach im Code handelbar durch einen neuen Layer einfach eine neue Klasse bauen und der Rest kann die Anwendung automatisch. Das hört sich gut an. Jetzt sag mir nochmal, wie ich das im Verzeichnis abbilden würde. Du sagst ja schon, das bricht jetzt die Struktur
-
24:27
dieser Namespaces so ein bisschen auf. Gibt es da einen Guide, an dem man sich so ein bisschen entlanghangeln kann oder ist das immer sehr individuell? Also es fußt ja darauf, dass es eine gemeinsame Abstraktion gibt. Das ist üblicherweise wahrscheinlich, wenn wir über Code reden, ein Interface, dass die verschiedenen Services implementieren müssen. Und wir machen das üblicherweise so, dass es dann irgendwo ein Verzeichnis gibt. Das heißt dann zum Beispiel Zahlungs- oder Payments. Da drin ist das Interface und da drin wiederum gibt es dann ein Verzeichnis mit Payment Services. und da ist dann einfach die Liste unten drunter.
-
25:04
Also gerne auch wieder mit dem Namespace kombinieren, dass man sagt, man hat den Namespace Paypal Service oder sowas oder Paypal Payments. Und da drin sind dann die Tests kombiniert oder sowas. Da würde ich jetzt gar nicht so gerne direkte Vorgaben machen, wie man das im Dateifad abbildet. Wichtig ist, zu einem diese Services zu erkennen, weil das ist schon, glaube ich, der schwierigste Schritt, wie man es dann implementiert. ist dann fast egal. Aber mit den anderen beiden Regeln kann man sich da, glaube ich, gut was von ableiten. Ein guter Hinweis für mich ist immer dieses Don't-Repeat-Yourself,
-
25:37
dieses Drive-Prinzip. Und wenn man merkt, man baut Sachen, die man irgendwie so schon mal gesehen hat oder die sich ähnlich anfühlen, dann kann das ein Hinweis darauf sein, dass man vielleicht da ein gemeinsames Ding draufpacken kann. Und das ist dann vielleicht in dem Fall ein Service. Genau. Wir haben es vorhin schon grob angesprochen, wenn man jetzt so ein bisschen auf die Probleme eingeht, die da mit einhergehen. Alle diese drei Konzepte verlangen ein unfassbar großes Wissen darüber, wie die Anwendung funktioniert. Und zwar auf einer großen und weiten Meta-Ebene, die Entwickler üblicherweise
Potenzielle Probleme
25:50–30:01
-
26:10
nicht so gut haben, wenn sie sich nicht selber drum kümmern. Die bekommen eine Aufgabe, High-Level, von dem Kunden vielleicht direkt, der selber nicht so genau weiß, was er will. Und er sagt dann, ja, mach mir mal diese Funktion und die soll das und das machen. Und die Herausforderung ist dann, vom Entwickler, der das umsetzt, diese Konzepte zu kennen, die ich gerade genannt habe. Und dann muss er sich die Mühe machen und sich in das Geschäftsfeld einarbeiten, mit dem Kunden reden und ein großes Verständnis von der kompletten Anwendung bekommen, damit er fundiert solche Entscheidungen treffen kann.
-
26:45
Weil je komplizierter die Anwendung schon ist und je komplizierter das Geschäftsfeld ist, desto schwieriger ist es, diese ganzen Zusammenhänge zu wissen und zu verstehen. Und die braucht man aber, um so fundierte Entscheidungen über Entities und Namespaces und so weiter treffen zu können. Und das Zweite ist, dadurch, dass das häufig so im Affekt passiert, passiert es auch gerne mal, dass man so eine Entity erst im Nachhinein erkennt. Das haben wir vorhin kurz angesprochen. Und dann muss man eigentlich, wenn man es sauber machen möchte, den Schritt zurückgehen und sagen, oh, guck mal, hier hat sich jetzt eine Entity ergeben.
-
27:18
Die haben wir bis jetzt nicht abgebildet. Aber wenn wir die sauber abbilden wollen, dann müssen wir große Refactorings umführen und den Code restrukturieren. Und das ist natürlich erst mal enorm aufwendig und enorm zeit- und geldintensiv. Und der Nutzen davon mag vielleicht nicht direkt klar sein, weil man ja denkt, naja, es hat ja bis jetzt auch funktioniert. Aber je mehr so eine Anwendung wächst, desto wichtiger werden nachher, dass man so stabile Fundamente hat, weil sonst man wirklich in der Zukunft noch irgendwas umsetzen muss und das geht dann gar nicht mehr so richtig. Das kennt man ja gut bei großen Anwendungen,
-
27:49
dass man denkt, am Anfang hat man super Struktur aufgebaut, eine super Architektur und nach ein, zwei Jahren des Rumentwickelns und des Entwicklerwechsels ist dann plötzlich ein riesen Wuster ausgeworden. Und das hängt ja oft damit zusammen, dass eben Inkonsistenzen reinkommen, gerade auch im Naming. Und wenn man die früh erkennt und sich auch die Mühe macht und vielleicht auch der Kunde dazu bereit ist, da mitzugehen, dass man dann Refactoring macht, dann ist es früh erkannt eigentlich oft auch ein kleineres Problem und schneller gemacht. Und vor allem, wenn man es ein, zwei Mal gemacht hat, hilft das auch,
-
28:20
die Anwendung gut zu verstehen und in Zukunft schneller zu werden. Und da können wir nur alle zu ermutigen, das dann tatsächlich auch zu machen. Und bei uns wird es so gehandhabt, dass wenn wir solche Stellen erkennen, dann gehen wir wirklich dran und sagen, das muss rigoros geändert werden. Genau. Ich hoffe, dadurch, dass ich das ja einmal im Podcast alles erklärt habe, wird mir dieses Thema nie wieder begegnen. Zumindest, dass zumindest die Konzepte klar sind und so die Grundlagen. Ich glaube wirklich, das ist entscheidend. Und dann hilft, glaube ich, nur noch Übung und die Sachen in der Realität finden,
-
28:51
erst mal zu suchen, dann zu finden und dann zu überlegen, wie man damit umgeht. Ich hoffe, das war verständlich, trotz meinem Wasserfallgeschwafel. Also ich habe jetzt noch mal einen guten Refresh gekriegt. Also ich kenne die Konzepte ja und sehe es ja auch täglich in unseren Reviews und in unserem Code. Und trotzdem ist das ja noch mal was anderes, wenn man es dann noch mal konkret hört und noch mal zusammengefasst hat. Ich würde den Podcast heute gerne schließen mit einem weiteren Zitat. Ich habe ja schon zwei mitgebracht und ich habe noch ein weiteres. Da weiß ich tatsächlich gar nicht, von wem es ist,
-
29:22
aber ich gebe es mal zum Besten und das geht nämlich wie folgt. Name is a reflection of meaning and design. When you name properly, you think properly, you design properly and you use properly. Bad names lead to improper usage, bad design and bugs. Und das finde ich eigentlich genau knackig und perfekt und deutet noch mal so ein bisschen auf die Wichtigkeit vom Naming hin. Dem habe ich nichts hinzuzufügen. Kay, ich danke dir für die heutige Folge und wir hören uns in der nächsten Woche. Danke auch. Bis auf Wiedersehen. Bis dahin.
Nebenan im Webcafé
Alle zwei Wochen montags eine neue Folge über Webentwicklung, Codequalität und die Art, wie wir zusammenarbeiten.
Alle 52 FolgenFragen an Felix und Kay?
Themenwunsch, Widerspruch oder eine Frage aus Deinem Projektalltag — schreib uns. Was uns erreicht, landet regelmäßig in einer der nächsten Folgen.
podcast [at] geenen-it-systeme.de
