Dieses Interface wurde für den Cheeseburger implementiert, das heißt Brötchen, keine Ahnung, Patty, was kommt, da kommt da überhaupt noch ne Gurke drauf, keine Ahnung was war da glaub ich noch nie drauf. Ne. Coding Buddies Dein Podcast rund um Softwareentwicklung und aktueller Tech News herzlich Willkommen.
Einen wunderschönen guten Tag und herzlich Willkommen zur neuen Folge vom Coding Buddies Podcast und Tino begrüße ich hier ganz herzlich und ich hoffe, Tino, Du hast auch einen so wunderschönen Tag, wie ich ihn gerade allen hier gewünscht. Habe ja Moin Moin fabi, ja ich habe einen super Tag, es ist tolles Wetter, ich genieße das so richtig drin zu sein und. Um mit dir jetzt n Podcast aufzunehmen. Ich hab Bock, ich hab Bock. Das ist sehr gut, das freut
mich. Wir haben nämlich auch heute wieder n sehr interessantes Thema. Also ich freu mich auf die Folge, ich hab da echt Bock drauf, hab ich ja sonst auch immer, aber irgendwie weißt du es gibt immer mal so da da da stehst du morgens auf und denkst dir heute n Podcast aufnehmen. Fühl ich so mit dem Thema. Ja, ich find es auch. Was haben wir denn so?
Wir haben ja n ganz cooles Thema heute und zwar wollen wir so richtig durchstarten mit unserer neuen Reihe zum Thema Design Pattern und quasi heute mal so das erste Pattern besprechen.
Doch bevor wir sagen, welches das ist und so richtig reinstarten noch ganz kurz die Anmerkung, Liebe Zuhörer, liebe Zuhörer, falls dir dieser Podcast gefällt, du den Abfeierst, ihn vielleicht schon länger hörst, so Mehrwert rausziehen kannst, schau doch mal in die Shownotes, da gibt es einen kleinen Spendenlink. Falls du Bock hast zu uns zu unterstützen, wir würden uns mega darüber freuen. Das nur kurz als Anmerkung. Werbung ändern an dem Punkt.
Und deswegen fabi, Hau doch mal raus, was für ein Pattern kommt heute, wir haben es ja in der Einleitungsfolge schon mal etwas angeteasert und genau das haben wir auch jetzt gemacht. Wir haben gesagt, wir nehmen einfach ein Pattern, was ich glaube einfach wirklich, wirklich, wirklich oft einem über den Weg läuft und zwar das Factory Pattern und ich finde
auch persönlich ist es auch ein. Pattern, was ich auch häufig sehe, häufig nutze also auch selber und ich finde irgendwie, das ist so ein Klassiker und deswegen können wir einfach mal mit diesem Klassiker einfach anfangen und durchstarten und einfach mal gucken okay ne, was ist das, wann nutzt man das,
wofür benutzt man das? Und diese Fragen klären wir einfach mal alle und zeigen natürlich, was es also wie das aufgebaut ist, ne. Genau, also wir hatten ja gesagt, dass wir uns heute das Factory Pattern anschauen wollen. Und in der Einleitungsfolge sag ich mal, haben wir ja auch gesagt, warum Pattern so wichtig
sind. Noch mal kurz genannt, um einfach Strukturen den Code zu kriegen, besser testbaren Code zu haben, Skalierbarer und Wartbarer zu sein und das kann man am Factory Pattern auch ganz gut schon sehen und deswegen ist es auch n super einstiegspattern sag ich mal, weil man kann es auch mit. Mit Analogien gut erklären und ich weiß, du bist Fan von Analogien. Fabi, da kannst du dich richtig austoben heute aber mal ganz kurz allgemein, warum überhaupt Factory pattern?
Also wir bewegen uns heute so n bisschen in der objektorientierten Welt, das noch als Anmerkung dazu. Ja. Und jeder, der vielleicht gerade am Anfang ist, sich mit der Objektorientierung zu beschäftigen, beispielsweise mit Javas startet und da ja notgedrungen in die Objektorientierung kommt, was ja
nichts Schlechtes ist. Nicht falsch verstehen, aber der wird das Halt merken, dass gerade am Anfang, dann hast du überall New im Code, überall werden Objekte erzeugt, du weißt gar nicht mehr, auf welchen du jetzt arbeiten sollst. Du hast ne hohe Kopplung des Codes, du kannst das nicht mehr so wirklich extrahierend voneinander und. Wie sagt man so schön Dead escalated Quickly?
Also du kommst halt dann auch schnell an den Punkt, wo es einfach unübersichtlich wird und da möchte ich wirklich mal mit einer Analogie starten. Fabi, Ich hoffe du greifst die auf oder hast vielleicht noch ne andere damit man sich das Ganze einfach mal vorstellen kann wie man jetzt mit Hilfe eines Factory Patterns. Mehr Struktur in seinen Code bekommt. Und zwar möchte ich da, dass ihr euch alle, liebe Zuhörer, liebe Zuhörer, du und vor allem auch du Fabi euch folgendes vorstellt.
Ihr seid beispielsweise wieder in der Schule oder an der Uni, ihr hattet eine anstrengende Vorlesung deswegen oder oder gerade Unterricht und ihr seid so richtig ausgelaugt und was wäre jetzt besser als ein kühles Getränk, weil es ist warm draußen ja, also du hast jetzt so richtig Bock auf ein kaltes
Getränk und. Und dann steht er da, am Ende des Ganges, leuchtend der Getränkeautomat, und du rennst dahin mit deinen letzten Münzen in der Tasche und möchtest dir jetzt noch ein schönes kaltes Getränk holen und stehst davor und siehst die verschiedenen Knöpfe, weißt erst mal gar nicht, was du nehmen sollst. Nimmst du eine Cola, eine Cola light, ein Wasser, eine Apfelschorle vielleicht und eine Spezi gibt es auch für dich kein Problem, hat der Automat am
Start und. Und ja, was passiert jetzt? Du schmeißt dein Geld rein und drückst einfach auf n Knopf und sagst zum Beispiel Wasser und du bekommst ne Wasserflasche daraus, vorzugsweise wahrscheinlich n halber Liter PET Flasche, aber du bekommst n Wasser. Hättest du jetzt Cola gedrückt, würde der Automat dir Cola
geben. Das heißt abhängig davon, was du dem Automat als Eingabe gibst, kriegst du dementsprechend den Output. Ja, und das kann man sich jetzt wieso n neues Objekt getränkt vorstellen, nur das ist in dem Fall wenn ich Wasser drücke und Wasser ist wenn ich Cola drücke ist es ne Cola. Das heißt, in diesem Fall ist der Automat genau diese Factory und das Pattern, was wir heute
besprechen wollen. Denn die Logik was du bekommst an Getränk, also als Getränk, ist quasi intern im Automat gegeben und abhängig von deiner Knopfeingabe sagen wir mal da drin ist ne Art Switch. Ja FLS wie auch immer. Wird entschieden, welches Getränk ausgegeben wird. Das heißt, für dich spielt es gar keine Rolle, wie intern ausgewählt wird. Es spielt für dich nicht mal eine Rolle, wie dieses Getränk da überhaupt rein gekommen ist.
Dass das irgendwer aufgefüllt hat oder wie das Getränk abgefüllt wurde oder was auch immer es spielt für dich in dem Fall keine Rolle, sondern es spielt nur eine Rolle. Ich möchte jetzt auf Wasser drücken und dann möchte ich bitte auch ein Wasser bekommen, der Rest ist mir egal und.
Und ich finde, daran kann man das schon mal ganz gut erklären oder beziehungsweise verstehen, was dieses Pattern eigentlich für n Ziel hat am Ende. Ja, also du kriegst ja im Endeffekt sozusagen ein, wenn man jetzt so n bisschen, weil du ja auf Switch und IF und so eingegangen bist. Du kriegst ja am Ende so so ne Art, ich sag mal Objekt Getränk.
Und was es dann aber speziell für ein Getränk ist, das ist im Endeffekt erstmal, sage ich jetzt mal egal, weil das dieser Getränkeautomat kann nur Getränke ausspucken und dann ist es natürlich wichtig. Was ist es denn wirklich
speziell für ein Getränk? Also wenn du jetzt zum Beispiel sagst Wasser ist dann zum Beispiel auf 1 und dann hast du zum Beispiel if Eingabe 1 dann Wasser if Eingabe oder Else IF oder so und so weiter und sofort oder mit dem Switch wie du meintest um sich das jetzt mal ganz explizit vorzustellen und dann kriegst du halt einfach dein dein Getränk da raus. Ja finde ich gut, ich finde das. Also ich hab hätt noch ne andere Analogie, vielleicht noch mal so n bisschen um die Vielfalt
rauszubringen. Wenn wir jetzt schon bei Cola und und ungesunden Getränken waren, dann möchte ich jetzt noch n ungesundes Essen ansprechen. Oh, jetzt bin ich gespannt. Zum Beispiel Pizza, ne. Also wenn ihr jetzt zum Beispiel was. Ungesund. Ja, natürlich nicht.
Pizza ist sehr gesund, sollte man jeden Tag essen, mindestens 3, mindestens 3, ja wenn nicht mehr, nein, auf jeden Fall, ich finde, daran kann man sich das auch oder kann ich mir das ganz gut vorstellen, wenn man sagt okay, du gehst in eine Pizzeria und möchtest jetzt eine Pizza bestellen und du weißt eigentlich okay egal welche Pizza du bestellst, du hast eigentlich immer den gleichen Pizzaboden, also der Teig von
dem Boden ist immer der gleiche. Die Soße da drauf, die Tomatensoße auch immer die gleiche, ne so und dann ist natürlich nur die Frage OK, was möchtest du jetzt drauf haben?
Ne du gehst jetzt zum Beispiel hin du sagst ich möchte ne Salamipizza bestellen, also bekommst du halt eben diese Grundpizza ne Teig und Tomatensoße plus dann Salami und Käse drauf ne oder du sagst ich möchte ne Hawaii Pizza haben und bekommst dann halt eben wieder diese Grundpizza mit halt Schinken und Ananas ich glaub so. Ungefähr geht nach Hawaii, bin ich jetzt nicht so Fan. Von Hawaii hast du doch nur gewählt, um jetzt hier Leute zu provozieren, die sagen Hawaii ist keine Pizza.
Ja, mal gucken, finde ich gut, finde ich gut, gleich war so eine Grundsatzdiskussion jetzt hier ausbrechen lassen. Ja ich bin auch kein Fan von Hawaii muss ich sagen, aber ist ja Geschmackssache, Geschmackssache.
Genau, aber im Endeffekt gehst du ja eigentlich dann am Ende aber auch nur hin und ne, also wenn du das ganze noch weiter abstrahierst, hast du ja in vielen Restaurants auch einfach nur zahlen, die dann zu mich dran stehen und sagst ja ich möchte jetzt die 10 ne und 10 ist dann am Ende beispielsweise die Salami ne und dann sagst du ich möchte aber zu mich die 14 und das ist dann aber die die Hawaii und wichtig ist ja nur, dass du weißt, du möchtest eine Pizza Punkt 1 und Punkt 2 ist
welche denn genau ne? Dann sagst du halt entweder den Namen oder die Zahl und bekommst dann halt eben am Ende diese Pizza. Und wie das jetzt aber hergestellt wird, wie du meintest ne keine Ahnung, du brauchst nicht wissen wie der Belag aussieht beziehungsweise wie der wie der da drauf gelegt wird, wie die Pizzateig Rezeptur ist, was in die Tomatensoße kommt alles egal. Das macht alles die Küche ne und wenn man das jetzt auf Code Ebene sieht, dann ist die Küche der Defactory und.
Innerhalb der Factory weiß der Code, was da passieren soll, aber du von außen, wenn du die benutzt diese Factory die brauchst, da brauchst du es nicht wissen, du willst halt nur die entsprechenden Pits und so ne. Und. Das ist im Endeffekt dann ja auch eine andere Analogie für so n Factory patter ne. Ja, was man daran auch wirklich. Also es ist auch n sehr gute Analogie, vielen Dank dafür, fabi. Weil wir ein wichtiger Punkt der ne Factory auch noch mit sich
bringt. Also das Pattern kann man daran
nämlich auch ganz gut erklären. Angenommen jemand bestellt jetzt ne Salamipizza, fängst du ja nicht an zu sagen ich setze jetzt n Teig an, ich rühre jetzt die Soße an oder stell diese Soße quasi her, hab dann den Teig, die Soße und dann den spezifischen Belag für die Pizza drauf, ne um ne Salamipizza zum Beispiel herzustellen, sagen wir mal das machst du ja nicht in dem Fall, sondern du hast ja wie du meintest diese Grundsoße, die ist fertig für alle Pizzen, das heißt du kannst sie wieder
verwenden und musst nicht jedes Mal neu definieren, wie diese Soße aussieht, welche Kräuter da reinkommen, wie auch immer, genauso der Teig, der ist fertig, das heißt du musst nicht jedes Mal wieder neuen Teig herstellen, nur um jetzt ne Salami oder was hast du gesagt ne Hawai Pizza zu machen. Ja und daran kann man nämlich auch gut erkennen welche Vorteile das mit sich bringt, weil du kannst ja sagen ich habe diese Grundpizza und die hat Eigenschaften.
Ja, zum Beispiel der Teig sieht so und so aus, die Soße da drauf ist in der und der Menge da drauf und so weiter und darauf aufbauend spezifizierst du dann ja nur noch wie du meintest die Pizza und kannst so quasi Objekte schnell und einfach herstellen, in dem Fall die Pizza.
Wenn wir jetzt noch mal n bisschen in die Coderichtung gehen, also quasi in deiner objektorientierung Objekte herstellen ohne zu wissen wie genau sie im Detail gebaut sind, wie der Teig aussieht, wie die Soße aussieht, aber du weißt du kriegst ne Pizza. Plus die Parameter, die du reingibst Salami oder Hawaii oder ne Nummer wie du meintest und hast dann am Ende n fertiges Pizzaobjekt, was deinen Ansprüchen entspricht, sag ich mal.
Der Code liefert es dir einfach ne und das ist eigentlich wirklich ne perfekte Analogie um einfach mal. Den Factory Pattern zu zeigen, also quasi auch diese Analogie mal zu programmieren, einfach sich zu sagen, ich habe jetzt ein eine basisklasse Pizza und habe dann spezifische Pizzen sozusagen die ich erzeugen kann, also alle, die jetzt diese Folge hören und das mal ausprobieren wollen, programmiert ruhig danach mal. Diese Pizzeria ist eine sehr
geile Übung. Was ich ein bisschen, also was, was mich früher am beim Start in die Softwareentwicklung, was mich immer so. Ein bisschen verwundert hat an diesem, an dieser Beschreibung von einer Factory, das das heißt, die Factory gibt ja ein Objekt und wie dieses Objekt am Ende gebaut wird, das ist dir egal, das brauchst du nicht wissen, das wird von der Factory bereitgestellt, das Macht der Code dahinter und du brauchst das Wissen darüber nicht und das
fand ich da dachte ich mal so, ich verstehe es nicht ganz am Anfang, da dachte ich mir, so wie ich bau. Bau doch diese Factory, dann weiß ich doch wie das funktioniert. So weißt du da dachte ich mir immer so, das macht doch gar keinen Sinn.
Natürlich weiß ich wie das da drin aussieht, natürlich muss ich wissen wie das passiert und das war für mich damals immer so ein kleiner wie sagt man so, da habe ich mir so ein bisschen den Kopf drüber zerbrochen, im Endeffekt ist es ja so, dass wenn du normalerweise später irgendwann mal in der Softwareentwicklung arbeitest, dann.
Dann schreibst du ja nicht den kompletten Code für die gesamte Anwendung. Das heißt, du schreibst vielleicht an einer Stelle und jemand anders schreibt an einer anderen Stelle, das heißt, eine Person hat beispielsweise diese diese Factory erstellt und du kannst sie dann für deine Aufgabe nutzen. Und in dem Fall ist es dann so, dass du natürlich darauf vertrauen solltest, dass die
Factory funktioniert. Ist ja auch deine Arbeitskollegin oder dein Arbeitskollege, der das dann implementiert hat, aber du kannst dann einfach nur sagen, OK, ich möchte jetzt Objekt AB oder C haben und das kriege ich aus der Factory raus, ne und das ist halt so n bisschen das war ich weiß nicht ob noch irgendjemand vielleicht genauso mal an diesem Punkt war, aber das das hat mich früher. Gerade im Studium habe ich das immer. Ich dachte, was wollen die denn von mir.
Natürlich weiß ich, wie das alles aussieht, ich habe es ja programmiert. Dann, ja, natürlich ist damit ja nicht gemeint, dass du eine Blackbox hast. Also gerade wenn du sie selbst entwickelst, also das Pattern selbst implementierst, geht es ja nicht darum, eine Blackbox zu haben, wo du nicht in den Code reingucken kannst. Aber um die Wiederverwendbarkeit und Skalierbarkeit, das ist ja das Entscheidende, dass du genau diese Factory an einer Stelle
definierst. Und dann das Hochskalieren kannst, indem du dir halt verschiedene Implementierung einer Pizza überlegst oder implementierst und die dann halt wieder verwenden kannst. Über deine Factory und das Entschlankt oder macht ja den Code schlank am Ende unvorinkalierbar. Ja, genau. Aber es gibt halt auch, um mal ein bisschen fachlicher zu werden und so mal richtig in das Design Pattern reinzukommen.
Es gibt ja verschiedene Formen des Factory Patterns, es gibt sozusagen so eine vereinfachte Factory, es gibt die klassische, was auch als Design Pattern so quasi in jedem Buch zu finden ist. Und es gibt noch darauf aufbauend eine erweiterte Form und die 3 würde ich gerne mal jetzt der Reihe nach mit dir besprechen und. Um einfach n guten Überblick zu geben und halt auch immer so n bisschen vor und Nachteile und Use Cases zu nennen. Und ich glaube dann haben wir hier im.
Vorfeld bevor wir jetzt wirklich in diese 3 Punkte einsteigen, würde ich vielleicht noch mal ganz kurz n kleinen mini Exkurs machen. Nur falls weil ich es könnte sein, dass 2 bestimmte Begriffe fallen innerhalb dieser, wenn
wir das jetzt durchgehen. Und zwar einmal Interface, also Schnittstelle und abstrakte Klasse, weil wir sind ja jetzt wie wie du schon meintest, in Objektorientierungsebene und damit man einmal vielleicht noch mal ganz kurz diesen ne, dass man dann vielleicht noch mal alle abholt, bei denen es vielleicht mal so n bisschen ins Grübeln kommt, so was war noch mal ne Schnittstelle und das würde ich einmal ganz kurz noch mal sagen und dann können wir direkt reinstarten also n
Interface ist im Endeffekt ja nichts anderes als eine.
Sammlung von Methodendeklaration also, dass du sagst, OK, du hast jetzt zum Beispiel bei, wenn wir jetzt bei der Pizza sind bei dieser ne, wenn wir jetzt von diesem Pizzabeispiel ausgehen, dass du einfach sagst sowas wie mach Soße drauf, das ist eine Funktion wo also ne die die da zum Beispiel irgendwie sinnvoll wäre, weil du musst ja irgendwie Soße drauf machen, ne als Beispiel und dann hast du vielleicht noch andere, aber du hast im Endeffekt nur diese leeren Hüllen von Methoden, die
einfach so. Für jede Pizza angewandt werden müssen und die dann aber für jede Pizza selbst implementiert werden müssen. Also du sagst nur, das muss passieren bei der Pizza, also du musst auf jeden Fall Soße drauf tun, wie genau ist bei dem Interface nicht festgelegt, das heißt du hast im Endeffekt nur du weißt nur was passieren soll, aber du weißt nicht genau was passieren soll.
Also im Einzelnen. Und wenn du jetzt sagst, du hast eine abstrakte Klasse, das ist ja ein bisschen ähnlich, kannst du ähnlich verwenden, nur dass eine abstrakte Klasse zwar auch sowas haben kann, wieso eine abstrakte Methode wo du sagst okay es gibt keine Implementierung dafür, aber es muss implementiert werden in der entsprechenden Klasse, aber es gibt auch konkrete Methoden, also wo wirklich eine
Implementierung drin ist. Und wenn du jetzt zum Beispiel das Gleiche mit einer Pizza machst kannst. Könntest du zum Beispiel sagen, wenn du dieses Interface Pizza hast, wo du sagst paktros Soße drauf, dann müsstest du, wenn du 2 verschiedene Pizzen implementiert, also implementierst müsstest du bei jeder Pizza sagen okay pack mal bitte Soße drauf, zum Beispiel eine Kelle und bei der anderen zum Beispiel auch eine Kelle oder 2.
Wenn es mehr oder weniger sein soll, wenn du eine abstrakte Klasse nimmst und dieses in dieser abstrakten Klasse, dass die Methode packsoße drauf hast, dann. Dann könntest du immer festlegen, weil wir auch vorhin meinten, es ist immer die gleiche Menge.
Sagst du dort einfach, mach mal eine Kelle Soße drauf in dieser Methode und dann kann quasi eine Salami Pizza kann dann im Endeffekt eine Pizza sein und je nachdem ob es dann ein Interface ist oder eine abstrakte Klasse, von der ich sag mal die entsprechende spezifische Pizza ableitet oder erbt. Hast du dann sozusagen die Möglichkeiten zu sagen, OK, muss ich das immer selbst implementieren oder ist es vielleicht schon an der einen oder anderen Stelle schon
vorimplementiert? Ja, also den Unterschied zwischen Interface und der abstrakten Klasse sehen wir dann auch in den Factory Pattern auch noch mal genau explizit sag ich mal, weil das ist nämlich genau der Unterschied zwischen so einer einfachen Factory und sag ich mal dem offiziellen Factory Pattern. Ja, aber ja, es ist natürlich ein wichtiger Unterschied und auch nicht so trivial, aber.
Also für also wenn man selbst halt manchmal so denkt, ja, ist ja klar was n Interface ist, was ne abstrakte Klasse ist. Nein, so klar ist das nicht gerade am Anfang nicht. Deswegen gut, dass du es noch mal erwähnt hast. Und ich weiß nicht, wie es bei dir ist. Jedes Mal, wenn ich drüber nachdenke, muss ich auch erstmal
wieder drüber nachdenken. Also es kommt nicht so wie aus der Pistole geschossen, dass ich sage ja, hier das und das, sondern erstmal noch mal kurz im Kopf differenzieren und dann quasi versuchen zu erläutern, das ist nämlich gar nicht so trivial am Ende. Ich find was man sich auf jeden Fall merken kann ist n Interface, da steckt niemals Logik drin. Es sagt immer nur, was muss passieren, aber nicht, wie es passieren muss. Und bei einer abstrakten Klasse kannst du beides machen.
Du kannst einmal auf der einen Seite sagen, OK, was muss passieren und du kannst aber auch noch zusätzlich sagen, wie soll es denn genau konkret passieren, so das ist so n bisschen das eigentlich das was man damit machen kann. Also ich würde sagen ne abstrakte Klasse ist halt mächtiger als n Interface. Ja genau, also in Interface kann man sich halt merken, ist halt so ne Art Vereinbarung, sagen wir es mal so, also es ist halt ne Definition.
Damit beide Seiten, die das verwenden, also der es erzeugt und der es verwenden möchte, weiß, was drin sein wird. So ne OK, aber dann lass uns direkt mal mit dem ersten Anfang und zwar mit der simple Factory, weil da kommen jetzt auch genauso die Interfaces zum Einsatz. Also wie gesagt noch mal die Anmerkung, Es ist kein offizielles Pattern, aber es ist sehr verbreitet und gerade am.
Anfang eines Projekts sehr einsteigerfreundlich, wenn man so schon mal n bisschen was strukturieren will, aber vielleicht noch nicht so ne Riesenkomplexität drin hat, dass
es nicht mehr ausreicht. Deswegen ist es eigentlich immer n ganz guter Start damit anzufangen und man kann sich das so vorstellen, dass man jetzt dieses simple Factory hat, also eine zentrale Klasse. Die eine Methode bereitstellt beispielsweise eine Create mit einem Eingabeparameter, also zum Beispiel, wie wir bei der Pizzeria hatten, zu sagen, man kippt noch rein, welche Pizza ja zum Beispiel als String kann man
ja machen. Ja, wenn du jetzt einfach sagen möchtest Salami oder oder ne Nummer vom vom vom vom Menü sozusagen und daran wird dann quasi entschieden was erzeugt wird, das heißt diese Create gibt dir dann am Ende dein Objekt zurück, was du haben möchtest, oder?
N anderer, n anderes Beispiel ne, was ich auch schon oft gelesen hab und das macht auch Sinn, wenn du dir jetzt so zum Beispiel vorstellst, du gehst Fastfood essen, ja du gehst jetzt zu mcdonald's zum Beispiel, dann stellst du dich ja auch an die Kasse und sagst ich hätt gern n Cheeseburger so das wird aufgenommen. Der Satz Ich hätte gerne einen Cheeseburger ist klar, die Küche weiß, was zu tun ist.
Ja, zum Beispiel jetzt und so. Factory mcdonald's Kitchen ruft die Create auf und sagt Cheeseburger so, dann geht es in der Küche zur Sache. Dieser Cheeseburger wird hergestellt und zwar ist es und jetzt kommt ein Interface, ganz klar wie n Cheeseburger auszusehen hat. Ja also dieses Interface wurde für den Cheeseburger implementiert, das heißt Brötchen keine Ahnung Patty. Was kommt da? Kommt da überhaupt noch ne Gurke drauf, keine Ahnung, klar das war da glaub ich noch nie drauf.
Nee, OK. Ja, Käse klar, Käse Käse wär gut beim Cheeseburger. Ich hoffe, dass da Käse drauf ist. Weißt du zugeklappt eingepackt raus, du kriegst das und hast deinen wunderbaren Cheeseburger. Vorteil an dieser Implementierung ist, dass es halt schnell, einfach und übersichtlich erstmal ist. Ne, weil du hast dann diese eine Funktion und du kannst dir tausende Cheeseburger erstellen, damit ne du sagst ihn immer wieder. Das hatte ich gerade gesagt.
Ja, mcdonald's Kitchen Punkt create gibt es Cheeseburger als Parameter rein und du kriegst n Cheeseburger so der Nachteil ist ist genau das was du nämlich jetzt gerade gesagt hast. Aber jetzt möchte ich aber n normalen Hamburger jetzt möchte ich oh Mann jetzt komm ich ins Schwimmen was gibt es bei mcdonald's? Ja super super Mcchicken oder wie die heißen ja also es gibt halt ziemlich viele Burger.
So, und da kommt nämlich dann der Nachteil, weil wir auch bei den Getränkeautomaten meinten, man kann das ja zum Beispiel mit einem Switch machen, nur dann kommst du halt relativ schnell bei steigender Komplexität in die Switch. Hölle also weil du einfach alle Fälle. Sauber unterscheiden musst, weil du ja immer explizit diesen einen Burger rausgibst und dieser eine Burger implementiert quasi deine Schnittstelle wie es aussehen soll und definiert.
Das ist n Cheeseburger, das ist NN Big Mac gibt es n Big Mac so Big Mac oder oder oder n Chicken Burger oder so ne ich find das heißt. Ich muss das jeden type erkennen ne also ich find es gut, dass du sagst auch es gibt n Burger raus, weil am Ende sagst du ja ne irgendwie die Küche. Create und dann zum Beispiel Cheeseburger, Hamburger oder was
auch immer. Was am Ende rauskommt ist ja ein Burger, ne, du sagst ja du kriegst einen Burger und was aber quasi der also du kriegst n Cheeseburger oder n Hamburger der aber im Kern n Burger ist ne und wenn wir jetzt zum Beispiel davon ausgehen, dass wir dann am Ende n Interface, also Burger ist n Interface und du kannst halt sagen ja OK, der Cheeseburger muss halt alle Methoden vom vom Burger quasi
implementieren. So, das heißt du weißt auf jeden Fall auf einen Cheeseburger kommt, also dafür brauchst du Brötchen, dafür brauchst du ein Patty, dafür brauchst du Soße zum Beispiel und das ist bei einem Hamburger genauso. Du brauchst auf jeden Fall auch wieder ein, also ein Brötchen und du brauchst auch wieder ein Patty und du brauchst auch Soße, es ist vielleicht was anderes je nach Burger und das ist halt
genau dann sozusagen. Dass du zwar sagst, OK, das muss alles da sein, aber es muss einzeln implementiert werden in den entsprechenden expliziten Klassen dann ne, also der Cheeseburger weiß nur was passieren muss, aber wie genau, das musst du im Cheeseburger festlegen. So ne genau. Und da haben wir nämlich genau das Problem. Wenn du jetzt sehr viele Burger
hast. Ja, also ich find das mcdonald's Beispiel ist gar nicht so schlecht, weil das kann man sich auch gut vorstellen, weil es noch n bisschen komplexer ist
als ne Pizza sag ich mal. Also komplexer im Sinne von der Variantenvielfalt. Wenn du jetzt nämlich wirklich grundverschiedene Burger hast und du gehst, aber das mit so einem simple Factory Pattern Ansatz so wirklich ganz simpel gehalten mit einfach so einer create Methode, ja dann hast du halt das Ding, dass du wie du meintest, das Interface immer neu implementieren musst. Ne, wie wird dieser Burger
hergestellt? Na ja, ich brauch das Brötchen OK ich hol mir das Brötchen. Was brauch ich jetzt für n Patty? Ja, Chicken Beef gibt es noch was drittes? Nee ich glaub die beiden so, da musst du da schon mal entscheiden ne und das muss ja jeder Bürger für sich implementieren, damit der am Ende dem entspricht wie er gedacht ist. Sozusagen ne richtig und da merkt man schon das ist doch viel doppelte Arbeit, ja. Wieso soll ich komplett neu definieren, wie n Cheeseburger aussieht?
Wenn n. Hier gibt es doch auch so mit Jalapenos so ne Chili cheese sag ich mal ne wenn der doch eigentlich der gleiche Burger also geh ich jetzt mal von aus der gleiche Burger ist nur, dass du nur noch n paar kleine Jalapenos da drauf legst. Weißt du da muss ich das doch nicht komplett neu definieren, wenn das der der gleiche Burger eigentlich im Kern ist. So und da merkt man schon hm.
Das skaliert doch nicht. Also wenn ich jetzt wirklich ne riesen burgerkarte hab, das wird nicht skalieren so ne und da ist nämlich dann auch der Nachteil bei der Simple Factory, dass man sagen kann, bei wenig Variantenvielfalt ist es schnell und einsteigerfreundlich implementiert und ausreichend völlig okay zu starten, weil Stichwort refactoring wenn du merkst, ah nee, irgendwie mill ich meinen Code jetzt doch zu, also das ist jetzt anstrengend, da diese ganzen Cases zu
unterscheiden, dann kann ich ja immer noch. Refactan und vielleicht auf das eigentliche Factory Pattern kommen und das würde ich jetzt gerne mit dir besprechen, um einfach auch da mal den Unterschied zu zeigen und welchen Mehrwert es bringt, auch wenn es natürlich Anmerkung nicht ganz so einsteigerfreundlich ist, weil es einfach ein bisschen mehr Aufwand hat. Ja, also bisschen mehr Overhead an Code hat am Anfang ja ja auf.
Jeden Fall. Also wenn ich jetzt zum Beispiel dieses Factory pattern, so wie es vielleicht dann auch angedacht ist, nehme. Würde ich einmal kurz vielleicht direkt den Unterschied zum zum simple Pattern mit dem Burgern
darstellen? Ne, weil wenn du dir jetzt zum Beispiel überlegst, du hast in in diesem Burger, den du haben möchtest, du meintest ja Cheeseburger und Chili Cheeseburger ne, also es klingt ja schon fast gleich und bei dem wenn wir jetzt noch mal dieses dieses Beispiel mit dem Interface haben, dann steht ja in in dem Interface drin, du brauchst ein Brötchen. So, und dieses Brötchen musst du ja dann sozusagen im Cheeseburger definieren.
Also ne, du brauchst ein Brötchen, musst du da in ne Logik reinpacken wie zum Beispiel Return? Weiß nicht simple Bun oder so ne, also ein ganz normales Brötchen und das gleich diesen gleichen, exakt gleichen Code musst du ja noch mal im Chili Cheeseburger definieren, das heißt du hast ja eigentlich quasi ne Code dopplung, die du eigentlich nicht doppelt brauchst. So und das bringt aber nun mal jetzt sozusagen so ein Interface mit sich, wenn du sozusagen ne Factory über so ein Interface
nutzt, ne? So ein simple Factory. Wenn du jetzt aber wirklich diese diese Factory patter nimmst und sagst an der Stelle okay wir nehmen jetzt aber eine abstrakte Klasse an dieser Stelle, dann können wir bei einem sagen du hast einen Chili Cheeseburger und du hast einen Cheeseburger und das Ganze hat eine abstrakte Klasse, von der geerbt wird sozusagen, die ist einfach ein Burger und dieser Burger hat nimm ein Brötchen und ich.
In dieser Burger Klasse, in dieser abstrakten Klasse ist schon definiert, dass du für deinen Burger, für die also einmal den Cheeseburger und den Chili Cheeseburger jeweils das normale oder das einfache Brötchen nimmst. Und damit hast du diese Implementierung schon in der abstrakten Klasse drin und musst es nicht zweimal im Cheeseburger und im Chili Cheeseburger sozusagen implementieren. Und das hilft dann halt sozusagen bestimmte.
Eigenschaften schon zusammenzufassen, um halt eben diese Codeduplikation zu vermeiden. Wie du meintest, weil stell dir vor, du hast n burgerrestaurant, ne was du jetzt in in weiß ich irgendwie programmierst in einem Game oder so wo immer der Gleiche es sind immer nur die gleichen Burgerbrötchen ne du hast niemals andere burgerbrötchen, da macht es keinen Sinn. In 20 Bürgern beispielsweise wirklich 20 mal den gleichen
Code zu machen. Ich mein, da kommt man ja relativ schnell hin und denkt sich so okay irgendwie müsste ich das ja vielleicht vereinheitlichen können. Genau, nimm ne abstrakte Klasse und kein Interface an der Stelle um das jetzt mal so direkt im Vergleich zu sehen, ne.
Genau. Und dann dann quasi alle, die dann so richtig auf Vererbungen in der Objektorientierung stehen, die können das natürlich bis auf die Spitze treiben, dass du sagst, ich hab ne klasse Burger, die ist abstrakt, ne und dann gibt es n Cheeseburger und den kann ich auch noch mal weiter vererben zum Chili Cheeseburger, der eigentlich nur n Cheeseburger ist, wo ich am Ende halt wie gesagt noch lalapenos drauf mache oder irgendeinen anderen Burger, wo
auf einmal Salat und Tomate drauf ist oder irgendwie so. Also du kannst das ja immer weiter Kapseln sozusagen und das Factory Pattern dann halt so richtig ins Spiel bringen, sag ich mal. Aber ich find n anderes Gedankenspiel dabei auch noch gut, um sich das noch mal vorzustellen, wofür so n Factory Pattern auch gut ist. Wir haben ja jetzt gesagt, du hast n burgerladen ja, mcdonald's als Beispiel, jetzt ist mcdonald's vielleicht sehr standardisiert. Länderübergreifend, so wie ich
es jedenfalls kenne. Also wahrscheinlich wird es schon Unterschiede geben, auch wahrscheinlich in den, es ist ja irgendwo n Franchise am Ende, das heißt du hast wahrscheinlich auch n bisschen andere Karten oder Aktionen whatever aber es ist schon so standardisiert, dass ich glaub ich würd ich jetzt mal sagen, so n cheeseburger. In fast jedem Land gleich ist ne.
Das heißt, das wäre ja auch wieder so n bisschen Richtung Simple Factory, auch wenn es halt wie gesagt zu viele verschiedene Burger gibt, aber da würde das ja noch so halbwegs funktionieren zu sagen, Hey Cheeseburger ist doch immer gleich, ja brauch ich es auch wirklich nur einmal machen, aber wenn man das n bisschen allgemeiner formuliert und ich hab jetzt einfach n Burger ne Burger Kette oder n Burger laden ne wo ich einfach gut Burger essen gehen kann ja dann sieht
ja dieser Laden oder? Sagen wir mal so, ich möchte einfach einen Burger bestellen und ich gehe jetzt in verschiedenen Ländern in einen entsprechenden Laden und kaufe mir einen Burger, dann sieht er ja natürlich beispielsweise im asiatischen Raum anders aus als im in der USA zum Beispiel ja, in der USA ist die Wahrscheinlichkeit ja schon groß, sowas Big Mac Artiges zu bekommen.
In im asiatischen Raum wahrscheinlich eher irgendwas asiatisch angehauchtes, ja vielleicht irgendwie so mit tiriyaki Soße in Japan oder so. Keine Ahnung, was geiles halt so ne, aber am Ende sind beides Burger, sind aber grundlegend verschieden. Also wie willst du jetzt anfangen mit einer simple Factory das alles abzubilden?
Das heißt da kommst du halt jetzt zu den offiziellen Pattern zu sagen es gibt ne abstrakte Burgerklasse ne es gibt Grundeigenschaften eines Burgers, aber je nach Land. Sind die Spezifikationen obendrauf anders?
Ja, für diesen Burgerladen, das heißt, meine Factory ändert sich dementsprechend auch oder die Burger, die ich damit erstellen kann, dass ich zum Beispiel sagen kann, hey, ich hab ne Factory und ich möchte jetzt n Burger und ich bin in Japan zum Beispiel und dann kriegst du halt deinen teriyaki Burger, ja oder ich sag, ich bin jetzt in der USA und Du kriegst halt n Big Mac so aber unter der Haube sind das abstrakte Burger, die selbst implementieren zum Beispiel deine Big Mac Klasse
Teriyaki Burger Klasse. Ich hab keinen besseren Namen, sorry, und da hast du jetzt den Vorteil, dass die eigentliche Erstellung ja wie das Objekt am Ende aussieht, dann in deinen
Subklassen ist. Das heißt, die Factory hat jetzt nicht mehr die Logik sowas wie OK, das Interface ich returne jetzt das Interface mit den und den Funktionen oder den und den Werten ja, sondern ich geb jetzt ne Subklasse zurück wie Big Mac Burger. Ja, weil die Factory wurde jetzt aufgerufen, mit Burger in der USA, Mhm so und dann geb ich ne Big Mac Klasse zurück und die Klasse selbst definiert jetzt wie der Burger ist und nach außen ist es dann halt wirklich
nur noch dieser abstrakte Burger. Erstmal ja so und das ist halt der große Vorteil, dass du halt so komplexe Abläufe damit dann auch implementieren kannst.
Zum Beispiel sowas wie. Länderabhängig Länderabhängig ist, weißt du ja. Ich meine, das ist ja, wenn man sich das zum Beispiel noch mal im Vergleich vorstellt, und du hast jetzt ein bisschen ein leicht abstrakteres Beispiel, du hast jetzt zum Beispiel ein Interface, ne, weil du ja meintest, das macht damit nicht so viel Sinn und stell dir vor, du hast am Ende ein Interface, wo alle Objekte eigentlich nur eine Methode teilen, die sie auf jeden Fall alle haben, und dann
aber zum Beispiel Objekt 1, ne, was du instanzieren möchtest. Hat dann aber 5 Funktionen von der von dem Interface noch und klasse 2 noch mal 5 andere. Das heißt du hast in deiner in deinem Interface 11 Funktionen, aber für die eine Klasse brauchst du eigentlich nur die Hälfte und für die andere auch n bisschen mehr als die Hälfte. Du hast also ne minimale Schnittmenge und denkst dir so, warum hab ich eigentlich n Interface mit so vielen Funktionen die ich aber am Ende
gar nicht implementieren muss? Also du musst sie quasi implementieren, was sind leerimplementierungen dann und? Und du denkst ja so, die brauch ich da ja gar nicht drin. Ne und das macht es dann an der Stelle irgendwann einfach nicht mehr sinnvoll, sozusagen so n simple Factory Pattern zu verwenden, sondern dann halt eben dieses Standard Factory
Pattern zu nutzen. Ne und ich find das ja, wenn wir jetzt das Ganze noch mal vielleicht n bisschen technischer erklären, weil mir bringt das manchmal auch irgendwie was, wenn ich mir dann denke so OK, ja gut, wann implementier ich denn jetzt mal ne ne Burger factory, weißt du? So, wo wird denn das? Überhaupt, ich hab jetzt genug über Burger geredet, ich hab erstmal Hunger, nur Pause ein. Aber zum Beispiel, wenn man jetzt sagt, du hast einen.
Ich bestell auch Grad nebenbei. Was willst du auch was? Ja komm. N. Cheeseburger und n Chili cheese würde ich gerne lesen. Wenn du jetzt aber pass auf wenn du jetzt sagst du hast ne UI oder so ne und du sagst ich möchte jetzt du hast ne Factory wie wie du sie gerade beschrieben hast.
Mit einem Button so und dann möchtest du einfach nur zum Beispiel einen Button haben und jetzt ist aber die Frage, auf welchem Betriebssystem hältst du dich denn gerade auf, weil jeder weiß das ja, dass zum Beispiel auf einem Mac das Ganze vielleicht ein bisschen anders aussieht als auf einem Windows PC, die UI oder vielleicht auch bei einem Linux oder?
Und damit du dann aber im Endeffekt sagst, ich möchte nur diesen Button, aber unabhängig davon, also ich möchte ja gar nicht, mir ist es egal welche auf welchem Betriebssystem ich mich befinde, diese Factory soll mir einfach den richtigen Button zurückgeben, den ich dann einfach meine UI einsetzen kann. Ja, das ist ein gutes Beispiel, weil ja der Button unabhängig vom Betriebssystem am Ende die gleiche Funktion haben wird oder die gleichen Fähigkeiten. Attribute nenn ich es mal ne.
Aber ich natürlich im Betriebssystem Style bleiben möchte. Gerade wenn ich jetzt so Cross Plattformen entwickle. Ja und ich sage, ich habe jetzt zum Beispiel ne Desktop application und ich möchte die aber auf eingängigen Betriebssystem anbieten können, dann macht es natürlich Sinn wie du gerade meintest erstmal zu gucken auf welchem Betriebssystem läuft diese Anwendung und dementsprechend Style ich sie oder baue sie wie auch immer an welchem Step wir jetzt sind ja und?
Das ist halt n cooles Beispiel, weil unter der Haube ist es ja der gleiche Button. Am Ende ne, der hat dann zum Beispiel irgendein Callback, wenn du ihn drückst der implementiert werden kann und das hat ja bei allen Betriebssystemen nur dass er halt vielleicht vom Styling anders aussieht. Richtig.
Und dann hast du sozusagen das Styling, ist unterschiedlich in den eigenen Klassen, aber dieser Callback, wie du ihn zum Beispiel gerade genannt hast, oder die Funktionalität, die dahinter steht n bisschen abstrakter. Ist dann halt eben in der Basisklasse vertreten.
Ne und und weil es ist ja immer das Gleiche dann für diesen entsprechenden Button, sagst zum Beispiel N submit Button und dann kriegst du halt wirklich diesen submit Button unterschiedlich gestylt, je nachdem Betriebssystem aber die gleiche Funktionalität, ne das ist auf jeden Fall dann der Sinn
dahinter. Das heißt, um das noch mal technisch sich vorzustellen, man hat dann im Code zum Beispiel ne Klassenabstrakte Klasse Button und die Implementierung davon wäre dann zum Beispiel N Windows Button oder N Linux Button. Ja, und die Factory gibt dir den abhängig von dem Betriebssystem, auf dem du bist. N Windows Button oder N Linux Button um es so n bisschen konkreter zu machen.
Und ja da sieht man ja eigentlich schon die die Vorteile einer Factory. Ja also du hast halt diese Austauschbarkeit, ne, das heißt mit jeder Subklasse die ich implementiere kriege ich halt auch so ne neue Implementierung rein ohne die anderen anrühren zu müssen. Ganz wichtiger Punkt ja wenn ich das Styling am Linux Button ändern muss ich nichts am Windows Button machen weil der
soll ja auch bleiben wie er ist. Das heißt, ich muss da am Code nicht drin rumrühren und kann halt potenziell Fehler einbauen.
Das heißt, die Austauschbarkeit ist halt auch gegeben, ne, wenn zum Beispiel der Linux Button einfach ganz anders aussehen soll oder vielleicht gar nicht mehr drin sein soll, oder dazu kommt, du kannst es halt einfach nebeneinander halten sozusagen, das heißt es ist auch besser testbar und wartbar ne wenn ich n Test schreibe für den Windows Button und den Linux Button änder, dann hab ich halt am Windows Button Test natürlich auch immer noch grün, hoffentlich am Ende ne wenn ich
es richtig implementiert habe das heißt? Wir haben halt keinen zentralen Code mehr, der alles wissen muss, sondern wir lagern es auf die Subklassen aus, was laut Objektorientiert einfach denn sauber getrennt ist. Ja, definitiv. Und im Endeffekt. Also es gibt natürlich auch Nachteile, es ist ja nicht immer nur so, dass es da die ganze Zeit immer nur ne Vorteil Vorteil, Vorteil, du brauchst natürlich n komplexeres Setup irgendwo ne, also du hast natürlich jetzt.
Also dein ganzer Code wird natürlich komplexer an dieser Stelle, weil du zum Beispiel ne, gerade wenn du sagst, du hast mehrere Objekte von einer, also die, die zusammengehören zu einer Familie, ne, dann brauchst du halt so ne so ne basisklasse, die dir sagt, OK ne, meine ganzen Bürger sind am Ende n Bürger ne die verschiedenen. Wenn du jetzt aber das ganze noch länderspezifisch spezifisch aufteilst, dann hast du
verschiedene. Burger, die zum Beispiel keine Ahnung, amerikanische Burger sind. Du hast Burger, die aber asiatische Burger sind, ne, und dann hast du wieder diesen diese beiden Burger Varianten, die aber am Ende auch wieder nur Burger sind, das heißt du holst dir natürlich ne höhere Komplexität, ne höhere Tiefe, ne in deinen Code rein. Und das kann natürlich auch dazu führen, dass es vielleicht n bisschen schwieriger am Anfang
durchzublicken ist. Ne. Deswegen heißt das andere ja auch simple Factory, weil es halt eigentlich eher n bisschen flacher Gehalt, also diese ganze Hierarchie n bisschen flacher hält. Aber wie gesagt, hier macht es mehr Sinn, wenn es auch n bisschen generell, wenn wenn diese ganze Abhängigkeit komplexer wird, dann also ne mit einer höheren Komplexität steigt meistens halt auch die Komplexität des Codes. Ja, es ist natürlich ratsam, immer zu gucken.
Je höher also auch, wenn die Komplexität steigt, Krieg ich es vielleicht doch mit möglichst wenig Komplexität in meinem Code hin, aber ab einem ab einer gewissen Ebene kommt man halt einfach nicht da dazu, dass man halt eine gewisse Komplexität vermeiden kann. Ja, und das ist auch ein gutes Stichwort, Komplexität, und das wäre so im Prinzip die dritte Stufe. Von den Pattern ist dann die sogenannte Abstract Factory, das heißt, wir fangen jetzt quasi
noch an, uns zu überlegen. OK, ich hab ne Factory und ich kann jetzt zum Beispiel länderspezifisch den Burger Design ne, also beispielsweise ich möchte n cheeseburger haben und der sieht halt wie gesagt in Japan anders aus als in der USA. So das können wir jetzt schon ganz gut abbilden.
Wie sieht das jetzt aber zum Beispiel aus, wenn wir ganze Produktfamilien haben und da kommt dann die Abstract Factory ins Spiel, das heißt, wir haben Produktfamilien, die Zusammengehörig sind, und das kann man an dem Beispiel, wir sind wieder bei dem Burger auch wieder gut erklären, weil ich hab jetzt nicht nur Bock n Burger zu essen, ich fühle es, ich möchte n Menü haben, ja. Ja.
Und. Habe jetzt quasi Burger, eine Beilage und ein Getränk. So und das alles natürlich so wie ich es erwarte im Stil des Restaurants, wo ich gerade bestelle, ja sagen wir mal zum Beispiel bei einem Cheeseburger in Amerika kriege ich halt so klassisch Doktor Pepper Cola keine Ahnung und Fries und in Japan zu meinem Teriyaki Burger will ich jetzt nicht unbedingt eine Doktor Pepper dazu haben,
sondern ich kriege. Ah, Klischee, auf keiner Matcha Tee oder so. Weißt du also was ich damit meine ist, du hast ja im Prinzip die Menüs die angeboten werden von dem Restaurant sind natürlich auch spezifisch und im
Stile ihres Restaurants ja also. Da, das wird sich ja denn grundlegend als gesamte Produktfamilie Burger Menü unterscheiden und da kommt halt denn die Factory ins Spiel, die Abstract Factory, die dann wiederum deine Factory so definiert, zum Beispiel, dass du sagst, ich bin in Japan oder in der USA und dafür sorgt, dass die einzelne Produkte, die jetzt ne Factory intern bereitstellen kann sowas wie gib mir einen Burger, gib mir eine Beilage, gib mir ein Getränk.
Dafür sorgt, dass es in sich zur gleichen Produktfamilie gehört, dass ich halt nicht sage, ich Krieg n amerikanischen Burger und ne japanische Beilage zum Beispiel, das wär auch Wahnsinn, das wär Wahnsinn, das nennt man Fusionsküche. Fusionsküche genau, aber weißt du, wie ich meine? Und ich finde, da kann man das eigentlich ganz gut dran erkennen, denn oder beziehungsweise verstehen, warum man diesen Schritt auch noch. Geht ja.
Wenn wir jetzt zum Beispiel noch mal dieses UI Beispiel von vorhin nehmen, ne und das noch zum Beispiel auch noch mal daran erklären, noch mal in die Technik n bisschen so abzutauchen ein wenig, dann ist es ja so, dass du zum Beispiel sagst, ich möchte jetzt ein, also meine UI Elemente haben, ne. Also nicht nur einen Button, sondern ich möchte vielleicht auch noch eine Checkbox haben oder ich möchte was gibt es noch einen Radio Button haben oder
was auch immer, so verschiedene Elemente, die aber auch wieder logischerweise entsprechend gestylt sind. Du kriegst ja nicht einen Mac Button in Windows Checkbox und eine Linux Radio Button, das wird ja im Endeffekt, also kannst du auch machen, wäre aber irgendwie blöd. So, und dann ist es halt im Endeffekt so, dass du halt abhängig vom Betriebssystem dir diese Familie holst. Von Ui Elementen, von denen du dann wiederum ein spezifisches
brauchst. Und im Endeffekt kann man sich das so vorstellen, dass Du eine Factory hast, die anhand des Betriebssystems und also unterscheidet, wenn. Welche Factory sie dir gibt, um den entsprechenden Einzelnen, das einzelne Ui Element zu bekommen. Das heißt du hast eine Factory die dir eine Factory ausspuckt, die dir dann am Ende wieder ein Objekt gibt.
Genau also im Prinzip. Das ist ein gutes Beispiel, und wenn wir jetzt noch mal so auf auf die Ui Elemente gehen, du definierst ja nicht jedes Mal. Also du, du erzeugst dir jetzt ja nicht eine Factory für Buttons und sagst jedes Mal wenn Du einen Button haben möchtest übrigens Windows. Und jetzt gib mir noch ne Checkbox. Übrigens Windows ja und dann machst du irgendwann den Fehler.
Übrigens Linux. Ach verdammt weißt du und deswegen gehst du quasi diesen Weg mit der Abstract Factory und sagst gib mir ne UI Factory Windows und die kann dir jetzt sagen create Button, create checkbox und es wird immer. Windows sein am Ende, weil du das unter der Haube quasi so definiert hast. Und dann musst du dir bei der Anwendung oder bei dem Erstellen der Objekte darüber keine Gedanken mehr machen und das bringt halt mehrere Vorteile mit
sich. Also erstmal, es ist konsistent, ja wie du gerade meintest, es passt alles zusammen, beispielsweise wenn ich betriebssystemabhängig bin.
Es ist super testbar. Ich kann die einzelnen Betriebssystem Stylings abtesten es ist austauschbar, ne, weil es muss ja nicht nur Betriebssystem abhängig sein, so ein klassischer Anwendungsfall sind ja auch so Themes sage ich mal ne habe ich ein helles Layout, habe ich ein dunkles Layout und ich möchte ja nicht bei jedem UI Element sagen, übrigens du bist gerade ein dunkles Layout oder ein helles Layout nein du willst es ja global irgendwo entscheiden und dann einfach
darauf arbeiten sozusagen oder wenn du eine Testumgebung erzeugen willst dann. Willst du ja auch sagen, gib mir mal meine Test Factory, ich will jetzt da was ausprobieren, zum Beispiel also das das bringt halt viele Vorteile mit sich schnell austauschbar auch zu sein. Ja Nachteil glaube ich kann man eigentlich ganz schnell erklären oder komplex. Ja klar, das ist natürlich die komplexeste Variante von allen Factories.
Und wie gesagt, ich ich persönlich würde auch darauf verzichten, wenn es nicht notwendig wäre, ne, also diese dritte Variante. Was ich noch sagen würde ist, weil das ist zum Beispiel auch n Punkt, der hat sich früher irgendwie ganz am Anfang von meinem Studium.
Zum Beispiel hat sich auch nicht so richtig erschlossen und ich würd das auch vielleicht noch mal so, weil ich denk mir so, vielleicht hat man mal das Problem gehabt, was vielleicht andere auch haben oder das Verständnisproblem, man kann sich ja jetzt hinstellen und sagen, was bringt denn eigentlich so ne Factory, wieso sag ich jetzt zum Beispiel nicht einfach ey, dann erstelle ich mir n neues Objekt davon und dann mach ich damit was und da an einer anderen Stelle nehm ich
mir halt n anderes Objekt. Ne was ich da halt vielleicht brauche und dann mache ich das halt ne, weil du ja meintest am Anfang um noch mal den Bogen zum Anfang zu schießen.
Du hast dann überall mal New Objekt von dem New Objekt von dem mach mal dies mach mal das ne und wenn du dir jetzt zum Beispiel vorstellst du hast n ne Anwendung auf deinem eigenen Server laufen und du sagst zum Beispiel OK ich möchte aber diesen Server, also ich möchte meine Anwendung überwachen und du hast jetzt zum Beispiel du fängst an und sagst OK ich
möchte jetzt. Diese, wenn irgendein Problem auftritt, möchte ich zum Beispiel mich selber notifizieren, ne mit einer e Mail so dann mach ich, erstelle ich irgendwie mir so NE Mail notifier und sag send mal die notification raus über die e Mail ne so und dann hast du aber vielleicht irgendwann denkst du dir so oh e Mail wirklich, das ist einfach da ich ich guck nicht immer so oft in die e Mails ich brauch das vielleicht als SMS oder so ne so das heißt
du sagst ey ich erstell mir jetzt noch n. Weiteren Notifire, nämlich einen SMS notifire und sende dann
sozusagen noch als SMS raus. So, und wenn du jetzt aber irgendwann sagst, weiß nicht SMS, ich habe manchmal irgendwie bin in einem Funkloch, aber Internet habe ich irgendwie, ich brauche das auch noch für eine App als push Nachricht, dann machst du noch einen Push notifire so ne, dann hast du 3 verschiedene Notifire, die du aber alle in diesem wenn jetzt zum Beispiel ein Fehler in deinem in deiner Anwendung auftritt, möchtest du über alle notifire dich notifizieren,
damit du auch wirklich mitkriegst. Es ist ein Fehler aufgetreten im System ne.
Und egal, wo du dich gerade aufhältst, entweder du hast kein Internet oder du hast einen Netzausfall oder du hast gerade keine Ahnung, mal wieder nicht in die e Mails geguckt, irgendwo willst du es halt herkriegen diese Information und dann möchtest du deinem Code aber nicht sagen, create new e mail notifeier und sende create new SMS notifeier und sende create new push notifeier und sende ne, das müsstest du ja für jeden, für jedes immer wieder noch mal neu machen.
Und wenn du jetzt aber sagst, ein e Mail notifier und eine SMS Notifier und Push notifier sind alles irgendwo notifier ist jetzt egal welche Factory an der Stelle und wie das genau implementiert ist. Aber du kannst dann zum Beispiel wenn du noch ein Notifier hinzufügen möchtest, kannst du alle in eine Liste von Notifier packen und dann mit einer vor darüber gehen und einfach sagen okay notifier send so, das heißt du hast einen viel eleganteren Code am Ende als immer zu sagen.
Also du musst natürlich diesen Notifire dann über deine Factory die entsprechenden Notifire erstellen und einen neuen
hinzufügen. Du musst aber nicht jedes Mal sagen okay, ich mache das jetzt für jedes erstelle ich ein neues Objekt und so weiter und sofort, sondern du nutzt immer nur die Factory sagst du möchtest ein bestimmtes neues Ding haben, kriegst es dann packst es in die Liste und wenn du jetzt zum Beispiel sagst, du hast eine Liste und in vielen Sprachen die jetzt auch Typsicher sind, kannst du ja nicht sagen, ich erstell eine Liste von einem Objekt.
E Mail notifire von dem Objekt SMS Notifire und von dem Objekt Push notifire weil es sind 3 unterschiedliche Objekte. Wenn du aber sagst das sind alles notifire, dann kannst du ne Liste von Notifirern erstellen und dann darüber iterieren und das sind manchmal so dann die Vorteile die das
dann am Ende mit sich bringt. So weißt du so Kleinigkeiten wo ich am Anfang wo ich mir weißt du das ist immer so bescheuert so am Anfang des Studiums dachte ich dann so was wie ja was brauche ich das ich verstehe den Anwendungsfall noch nicht und irgendwann kam ich an den Punkt wo ich mir dachte das ich würd das jetzt gern alles in eine Liste packen aber es geht nicht und dann irgendwann kam so diese Connection wo ich mir dachte Oh ne Factory weißt du und das kann man halt wie gesagt ist
unabhängig vom Typ der Factory kann man mit allen machen, die Implementierung ist dann sei mal dahingestellt, da haben wir ja auch schon n paar Beispiele genannt, aber das ist zum Beispiel finde ich n sehr sehr wichtiges Beispiel um zu zeigen so kannst du ne Factory nutzen als genau. Es hält halt den Code schlank, dann am Ende alright.
Genau dann hatten wir ja noch n konkretes Beispiel am Ende dann würde ich sagen lass uns doch mal noch mal kurz zusammenfassen, ich kann ja noch mal die meta Analogie Ebene zusammenfassen, die wir so quasi aufgebaut haben in dieser Folge also gehen wir noch mal quasi von. Unserem Burgerladen aus ne also die simple Factory ist ich geh jetzt hin und bestelle einen einzelnen Burger.
Ja, also wirklich nur ich bin in einem Laden, es gibt nur diesen Laden, es gibt nur einen definierten Cheeseburger und ich will n Cheeseburger haben, dann ist klar wie der aussieht und ich Krieg den ja das erweitert wenn wir jetzt gesagt haben na ja verschiedene Köche gleiche Karte aber unterschiedlicher Burger ne also ich kann jetzt bei verschiedenen Köchen.
Einen Cheeseburger bestellen und der wird halt unterschiedlich sein am Ende, weil es ja der unter unterschiedlich zubereitet wird, sehr wahrscheinlich, da hatten wir ja die Länderbeispiele genannt und da kommt halt die Factory, das eigentliche Factory Pattern ins Spiel, dass man sagt, gut, wir haben jetzt abstrakten Burger und der wird jetzt in den Subklassen definiert Cheeseburger und so sieht er aus und jeder implementiert sich seinen Cheeseburger, sozusagen
ne und dann abhängig davon wo ich bin, kriege ich dann dementsprechend den Cheeseburger und die Abstract Factory. Die maximale Ausbaustufe, sag ich mal, ist halt das Menübeispiel. Wenn ich jetzt n komplettes Menü haben möchte, dann krieg ich halt auch entsprechend immer passend Beilagen und Getränke beziehungsweise ich kann denn nur auswählen, was passend für den Laden dazu ist. Ja, also wie sieht das Burger Menü da aus? Genau. Und das ganze n bisschen
technisch. Kannst du es noch so n bisschen einordnen wo du was so ungefähr verwenden würdest? Zum Beispiel? Wir hatten es ja jetzt auch so in der Folge n bisschen angeschnitten. Ja, also simple Factory, ne, da hat man hat man eher zum Beispiel so n Interface was man verwendet für kleinere Projekte vielleicht Tutorials ne wenn man jetzt nicht so viele Varianten von Objekten von von von einem Typ hat, beispielsweise das Factory Pattern jetzt beispielsweise.
Wenn man dann mehr Objekte, wenn es komplexer wird, man halt mehrere Objekte hat, die vielleicht auch noch in Klassen wiederum gegliedert werden können, ne und also wie jetzt zum Beispiel halt ne, was du ja auch gerade beschrieben hattest mit deinen Beispielen und wenn du jetzt abstract Factory ne Abstract factory nimmst, dann bist du halt auf unterschiedlichen Objektfamilien unterwegs.
Dass du halt sagst, okay. Du kannst erstmal über das Factory Pattern kannst du dir ein eine bestimmte Familie überhaupt holen, dass man da gar nicht irgendwie sich vertun kann und dann ein spezifisches Objekt aus dieser Familie, das heißt du Filterst im Endeffekt ein bisschen vor, so und ja, dafür sind eigentlich die Sachen ganz gut gedacht, wie gesagt, es ist ich glaube so ein Abstract Factory.
Habe ich zum Beispiel selber noch gar nicht verwenden müssen, weil es ist auch immer die Frage, wann braucht man das
wirklich. Es ist, es ist ratsam, so was irgendwann mal einfach spaßeshalber zu programmieren, um es mal gemacht zu haben, aber das bedeutet noch lange nicht, dass es unbedingt wichtig ist, das anzuwenden, ne, aber wenn du jetzt zum Beispiel sagst simple Factory und Factory Pattern, diese beiden würde ich zum Beispiel schon als sehr hochfrequent einordnen und das ist durchaus wirklich wichtig, dass man auch dann. Das versteht und das auch
anwenden. Kann also. Die Abstract Factory ist sehr wahrscheinlich oder oftmals nicht notwendig selbst zu implementieren, weil man ja auch oft auf Frameworks und Libraries zurückgreift, die das unter der Haube implementieren. Gerade so in der Cross Plattform Welt wird das ja dir quasi genau diese Sachen werden die ja abgenommen dann am Ende ne, weil das halt unter der Haube so implementiert wurde. Aber das wäre auch so.
Ich würde gerne noch so ein 2 Tipps oder jeder ein Tipp kann man am Ende noch mitgeben so bevor ich die Folge schließe sage ich mal, das wäre nämlich auch genau mein Tipp gewesen, was du gerade angeschnitten hast.
Ist liebe Zuhörer, liebe Zuhörer, falls du dich mit dem Factory Pattern noch nicht so auseinandergesetzt hast oder immer noch ein bisschen struggles, weil du vielleicht gerade am Anfang der Softwareentwicklung stehst, probiere es aus, nimm dir die Beispiele unserer Analogien wie zum Beispiel mcdonalds oder dem Burgerladen allgemein oder die
Pizzeria oder. Und Programmier damit mal einfach n factory pattern, sag dir, ich mach jetzt n simple Factory, dann refactor ich das zum Factory Pattern zum Beispiel und ich probier auch mal ruhig n Abstract Factory aus, damit ich es einfach mal gemacht hab, dann sieht man einfach, welche coole Möglichkeit dieses Pattern bildet oder bietet um Code zu strukturieren. Ja, auf jeden Fall.
Und wie gesagt, am besten immer. Kleinen anfangen, sich dann wie du auch eigentlich meintest ne du hangelt, man hangelt sich einfach von der einen Factory zur anderen durch und ich würde auch einfach mal wirklich sagen OK wenn man das gemacht hat und diese Factory gebaut hat würde ich noch mal sozusagen daneben legen. Das gleiche Beispiel was du gebaut hast und keine Factory verwenden um einfach mal genau gegenüber zu diesen diese Gegenüberstellung zu haben.
Wie sieht es denn mit aus und wie sieht es ohne aus und was gefällt mir besser und die Antwort liegt nach dieser Folge eigentlich auf der Hand. Ja. Sehr gut. Ich denke, wir haben es sehr umfangreich besprochen, da sieht man mal, dass man zu so einem Designpattern echt viel erzählen kann, gerade wenn man damit mal
so n bisschen Analogien bringt. Aber ganz ehrlich, das hilft einfach mega das zu verstehen, das hat mir damals geholfen und ich hätte mir gewünscht, dass mir jemand das mal so anhand von einfachen Beispielen erklärt und deswegen vielen Dank dafür, Fabi ebenso Liebe zur Liebe zur falls dir die Folge gefallen hat oder du Anmerkungen hast zu den Pattern oder Fragen, schreib uns gerne. Alle Links zu den Plattformen oder auch unsere Podcast Mail findest du in den Shownotes.
Wenn dir der Podcast allgemein gefällt, lass auch gerne ne Bewertung da, das hilft uns quasi weiter zu wachsen und noch mehr Leuten unseren Content anbieten zu können und damit noch mehr Leute davon profitieren können. Und ja, ansonsten würde ich sagen, hören wir uns alle beim nächsten Mal wieder. Und lasst euch den Burger schmecken. Und lasst euch den Burger, ich geh jetzt Burger bestellen. Und habt ne gute Zeit bis dahin und bis zum nächsten Mal deine Coding Bodys. Gemeinsam besser.
