Heute wird es um objektorientierten Entwurf gehen. Also das ist der,
was ich so ein bisschen kontinuierlich durch sowieso,
was sowieso Hauptthema der heutigen, der ganzen Veranstaltung ist.
Und heute werde ich das Thema heute allein bestreiten.
Sie haben schon gesehen, Fred ist nicht da.
Heute gibt es ohne Java. Aber das ist,
nächstes Mal steht er uns wieder zur Verfügung.
Er hat heute eine andere Veranstaltung und ich habe mich sehr gefreut,
dass ich den Zeitblock heute von ihm mitnutzen kann.
Worum geht es? Es geht heute um Klassenentwurf.
Wir fangen an damit, dass wir durchaus nochmal,
also uns gegenwärtigen, was wir beim letzten Mal gesprochen hatten,
Qualität ist das Ziel und worum geht es bei diesem Klassenentwurf
Ich möchte gern zu Entwurf noch ein bisschen was mehr sagen.
Sie kennen, haben bis jetzt häufig,
oder die meisten von ihnen, haben Kontakt mit ganz kleiner Software-Systemen.
Ja, also da gibt es ein paar Klassen,
die machen zusammen irgendetwas. Sie kennen diese Mediathek,
sie kennen kleine Java-Beispiele und das ist das,
was man typischerweise auch nur in so einer Veranstaltung hat.
Das, was wir aber mit Entwurf machen und die Probleme mit,
wenn man sich in Softwaretechnik beschäftigt, sind für große Systeme.
Und das ist ein bisschen mein Dilemma.
Ich rede über Techniken, die Sie brauchen,
um große Systeme zu bauen
Zeigen kann ich ihnen aber nur kleine Systeme.
Auch in der Übung können wir nur kleine Systeme besprechen.
Das hat mit der Zeitbeschränkung zu tun,
die ich immer hier habe, diese 90 Minuten.
Und in der Übung haben sie 6, 8, 14 Termine übers Semester.
Das ist nicht wirklich Zeit für richtig größere Sachen.
Es gibt natürlich, das ist glaube ich, Züchter sehr,
es gibt natürlich die Möglichkeit, dass sie ein Projekt machen.
Das ist im Bachelorstudium, bei den meisten Studiengängen vorgesehen.
In diesem Projekt haben sie die Gelegenheit ein bisschen was Größeres zu machen.
Das ist schon mal toll. Prinzipiell ist es aber so,
dass ich einfach nur jetzt an sie ihnen versuchen muss zu verdeutlichen,
was denn die Probleme von größerer Software sind
Und darum geht es beim Entwurf, beim Entwurf geht es nicht.
Darum, die kleinen Sachen zu bauen. Die kriegen sie
alle mal hin. Da müssen sie nur verstehen,
was ist eine Klasse und welche Anweisung hat die Programmiersprache.
Vielleicht noch das eine oder andere Fremdwirken, sie müssen die
Tools beherrschen. Aber wenn wir von größeren Systemen sprechen,
dann sprechen wir damit, dass die arbeitsteilig entwickelt werden.
Das heißt, die Ideen, die einer hat,
sind noch lang nicht bei den Ideen, im Kopf des anderen angekommen.
Und die beiden müssen aber was entwickeln,
was am Ende ein großes Ganzes ergibt.
Das heißt, das Ausdrücken von Ideen in Software,
das ist eigentlich die Kunst. Es ist nicht die Kunst,
ein bestimmtes Feature zum Laufen zu bringen,
sondern es so zu machen,
dass der Kollege es auch versteht,
und zwar beim Ansehen des Quelltextes
Wir haben manchmal in den Projekten, haben wir Leute.
Ich hatte vielleicht schon erwähnt,
dass ich auch eine Industrieerfahrung habe als Projektleiter und Softwarearchitekt.
Da haben wir in den Projekten, haben wir Leute,
die sind clever, haben gute Ideen,
können mit Technologie ausdenken und sind aber nicht richtig ausgelastet.
Und die haben manchmal so einen Spieltrieb mit der Technologie,
was zu machen. Und dann zeigen sie einem was und sagen,
das und das ist das nicht toll und es funktioniert sogar.
Und als Projektler, da möchte man sagen, raus,
raus aus meinem Projekt. Die Leute senden,
wenden Tricks an, die irgendwie funktionieren,
die an den Grenzen der Technologie sind.
Und die keiner versteht
Wenn ich dem sage, das verstehst du selbst in einem
halben Jahr nicht mehr, geschweige denn irgendeiner deiner Kollegen.
Solche Leute will man in Projekten nicht haben. Aber nicht deswegen,
weil ich jetzt schlaue Leute nicht mag,
sondern weil Software arbeitsteilig entwickelt werden muss,
weil Software über einen langen Prozess aufrechterhalten muss.
Wir müssen immer Änderungen machen. Auch nach zehn Jahren,
nach 15 Jahren müssen wir noch Änderungen machen an der meisten Software.
Die wenigste Software ist nach einem Jahr nicht mehr im Betrieb.
Viele Software ist nach 30 Jahren noch im Betrieb.
Und nach 30 Jahren muss das noch jemand verstehen.
Und deswegen müssen wir klare Konzepte haben. Deswegen sprechen wir mit Ihnen hier über Werkzeugautomatmaterial,
diese Einteilung, die ist ja eigentlich, wenn Sie so betrachten,
irgendwie willkürlich ist oder manch einer mag sagen, philosophisch.
Wir versuchen seit uns unserer eigenen Gedanken beim Entwurf klar zu strukturieren,
die Technologie so zu benutzen,
dass sie klar benutzbar ist und natürlich auch noch weitere Qualitätsmerkmale erreichen.
Das ist jetzt auf der nächsten Folie, sind diese Qualitätsmerkmale unten nochmal angegeben.
Wir wollen vor allen Dingen die Wartbarkeit erreichen, ja,
also Wartbarkeit steht hier, Maintainability da unten mit den Untermerkmalen,
einfach zu verändern.
Wir werden heute, ich werde heute über die Vorlesung verteilt,
über einige Entwurfsprinzipien sprechen. Diese Entwurfsprinzipien haben immer beide Ziele,
vom Menschen klar verständliche Konzepte zu produzieren und Entkopplung zu erreichen.
Entkopplung, dass sich eine kleine Änderung nicht über ein
ganzes System ausbreitet
Das ist also das Ziel von Softwareentwurf.
Große Systeme beherrschbar zu bauen. Sie können sich vorstellen,
also ein Beispiel ist immer Flugzeug, da kann sich jeder von uns vorstellen,
dass da ganz viele komplizierte Techniken da drin sind.
Das kann man nicht mal einfach nur so bauen. Einfach nur so bauen,
kann man so ein kleines Flugzeug als Papier unter Holz oder vielleicht auch noch aus einem Bausatz,
was mit einem kleinen Motor fernsteuerbar ist, das kriegt man so hin.
Aber ein Flugzeug, was auch tatsächlich Kollisionswahnsystem und Nachtflug,
Radar und Versorgung für 300 Leute,
die da drin sitzen und Energie auch noch,
dass es auch noch weiter fliegt,
wenn zwei von vier Phänobinen ausgefallen sind
Und wenn da vorne ein großer Vogel davor crasht oder solche Sachen,
das ist nicht so einfach zu beherrschen.
Ja, da müssen viele Leute arbeitsteilig zusammenarbeiten. Und das
geht nicht, wenn da einer eine kreative Idee hat,
die irgendwie halbwegs noch funktioniert. Technologie, Softwaretechnologie spricht von Methoden.
Und das ist das, was wir beim Entwurf vorrangig machen.
Ich bin auch gleich fertig mit meiner Vorrede. Aber die
Methoden heißt, wir folgen bestimmten Faden. Das sind Sachen,
die man lernt, deswegen reden wir hier in der Universität darüber.
Deswegen unterrichten wir das, weil das eben mehr ist,
als was man nur lernt, wenn man nebenberuflich eine Programmiersprache,
sich selbst audiodidaktisch beibringt. Dieses Methoden lernen,
das ist auch das, was wir in den Übungen,
in den einzelnen Übungen, ihnen ein Stück weit beibringen wollen.
Wir können sie natürlich nur so ein bisschen triggern,
wir können sie nur so ein bisschen anfüttern und können sagen,
in so eine Richtung geht das.
Wir können sie leider nicht große Systeme bauen lassen.
Diese großen Systeme müssen sie versuchen und dazu möchte ich
sie damit mit allen Worten auch ermutigen.
Versuchen sie sich Projekte zu suchen. Projekte können durchaus welche sein,
wo man Geld damit verdient. Sehen sie zu,
dass das nicht mehr als einen Tag pro Woche maximal wird,
weil die Firmen, die saugen alle, der Arbeitsmarkt ist leergefähigt,
jeden da nicht bei drei auf den Bäumen ist,
wollen die in ihren Projekten haben.
Und das ist aber schlecht für ihr Studium
Ja, es gibt für meine Wahrnehmung ganz viele in Hamburg
an dieser Universität, das war einer meiner früheren Universität anders.
Ganz viele, die zu viel arbeiten für meinen Begriff.
Die arbeiten drei, vier Tage die Woche und das Studium ist irgendwie so ein Nebending.
Ganz besonders fällt mir das manchmal beim Masterstudenten auf.
Und da frage ich mich, warum machen die das eigentlich?
Das Teilzeitstudium ist irgendwie steuerlich, nicht lukrativ, habe ich mir sagen lassen.
Und die jobben nur. Wenn man, wenn die mal wüssten,
wie wenig bei ihnen bleibt, dann ganz wenig vom Studium hängen,
die schaffen das auch irgendwie so mit einer 3 durchzukommen.
Ja, also sie kriegen am Ende so ein Papier,
wo drauf steht die Blumen, oder Master,
aber das im Hirn haben sie nicht.
Ja, das ist alles durchgerauscht. Genauso gibt es Leute,
die natürlich viel Party machen, meines Jungen,
warum nicht, man muss das Leben genießen,
so viel Freiheit hat man nie wieder, so ungefähr.
Es sind die Sprüche, alles okay. Sehen Sie nur
zu, dass Sie trotzdem genug mitnehmen für Ihren Beruf.
Ja, und das ist das,
wo man wirklich Qualifikationen braucht und das ist wieder das Methodenwissen.
Und damit bin ich wieder im Kernthema der heutigen Veranstaltung.
Wir wollen darüber sprechen, wie komme ich dahin,
dass ich diese Qualität, über die wir hier vor zwei,
drei Vorlesungen gesprochen haben, dass ich die erreiche.
Ja, wir wollen den Entwurf so machen,
dass sie arbeitsteilig gut funktioniert und da kommt das erste Entwurfsprinzip ins Spiel.
Entwurf nach Zuständigkeiten, das ist ein Entwurfsprinzip, das steht,
ich mache das mal, das zeigen hier mal am Bildschirm,
dass die Leute im Stream das auch noch mitkriegen.
Also hier unten gibt es ein Entwurfsprinzip,
das hat auch noch einen englischen Namen, Separation of Conserns oder ein anderes,
ein anderer Name dafür ist Responsibility, Driven Design.
Das hat damit zu tun, dass wir Arbeitsteilung irgendwie organisieren.
Arbeitsteilung kann man natürlich sagen, okay,
wir teilen den Kuchen auf in zwölf gleiche Stücken
Bei dem Kuchen ist das ganz einfach,
wenn sie ein Kabel graben, von hier bis zum Dampftrop-Bahnhof machen wollen,
weil sie da eine Heizleitung durchlegen wollen oder ein Kabel durchlegen wollen,
ist das auch einfach, hier,
da kriegt so und so viele Meter.
Aber bei sowas Komplexen wie Software ist das schon nicht ganz
so einfach, weil ich muss viele Abstimmungen machen.
Bei dem Kabelgraben muss ich nur sagen,
wie breit wie tief und wo geht es lang.
Und von da bis da. Und da kann jeder losgraben
. Bei Softwareentwicklung müssen wir vorher die Schnittstellen absprechen,
wer benutzt was, die Reihenfolge, die Datentypen,
die Strukturen, die Aufteilung der Aufgabenstellung.
Und viele Sachen sind übergreifend
Aufteilentwurf nach Zuständigkeiten hat das Ziel, das steht jetzt ganz unten,
die letzten drei Punkte auf der Folie,
dass der Entwurf für jeden verständlich ist.
Bei komplexen Systemen ist dieses Verstehen tatsächlich eine Herausforderung. Die Antwortungsbeschreibung,
die Aufgabenbeschreibung ist so ein dicker Aktenordner, wenn sie es ausdrucken.
Das kennt man nicht mal einfach nur so vom Durchblättern am Nachmittag.
Da gibt es so viele komplizierte Sachen, manche steht ganz hinten,
manche steht vielleicht auch nicht gut aufgeschrieben.
Man möchte das nicht alles verstehen. Und wenn man das aufteilt,
den Zuständigkeitsbereiche, dann weiß man, okay,
da gibt es den Bereich Datenspeicherung.
Ich habe nicht viel Ahnung von Datenspeicherung,
ich weiß nur, wie ich mein Zeug dahin packe
Und da gibt es den Bereich Goui. Ich habe
nicht viel Ahnung von Erkonomie, aber ich weiß,
wie kriege ich dort meinen Funktionsaufruf unter?
Und dann kann ich mich darum kümmern, wie meine Funktionen ausgehen.
Oder sie machen, sind nur derjenige, der die Wirkfluss beschreibt.
Da gibt es eine Wirkflow-Engine. Das genau ist Zuständigkeiten.
Ja, es gibt, wir schaffen damit die Möglichkeit,
mit diesem Entwurfsprinzip die Möglichkeit, Spezialisierung für bestimmte Arbeitsbereiche zu machen.
Das ist der eine Punkt, Spezialisierung. Ich kann mich
qualifizieren für Erkonomie, für Workflows, für Datenspeicherung, für Persistenz.
Und das zweite ist, ich muss nicht mehr alles wissen.
Ich entlaste mein Hirn. Ich kann mich auf die Sachen
konzentrieren, die ich gut verstehe
Damit sind wir schon bei der ersten Entwurfsmethode, von diesem Entwurfsprinzip,
das ist eigentlich mehr so ein Ziel sagt und nicht genau sagt,
wie es hinkommt, möchte ich Ihnen die erste Methode vorstellen.
Diese Entwurfsmethode, wenn Sie mal die unterste,
das ganz letzte, die letzten Zeichen dieser Folie angucken,
es klingt schon wie uralt. 1998, das ist ja
die Zeit ungefähr, wo die Dampfloks fuhren, oder?
Nee, 1989. Ja, also schon lange, lange,
lange her für Sie, für mich nicht ganz so lange.
Da ist diese Methode entwickelt worden, CRC.
CRC hat jetzt nichts mit so einem Cyclic,
wie dann den Code zu tun, so ein Verschlüsselungsverfahren,
also so ein bisschen eine Vorstufe von einem Verschlüsselungsverfahren,
sondern das heißt,
steht für eine Entwurfsmethode
Class, Responsibility Collaboration. Es ist eine Methode,
die entwickelt worden ist für objektorientierte Systeme, die dieses Prinzip,
was wir auf der vorhergehenden Folie hatten,
Entwurf nach Zuständigkeiten umsetzt und die uns dabei hilft,
diese Zuständigkeiten, Klassen zuzuordnen.
Was es dabei gibt, ist, wir haben zunächst
die Klassen, das ist der oberste Punkt. Klassen,
Schrägstrich, Komponenten, das geht auch mit C,
aber eigentlich war das für Klassen gedacht,
wir haben erstmal eine Softwareeinheit,
die wird sich um irgendetwas kümmern
Wir identifizieren erstmal, da gibt es einen Teil.
Das Nächste ist, wir suchen raus,
was sind denn abgrenzbare Zuständigkeiten? Das ist genau das,
das kann zum Beispiel eine Dienstleistung sein, ein zusammenhängendes Angebot,
manchmal auch eine fachliche, ein fachlicher Bereich.
So Sachen, wie ich eben sagte, irgendwas mit Datenspeicherung,
irgendwas mit Wirkfluss oder was auch immer.
Oder auch ein Teil davon. So,
und die ganzen Sachen müssen natürlich nicht einzeln,
sondern die müssen auch zusammenarbeiten.
Und dafür hat diese Entwurfsmethode
eine Technik entwickelt
Jetzt bin ich nochmal bei Groß und Klein. So wie
ich das jetzt darstelle und wie ich das jetzt sagen werde,
wird jeder fast von Ihnen sagen, super,
verstehe ich, kann ich so machen.
Warum brauche ich dann bitteschön eine Methode? Warum muss ich hier
ein Buch kaufen von irgendjemandem? Diese Methode brauchen wir,
um diese Vorgehensweise auch anderen zu unterrichten,
damit alle Leute in einem Projekt, sagen wir mal zehn,
zwölf oder 30 Leute in einem Projekt,
die an einer Aufgabe arbeiten,
dass sie alle genauso vorgehen.
Und damit auch Leute mit unterschiedlicher Qualifikation oder mit unterschiedlichen
fachlichen Vorkenntnissen,
das verstehen
Das heißt, man geht einen bestimmten Weg mit diesen Methoden
, sind manchmal relativ einfache Techniken drin.
Sie haben vielleicht schon mal gehört, so Klassen identifizieren,
nimm einen Text, unterstreiche alle substantiefer.
Und dann sortiert man noch ein bisschen und da kommen am
Ende Klassen raus. Und das sind dann die Klassen.
Oder Use-Cases finden, unterstreiche alle werben. Ja,
und die Sachen, sind wir denn hier im Kindergarten?
Ja, das klingt zu einfach. Tatsächlich versucht man direkt,
und das ist dann wirklich das Ergebnis von längerer Arbeit,
wie diese CRC, diese CRC-Methode, man versucht,
die Methoden so einfach zu machen,
damit man sie wirklich in der 15-Minuten-Schulung den Leuten beibringen kann
Was ganz kompliziert ist, wird er nur zu 60 Prozent ankommen.
So was Einfaches kommt vielleicht zu 90 Prozent an.
Also deswegen wundern sie sich nicht, dass diese Methoden alle,
nicht nur diese, etwas einfach daherkommen.
Es steckt meistens sehr viel mehr dahinter. Der Werkzeugmaterialansatz,
wann kommt ja auch nicht so kompliziert daher.
So, schauen wir uns diese Karten an. Also CRC-Karten,
schreibt man da, die Idee war, dass man durchaus mit Papierkarten anfängt.
Low-Tech ist auch bei einer persönlichen Empfehlung,
man muss das nicht gleich auf dem Bildschirm machen.
Dieses Papier ist viel besser geeignet, um das auch in
Erinnerung zu behalten. Man kann das leicht mal ausradieren,
man kann die Sachen nebeneinander legen,
man kann sie an der Wand hängen,
natürlich kann man sie auch in der Datei packen
Diese Karten sehen so aus,
dass ich also den Namen habe und dann habe ich
die Zuständigkeiten auf dem einen Teil und die Kollaboration,
die Zusammenarbeit auf dem anderen Teil.
Also hier, was macht diese Komponente? Die hat ein paar Funktionen,
sind das hier. Hier sind es nur Funktionen und hier
sind es Sachen, die mit anderen in irgendeiner Form zusammenhängen. So,
wenn wir uns das so anschauen,
und wir haben ja schon kennengelernt wie ein Klassensymbol der UML aussieht,
nämlich so ein Kasten, wo es drei Bereiche gibt,
ganz oben der Name,
dann kommen die Attribute und dann kommen die Methoden,
da wenn sie sagen, ist das nicht das Klassensymbol nur nebeneinander?
In der Tat ist es das. Es führt uns
hin und deswegen, wir reden heute über Klassenentwurf.
In der Tat ist das eine sehr einfache Methode und so
sehr viel reden wir über diese Methode jetzt auch gar nicht.
Ist eine Methode, um zu guten Klassen zu kommen.
Wie kommen wir zu einem guten Entwurf? Gute Klassen.
Gute Klassen sind welche, die diesem ersten Prinz,
diesem Prinzip Entwurf nach Zuständigkeiten folgen.
Also eine Klasse ist für etwas verantwortlich
Damit wird es klar verständlich,
ich weiß, wann muss ich diese Klasse haben,
ich kann, der lasse einen guten Namen geben.
Wenn die Klasse für eine bestimmte Aufgabe ist,
dann gibt es diese Aufgabe meistens auch einen Namen und dann kann ich der DSA Klasse den Namen geben.
Wenn sie so eine Klasse hatten, die macht irgendwas,
dann kann sie, können sie die Klasse nur Utilities nennen oder irgend so etwas.
My Little Helper, ja, na toll,
da weiß ich sofort, was diese Klasse tut, oder?
Ja, also ein guter Name ist auch dann erst möglich,
wenn ich diese Zuständigkeiten aufteile. Das nächste Prinzip,
was hier in der vordersten Einrückung steht oder die nächsten zwei,
lose Kopplung und hohe Kollision sind das,
was sie schon kennen,
als Prinzip,
was zu Modularität beiträgt
Ich möchte sagen, lose Kopplung bedeutet, es gibt wenig Abhängigkeiten.
Das heißt, eine Änderung in dem einen Teil
hat nicht unbedingt Auswirkungen auf die anderen teil.
Wir versuchen, diese Auswirkung zu minimieren. Ein Beispiel ist,
in der Objekte und Tierung lernt man, wenn man anfängt,
das haben Sie vor einem halben Jahr gelernt,
wenn ich auf die Methode einer anderen Klasse zugreifen will,
dann nehme ich den Objektnamen.methodenname.
Da kann ich direkt auf die Methode der anderen Klasse zugreifen.
Und das kann ich doch in meinem Code wunderbar vereinbaren.
Ich bin in der Klasse A und brauche von
der Klasse B, brauche ich irgendetwas,
dann schreibe ich
Give me is this and that. Und dann kann ich,
wunderbar, kriege ich, und das Ergebnis ist gleich das,
was die andere Methode gemacht hat für mich.
Super. Aber wir haben damit eine enge Kopplung zwischen Klasse A und Klasse B.
Mit dem Effekt, dass wenn ich in Klasse B etwas ändere,
muss ich den Code in Klasse A so mindestens prüfen,
in vielen Fällen auch anpassen.
Weil er irgendwas anderes macht. Einfacher wäre es,
wenn ich einfach nur die Daten rüberschiebe.
Ich lasse mir von Klasse B die Daten geben,
die die ausgerechnet hat und nehme nur die Daten,
ein String, ein Array oder was auch immer,
dann muss ich nur etwas anpassen, wenn das Datenformat sich geändert hat.
Nicht, wenn die Klasse B intern
irgendwie jetzt ein bisschen optimiert worden ist,
Befehler behoben oder sowas,
da muss ich
sehr wahrscheinlich
noch nichts tun
Das heißt lose Kopplung. Hier steht noch ein paar Punkte
drunter, die dazu gehören. Zunächst muss ich erst mal
sagen, ich sollte eine Schnittstelle richtig wählen.
Hier steht geeignet. Richtig bedeutet, dass ich wirklich dort,
wo etwas Zusammengehängendes ist, die Grenze dazwischenmacher zwischen den zwei Einheiten.
Natürlich kann ich auch einen großen Ablauf in der Mitte teilen.
Es hindert sie niemand daran, aber das ist eine schlechte Teilung,
weil dann der Oberen, der untere Teil irgendwie stark zusammenhängen.
Am besten man teilt es dort wohl,
eine natürliche Teilung ist, weil die Aufgaben aneinander grenzen.
Bei so etwas helfen diese Class-Russponsibility-Cards,
bei so etwas hilft einem die Einteilung,
wie wir es in Wamm lernen
Dass wir da versuchen, was sind Werkzeuge und was sind Materialien.
Die weiteren Prinzipien, die hier draufstehen, Entwurfsentscheidungen kapseln,
klingt für uns ein bisschen komisch, was ist Kapsel?
Hat das was mit Raumkapsel zu tun oder mit dem,
was ich mir als Tablette einwerfe? Nein,
es hat damit zu tun, dass ich eine Entwurfsentscheidung mal ändern möchte,
ohne Auswirkungen auf andere und Kapseln heißt,
dass ich das, was dort passiert,
mit allen seinen Auswirkungen und Varianten in eins packe.
Also zum Beispiel, da gibt es etwas,
das ist verantwortlich dafür, dass ich den letzten Zustand mir merke.
Und ich habe mir mich entschieden,
das über eine Liste zu tun,
weil ich dann hinterher
nochmal zurückblättern kann
Es würde aber auch reichen, nur einen mehr zu merken. So,
und diese Entscheidung, das über eine Liste zu machen,
steht in so einem Ding, in so einem Ding,
was dann den letzten Zustand sich merkt.
Und ich kann den letzten Zustand abfragen. Alle anderen brauchen nicht zu wissen,
wie das intern implementiert ist und damit hat es keine Auswirkungen,
wenn ich diese Implementierung mal ändere, wenn ich diese Entscheidung mal ändere.
Dann gibt es noch weitere Sachen, Geheimnisprinzip. Vielleicht haben Sie
schon mal davon gehört, auf Neudeutsch heißt das Information Hiding.
Es geht nicht darum,
dass wir dem Entwickler unserem Kollegen im Nachbarraum oder im Nachbarteam
nicht verraten wollen, wie das geht,
sondern wir wollen letztlich nicht ihn nicht davon abhängig machen,
wenn wir später mal was ändern.
Wir wollen immer irgendwas ändern. Es muss schneller werden,
es muss schlanker werden, wir wollen noch was dazu bauen.
Und wenn er das alles weiß und alles,
guckt er es an unserem Code an und sagt,
ach, so machen die das,
greife ich mal auf die Variable zu und da rufe ich mal die Methode auf.
Deswegen haben wir zum Beispiel die Kapselung in Klassen.
Und das muss es auch auf der Ebene höher geben,
nicht jedes Public, nicht jede Public Methode,
einer Klasse muss eigentlich systemweit verfügbar sein.
Nein, ich entscheide mich genau ein paar wenige Sachen
nur nach außen zu geben und alle anderen Sachen bleiben
lokal.
Das ist das Geheimnisprinzip
Und die war in den nächsten beiden Sachen Zyklen vermeiden,
Law of Dameter, Zyklen vermeiden bedeutet,
ich möchte nicht das eine vom anderen abhängig machen,
dann wieder zurück, weil ich das mal zu einem Knoten,
den ich nicht wieder auflösen kann und Lauf Demeter hat was zu tun mit der,
da würde ich jetzt nicht so viel weiter dazu sagen heute,
das hat damit zu tun,
dass ich das aufteile in ein gewisses Gleichmaß,
dass ich das so aufteile, dass sie,
hat also nichts mit dem Öko- oder Bio-Nahrung zu tun,
sonst hatte ich durch das ich ein gleichmäßiges Maß,
die Sachen aufteile, dass es nicht so große Klumpen gibt.
Der nächste große Punkt,
der hier steht,
hohe Kohession
Kommissionen erinnern sich vielleicht, diesen Begriff,
gibt es in der Physik, wenn Teile aneinander haften.
Also wenn ich eine Glasplatte habe und noch eine Glatplatte,
auch wenn da kein Kleber dazwischen ist,
dann schiebt die aneinander, dann sind die beieinander.
Das wäre Athession. Und Kommission war so ähnlich,
das war die Zusammenhaftung zwischen den Teilchen.
Also zum Beispiel zwischen Wassertröpfen, Wassermolekülen gibt es eine engere Haftung
als zwischen Sandkörnchen. Und deswegen wollen sie mal pusten,
kommt von ihrem Aquarium nicht leichten Tropfen hoch,
aber ein Haufen Sand ist dann schon mal aufgelöst.
So Kommission hat damit zu tun, wir wollen Sachen,
die miteinander zu tun haben, eng zusammenpacken.
Und die Sachen, die wir zusammenpacken,
in eine Komponente, in einer Klasse,
sollen bitte auch viel miteinander zu tun haben
Diese beiden Prinzipien zusammen, lose Kopplung, hohe Kollision,
helfen uns, Einheiten zu finden, die eng zusammenhören gehören,
die wirklich etwas miteinander zu tun haben.
Und dieses Zuständigkeiten hilft uns dabei, das zu erreichen,
zu erkennen. Hier uns stehen die Namen nochmal,
also in Modularität steckt das drin, Kapselung, Information Hiding,
steckt auch in beiden drin und Separations of Conserns ist diese Zuständigkeitensache.
Ich hatte mit den Kopplungen eben schon was zu enger Kopplung gesagt.
Die nächste Folie sagt uns, was sind denn,
was ist denn eigentlich Kopplung
Bei Kopplung geht es um Abhängigkeiten. Da geht es darum,
dass ich erreichen möchte, dass die Änderung von dem einen
sich nicht in die Änderung von dem anderen auswirkt.
Weil ich habe sowieso schon viel zu viele Sachen,
die alle voneinander abhängen. Nur die naive Betrachtung von Software
ist, ich kann das leicht ändern.
Software ist nicht leicht zu ändern. Software ist ein Soft.
Das ist so ein Sprich, Sprichwort, ich weiß nicht,
ob sie es schon mal gehört haben.
Ich hatte schon mal mit Managern gesprochen,
da ging es um Softwarequalität,
Änderbarkeit,
meine Projektleiter unter anderem
So ein Projekt, was irgendwie gewachsen ist über eine längere Zeit,
da ist nicht mehr alles so ganz ordentlich.
Und das heißt, es gibt viel zu viele Beziehungen,
viel zu viele Abhängigkeiten, die dann verhindern, dass sich etwas ändere.
Und die haben das immer nicht verstanden. Die haben entweder gefragt
, Herr Riebisch, haben denn Ihre Leute schlecht gearbeitet?
Was soll ich da sagen? Natürlich haben die nicht schlecht gearbeitet.
Ich halte die auch für sehr qualifiziert, jedenfalls die meisten.
Aber das hat auch, das ist einfach über die Lauf der Zeit,
sind immer mehr Abhängigkeiten entstanden. Und diese Abhängigkeiten führen dazu,
wenn ich an einer Stelle was ändere,
hängen da ganz viele anderen Sachen an, die ich da auch alle anpassen muss.
Und wehe, ich vergesse welche, dann funktioniert irgendwas nicht mehr
Und wir haben relativ schnell den Zustand erreicht,
wir hatten hier zwei, drei weiter Fullin zurück hier,
ziemlich zu Anfang Maintainability, Wartbarkeit ist dann so schlecht,
dass der Aufwand für eine Änderung so hoch ist,
dass sich manche Änderungen einfach nicht mehr durchführen kann.
Es ist relativ schnell bei Software der Zustand erreicht, wenn sie wollen,
das und das machen, sie kriegen es nicht zum Laufen.
Es stürzt ständig ab, es gibt irgendwelche unvorhersagbaren Fehler in den
ganz anderen Bereichen des Systems, weil es solche Abhängigkeiten gibt.
Und diese Abhängigkeiten wollen wir bekämpfen, schauen wir nochmal,
genau, wir waren jetzt bei der Kopplung, ja,
und wir meinen damit, Abhängigkeiten ist der Teil,
der oben steht und wozwischen, nicht nur zwischen Methoden oder Anweisungen,
sondern vor allen Dingen zwischen Klassen und Komponenten.
Und je mehr Abhängigkeiten bestehen, desto schwieriger wird es
und deswegen schwieriger wird es, eine Änderung durchzuführen.
Und vor allen Dingen, je mehr Abhängigkeiten es gibt,
um die müssen wir uns ja alles kümmern.
Dieses Bildchen soll das ein bisschen sagen. Wir haben hier
sieben Punkte. Und wenn wir sechs rote Punkte,
und wenn wir die roten Punkte, die ja,
wir letzt sind hier bei uns am Screen House,
wenn wir die auf diese Weise verbinden, haben wir genau sechs Verbindungen.
Sechs Sachen, um die wir uns kümmern müssen.
Prüfen müssen, ob die noch funktionieren.
Wenn wir hier mit jedem verbinden, sind es viel mehr.
Ich habe jetzt nicht gezählt, wie viele oder ausgerechnet, Super.
Vielen Dank. Ja, also ganz viele Verbindungen,
die wir hier haben, N mal N minus 1,
halbe ist die Formel, für die das schnell mal nachrechnen wollen, ob die 21 stimmt.
Okay, was wir erreichen wollen, ist lose Kopplung.
Wir wollen, wir können diese Kopplung nicht vermeiden.
Ja, ein System, was eine komplexe Aufgabenbestellung bearbeitet,
das ist komplex. Ja, wenn ich,
wie ich so ein Containerschiff belade, dafür eine Strategie zu bauen,
das ist komplex. Aber wir können versuchen,
zusätzliche Komplexität, wie nur dadurch entstanden ist,
dass sich bestimmte Sachen zu eng miteinander koppeln, die können wir versuchen wegzulassen.
Darüber reden wir in Softwaretechnik. Darüber reden wir, wenn wir Entwurfsprinzipien ansetzen.
Lose Kopplung heißt also, dass wir Dinge besser verstehen müssen,
können, weil wir uns um die anderen nicht kümmern müssen.
Es reicht uns zu sagen, da gibt es irgendjemanden,
der macht was in der Richtung, ich muss es nicht genau wissen,
weil ich bin nicht so direkt davon abhängig.
Und wir können es dadurch auch leichter ändern, weil wir müssen da drüben nichts tun.
Explizit implizite Kopplungen möchte ich einfach nochmal gegenüberstellen. Es wird ihnen,
wenn beim Angucken, ein Stück Java-Kodes, völlig klar,
wir haben dort mit der Methode was zu tun,
wenn da direkt ein Aufruf dieser Methode drin ist.
Das wäre explizite Kopplung, explizit im Sinne von ausdrücklich ist
die Übersetzung von explizit. Es gibt aber auch viele Fälle,
wo ich das nicht so klar sehe,
wo ich erst beim Debucking merke, oh,
das ist ja von dem Typ,
Beim Aufruf sehen Sie das nicht direkt,
weil das ist Vererbung und dann habe ich noch eine Referenz gehabt.
Das sieht man nicht direkt. Noch schlimmer ist es,
wenn es über irgendwelche Seiteneffekte passiert. Ich benutze eine Ressource,
die jemand anders auch benutzt und schon bin ich von dem
in irgendeiner Form abhängig, was der da gerade tut.
Diese Kopplung ist noch viel schwerer zu finden. Nicht alles davon
können wir wirklich beheben, aber wir wollen das versuchen.
Für die implizite Kopplung hier ein Beispiel,
für die Sachen, die ich schlecht sehe.
Wenn ich so einen Aufruf habe, ein Klient,
einen Anwender von irgendetwas, benutzt einen Behälter.
Und die Schnittstelle hat unter anderem sowas,
dass sie Elemente liefert
Und dann verlasse ich mich und das Ding macht mir alphabetische Sortierung,
dann verlasse ich mich drauf, okay,
da gibt es eine alphabetische Sortierung, wunderbar, kann nichts passieren.
Aber es könnte sein, ich mache die gleiche Schnittstelle hier, aber ändere die Implementierung.
Das merkt erstmal keiner. Der Compiler läuft durch,
der Entwickler, der das aufruft, auch bloß bei irgendeinem Fall,
wenn er plötzlich was machen will, merkt er,
oh, das funktioniert ja jetzt ganz anders.
Und das sehe ich nicht an der Schnittstelle.
Ich sehe es auch nicht am Namen.
Es passiert irgendwie nicht mehr
Wenn ich solche, wir reden über Kopplung,
wir reden über lose Kopplung und da spielen Schnittstellen eine wichtige Rolle.
Schnittstellen sollten schlau gewählt werden. Es gibt kaum die Möglichkeit
zu sagen, korrekt. Deswegen steht hier drüber geeignete Schnittstellen wählen.
Wann ist eine Schnittstelle gut? Eine Schnittstelle ist gut,
wenn sie wirklich Zugriff auf eine Leistung gibt.
Und dabei klar verständlich ist, worum es geht.
Dass sie diese Leistung vollständig liefert. Und das Ganze
irgendwie beschränktes Aufeinander. Konsistent heißt widerspruchsfrei. Es sollte
ein einheitliches Verhalten sein. Und natürlich möchte ich sie
gut benutzen
Der Satz hier unten drunter ist leider das, was wir immer haben.
Ich kann das nicht alles haben. Manchmal muss ich
Kompromisse machen. Kommt es mir besser darauf an,
dass es ganz einheitlich ist oder kommt es mir besser darauf an,
dass es ganz einfach ist oder dass es in Eindruck Einheit zusammenkommt.
Manchmal wäre es in einer Reinheit zu groß. Also ich kann manchmal,
muss ich da Kompromisse machen, das müssen wir einfach davon absehen.
Deswegen gibt es nicht die eine Lösung, sondern immer verschiedene.
Das ist auch etwas, was Sie im jetzigen Teil der Übungen von SE2 eigentlich machen sollen.
Sie sollen versuchen, in diesen kleinen Projektaufgaben aus Varianten zu finden,
wie sie das lösen können. Es gibt,
wir sind ja Vinya dabei jetzt, wie im ersten Teil,
dass es genau die eine Lösung gibt und nur die ist richtig,
sondern es gibt immer Varianten, versuchen sie durchaus, Varianten zu finden.
Etwas, was Sie schon kennen als Möglichkeit von Java, sind Interfaces.
Interfaces sind ja Dinge, die eigentlich nicht wirklich Code enthalten,
sondern die nur die Vorschrift machen, wie die Schnittstelle aussehen soll,
wie die Methoden aufsehen soll von der Methode,
die so etwas implementiert und diese Interfaces haben die Möglichkeit,
uns die wesentlichen Informationen zusammenzustellen, nämlich Name des Interfaces, Aufruftypen
In welchem Umfang ist das? Und Rückgabetypen. Und dieses Sprachkonstrukt von Java,
hilft uns ein bisschen, uns auf das Wesentliche zu konzentrieren.
Wir sollen uns nämlich nicht die Klassen, die Methoden anschauen,
was macht die denn da, was macht die denn da?
Nein, wir sollen den, wir sollten eigentlich,
sollte es uns reichen, den Namen zu lesen,
zu wissen, um zu wissen, was sie tut.
Das reicht nicht wirklich ganz, weil ich muss auch noch wissen,
was ist für ein Verhalten dahinter,
weil sie verhält sich so etwas im Ausnahmefall.
Deswegen gibt es noch so nette Dokumentationsteile dazu,
die in Java-Doktern formuliert werden,
wo man
so was dazuschreiben soll
Und das braucht man, um diese Kopplung zwischen zwei Klassen
so zu beschreiben, dass man die Informationen alle beieinander hat.
So, es gibt die Forderung, schmale Schnittstellen zu verwenden.
Das heißt, nicht so viele Informationen darüber und überzugeben und das deutlicher zu machen.
Ein weiteres Prinzip, was wir genannt hatten, war dieses Geheimnisprinzip
Neudeutsch Information Heiding. Was ist gemeint? Es ist gemeint,
wir sollten den meisten Teil der Informationen für uns behalten
Ich hatte schon gesagt, das machen wir nicht,
um unseren Kollegen zu ärgern. Ich verrate ja nicht,
was ich hier tue, sondern damit es auch funktioniert, ohne etwas.
Das hat eine zweiseitige Wirkung. Er muss sich nicht so stark
um die Details kümmern, die ihn quasi belasten wirken.
Er soll sich mal um sein Zeug kümmern. Und ich muss
mir Mühe geben, dass die Schnittstelle wirklich alles ausdrückt.
Ich muss also mir richtig Mühe geben, nicht,
dass er die Implementierung lesen muss, um zu verstehen,
was das Ding tut.
Nein, der Name sollte das aussagen.
Und die Schnittstelle sollte so genau geschnitten sein,
dass sie wirklich nur diese eine Funktion liefert.
Und nicht noch das und das und das und
die Variante und die Variante.
Da sollte ich was Separates dafür schreiben
Nur das soll es sichtbar sein, nur das sollte zugänglich sein und
nur auf das sollte sich der andere verlassen und damit Änderungen auszuprägen.
Das Wissen allein über Interna kann schon missbraucht werden,
missbraucht im Sinne von, ich verlasse mich am Ende drauf,
dass da intern bei einem Fehler das so und so passiert.
Nein, das sollte so sein, dass die Schnittstelle das
schön ausdrückt, was passiert dann im Fehlerfall?
Und die Interna sollte ich mir gar nicht angucken. Natürlich,
wenn ich die backe und da ist da hinten drin ein Fehler,
dann werde ich das natürlich mir angucken müssen.
Dann wäre es blöd, wenn ich es nicht sehe.
Aber ich sollte mich beim Entwickeln darauf verlassen, dass ich
die Oberfläche nur kennen muss. Was heißt Zügeln vermeiden?
Zügeln vermeiden heißt, Dass ich Abhängigkeiten zueinander sich wiederholen habe.
Also etwas hin und etwas geht zurück,
so etwas hier, wie das Grafische hier darstellt.
Und damit wird es schwierig. Zum Beispiel kann ich das schlecht auflösen,
weil das eine und das andere hängt hineinander zusammen und
hier sind eben gerade drei Beispiele.
Die Reihenfolge, was mache ich zuerst, wer initialisiert wen,
wer triggert wen? Das ist dann ganz schwierig aufzulösen.
Und es ist der Audioeinstiegspunkt beim Verstehen, beim Debugging,
beim Untersuchen, ist ganz schwierig,
deswegen sollte man das vermeiden.
Beispiel, und
zwar jetzt von wann
Hier ist es so gestaltet, dass die verschiedenen Teile sich nicht kennen sollten.
Zum Beispiel ist es so, der Fachwert sollte nur andere Fachwerte kennen.
Niemanden anders. Der Service sollte zum Beispiel nicht
das Werkzeug erkennen, sondern nur in diese Richtung.
Das Werkzeug darf das Material kennen, aber nicht umgekehrt.
Auf diese Weise, durch diese Regeln ist es,
können keine Zügeln auftreten. Das ist jetzt in diesem Wamm-Ansatz
so eingebaut, dass diese Zyklen vermieten werden sollen.
Das Gleiche für Pakete
So, diese Law of Demeter hat zur Folge oder sagt,
dass man ausschließlich der Nachbarn und die Nachbarn aufrufen soll,
sprich nur mit deinen engsten Freunden,
soll also ein bisschen diese Abhängigkeiten quer verringern.
Und wenn so etwas verletzt ist, dann sieht man es darauf,
dass ganz viele solche Sachen hintereinander hängen. Zum Beispiel hier,
das ist ein Aufruf, der über drei Methoden geht.
Also des Tudents ist der Name des Objekts.
Das Objekt hat Eine Methode, Get Record und das,
was die zurückliefert, kann eine ganz andere Klasse sein.
Von dieser anderen Klasse rufe ich eine Methode auf und von dem,
was die zurückgibt, wie rufe ich wieder etwas auf.
Das heißt, über drei, über vier Objekte hinweg einen Aufruf,
die also miteinander zusammenhängen. Das nächste Bild zeigt uns,
dass wie das aussehen könnte, dass ich also hier vier Objekte habe.
Und indem ich die miteinander verkomme, das ist jetzt genau dieses Beispiel,
was ich vorher sagte mit Klasse A und Klasse
B, ja, also diese Klassen sind durch diese lange
Kette miteinander verbunden. Objekte und Tierung erlaubt das.
Sie werden jetzt sagen, wieso ist doch erlaubt den Java?
Natürlich ist es erlaubt
Für kleine Systeme ist es auch völlig okay.
Und wenn diese vier Sachen, die wir hier sehen,
eng zusammenhängen, was war das jetzt?
Irgendwie ist es weg. Wenn diese vier Sachen hier eng
zusammenhängen, dann ist auch alles gut. Wenn sie innerhalb
einer Klasse sind, wenn sie innerhalb eines Paketes sind.
Aber wenn das so ist, dass ein Teil macht jemand
in Indien und das andere Teil macht jemand in Stuttgart,
dann sollten die Sachen nicht so eng zusammenhängen,
weil die Änderungen schwer abzustimmen.
Es ist viel mehr Abstimmungsaufwand.
Dann sollte ich lose Kopplung machen
So, die Beispiele übergehe ich oder das ist doch das Beispiel,
könnte man machen, es könnte jetzt lieber statt dieser langen Kette,
könnte ich lieber sowas machen,
dass ich, der hat eine Methode,
wo dann drin das berechnet wird und dann frage ich dort nach,
was dann passiert ist.
Und ich kann zum Beispiel sogar Head- und Set-Methoden als Verstoß dadurch machen,
indem diese Geldmethode mir das komplette Objekt drüber gibt.
Und damit habe ich so eine enge Kopplung erreicht.
Das wäre auch ein Verstoß, den ich hier erreichen kann.
Wir sollten versuchen, dass wir große Einheiten haben,
wie hier steht es im Beispiel mit so einem Satelliten,
dass ich das mit einem bestimmten Verantwortlichen habe, der sich um etwas kümmert.
Und ich lasse es in dessen Verantwortlichkeit. Die Kohession war dieser innere Zusammenhalt,
ich hatte vorher das mit dem Begriff der Chemie gesprochen,
Zusammenhalt von Elementen. Und jetzt kommt ein Beispiel dazu,
ja, ich möchte gerne eine Klasse haben,
die viele Sachen enthält, die genau eng zusammenhängen.
Und nicht hier eine Klasse, die riesengroß ist,
hier so, es gibt das Hauptprogramm,
da ist alles drin, sondern ich habe eine Klasse,
die für eine Sache verantwortlich ist,
hierfür einen Film oder für etwas.
Das hängt also mit dieser Zuständigkeit zusammen
Gleichzeitig sollten wir noch eine weitere Sache vermeiden, wir sollten vermeiden,
dass wir etwas doppelt machen. Duplizieren, Duplikate,
haben Sie vielleicht schon gehört, dass Ihnen jemand erzählt,
schreibe ja nicht von jemandem anders ab, das ist ja ein anderer Punkt.
Ja, also, dass man Wissen klaut.
Aber hier geht es ja nicht darum, das Klauen,
das ist ja nichts, womit ich glänze,
sondern es ist einfach eine natürliche Form von Wiederverwendung.
Ich finde etwas, das macht ungefähr das, was ich möchte.
Und dann sage ich, okay, markieren, Copy,
woanders einsetzen, paste und dann habe ich doch was,
was das löst. Dass ein bisschen was anderes ist,
passe ich da an, Copy-Paste,
Wiederverwendung ist eine sehr gängige Arbeitsweise und es gibt durchaus Software,
wo sie 25 Prozent des Codes Duplikater sind
Aber, das hat eine Reihe von Nachteilen. Und zwar
ist das, das Schwierige ist, der erste Punkt,
ich erkenne das typischerweise nicht, was im Publikat ist.
Und das Problem ist, wenn da ein Fehler drin ist,
müssen sie es woanders nochmal wiederholen.
Mir ist das in einem Projekt mal passiert.
Da haben wir eine Änderungswunsch gehabt eines Kunden,
das und das soll das geändert werden,
nur eine Benennung in der Tabelle, Bezeichnung, irgendwas.
Wir haben das auch gemacht und da gibt es ja immer so mit Meldungen,
der Auftrag, dann geht das zurück und sagt, ja,
es erlebt schon, in der nächsten Version ist drin.
Und dann kriegt er die Information,
die Version ist ab 1. Juni bei Ihnen verfügbar.
Da ist auch daran, wieso habt ihr das
nicht gemacht?
Ist doch nicht drin
Wir gucken rein. Doch, haben wir gemacht,
ja. Und da stellte sich heraus nach längerer Durchsuchung,
haben wir den Entwickler gefragt, was hast du denn gemacht?
Ja, dort und dort. Stell dir doch fest,
der gleiche Dialog war zweimal enthalten in der Software.
Das ist jetzt ein relativ harmlose Sache,
weil es war nur, es war nur eine Benennung.
Wir haben das beheben können. Stellen Sie sich mal vor,
das wäre ein hartnäckiger, ein böser Fehler gewesen,
der wirklich richtig Schaden verursacht. Wir hätten,
der Kunde reklamiert den, da sind wir bestimmt,
was das schöne erste Mal da ist, was wir so einen Fehler machen.
Dann reparieren wir den Fehler, liefern ihm aus und sagen,
lieber Kunde, der Fehler ist jetzt behoben.
Und er probiert es aus, boah,
kracht es wieder, weil wir woanders behoben haben.
Nicht da, wo es aufgetreten ist,
weil wir so einen Clone hatten
Clone ist die Bezeichnung für dieses Duplikat. Also deswegen ist
das etwas, was wir vermeiden sollen. Das Gleiche,
was wir vermeiden sollten, sind besonders große Klumpen von Software.
Mag alles korrekt sein, mag auch so sein,
dass da wirklich eine große Aufgabe ist und dass es nach
Kommission so sinnvoll ist, einen großen Block zu bilden.
Aber es fällt den Menschen schwer, den Überblick zu behalten.
Deswegen dann lieber zerlegen in kleinere Einheiten. Ein Begriff dafür,
der sich eingeprägt hat bei Entwicklern, Gott klasse.
Hier steht er vor Anti-Pattern,
haben Sie vielleicht schon mal gehört, Pattern sind Lösungen,
die sich bewährt haben und Anti-Pattern sind eben Sachen,
die man
gerade nicht machen sollte
Also, eine Klasse, die sich für alles verantwortlich Klassen führen möchte,
da gibt es eine ganze Reihe von solchen Empfehlungen,
was man nicht machen soll, das wäre zum Beispiel so eine Name Gottklasse.
Und die ist dann sehr groß, die Kollision ist niedrig,
man kann nicht so richtig sagen, wofür ist sie eigentlich zuständig,
die ganzen Sachen hängen miteinander zusammen,
da bündeln sich viele von Verletzungen, die sein Entwurfsprinzipien.
Ein weiteres Ding möchte ich ihn wenigstens nur kurz zeigen,
einige von ihnen haben das schon gehört,
es gibt solche Entwurfsprinzipien, die mit den Abkürzungen,
mit der Abkürzung oder mit Anfangsbuchstaben sollet zusammengefasst werden,
da steckt das drin, dass man hier dieses Verantwortungsprinzip hat,
Zuständigkeiten, das wäre das S, soll Single Responsibility.
Ich möchte das offen geschlossen, also die Informationen,
Kapseln, dieses Substitutionsprinzip, hat mit Vererbung zu tun.
Also die Oberklasse sollte nicht mehr Zusicherung machen als die
Unterklasse und die Unterklasse, die Oberklassenverzusicherung nicht entsprechen.
Interface spielt eine wichtige Rolle und ich möchte Abhängigkeiten nicht in Zyklen haben.
Und damit ist im Kern das Gleiche gereicht,
was niedrige Kopplung hohes Kursion erreichen soll
Und was wir damit erreichen wollen, ist am Ende,
dass alle damit zufrieden sind, dass unsere Leistung gut ist.
Wir haben hier mal ein Beispiel, hier ist ein Diagramm,
bekommt vielleicht noch eine zweite Kurve dazu.
Also hier auf der X-Achse sehen wir, wie Leute,
wie weit ist das zufrieden?
Wie weit erfüllen wir die Anforderungen? Und wie zufrieden sind
die Kunden? Das ist auch das, was wir erwarten.
Wenn wir mehr tun, sind die auch mehr zufrieden.
Wenn wir weniger tun, sind sie mehr unzufrieden.
Aber man kann das auch noch sagen, okay, es gibt Basisanforderungen.
Es gibt Sachen, die sind völlig selbstverständlich.
Der Kunde wird dafür nicht mehr zufrieden,
wenn wir die alle erfüllen
Nur wenn wir sie nicht erfüllen, hier drüben,
dann wird da immer mehr unzufrieden.
Also es gibt Sachen, die erwarten die Leute einfach.
Und wenn sie sie nicht erfüllt sind, die werden die richtig ärgerlich.
Und es gibt noch Anforderungen, die ein bisschen anders sind.
Das sind die Begeisterungsanforderungen oder die darüber hinausgehen,
wo man richtig den Wow-Effekt gibt.
Sie brauchen den Kunden gar nicht so viel zu geben,
sehen sie das hier fast null und er ist schon begeistert.
Und wenn sie die nicht haben, ist auch nicht so schlimm.
Aber wenn sie ein bisschen davon haben, werden sie richtig,
finden das richtig toll. Wenn betrachten wir jetzt mal,
wo wir auf dieser Kundenzufriedenheitsacke liegen,
mit dem Bassesanforderungen,
um die müssen wir
uns auf jeden Fall kümmern
Und das sind Sachen, da gehört dazu,
dass die Software nicht zu langsam ist, dass die Software die Funktion macht,
dass sie nicht so hässlich zu bedienen ist, solche Sachen.
Und da können wir, das können wir mit Basisanforderungen,
mit den Begeisterungsanforderungen hier oben, wenn wir Palle Features haben,
das sieht super toll aus.
Damit können wir das nie kompensieren, wenn wir hier uns
solche Negativpunkte haben auf dieser Achse der Kundenzufriedenheit.
Wie erreichen wir das? Wie erreichen wir das,
dass wir wissen, was der Kunde von uns will,
dass wir wissen, was wir brauchen und damit wir einen guten Entwurf machen.
Entwurf hat ja damit zu tun, dass ich eigentlich,
bevor ich anfange zu programmieren,
mir überlege,
wie strukturiere ich
das Ganze
Das heißt, lange vorher und diese Wasserfallmodelle, die ja davon leben,
dass ich also mit einem Punkt nach dem anderen abarbeite,
haben wir im Kern zur Folge,
dass ich eine lange Dauer habe, bis etwas fertig ist.
Also von dem Punkt, dem Punkt, dass der Kunde
mir sagt, was er möchte, der Auftraggeber.
Bis dahin, dass ich die Software fertig habe,
vergeht eine lange Zeit und eher kriege ich auch kein Feedback. Diese agilen Methoden wie Scrum und Konsotten leben davon oder haben ihre großen Stärken darin,
dass ich ständig ein Feedback bekomme, und zwar auf jeder Ebene,
relativ kurze Zyklen, eine Woche, drei Wochen Sprints,
wo der Kunde gleich etwas sieht, wo ich gleich die Nachricht bekomme,
ist das gut oder nicht, hat auch die Zurfolge,
ist der Kunde eher weiß, okay, es ist in Arbeit,
es gibt offensichtlich Fortschritte, es sammelt sich nicht so viel Misstrauen,
Ärger, Frust auf, weil er weiß, okay, die arbeiten und es wird schon irgendwann kommen.
Gehen wir zu einem von diesen Punkten von Solid durch,
Single Responsibility Principle. Das erste, das war dieses Zuständigkeiten
trennen und hier aber noch ein bisschen schärfer.
Eine Klasse sollte eine Aufgabe erfüllen. Da should be never
be more than one reason for a class to change.
Da sehen Sie schon gleich wieder, worum es uns eigentlich geht.
Es geht um die Veränderung. Es geht nicht darum,
die Klassen möglichst klein zu machen. Aber es geht darum,
dass eine Klasse am Ende eine abgegrenzte Aufgabe erfüllt.
Schon wenn Sie sich erinnern, vorhin wollte ich den Leuten
den Sachen einen Namen geben.
Es ist einfacher, einen guten Namen zu geben,
wenn es nur eine kleine Aufgabe ist.
Hier ist eine Klasse, die ganz viel tut.
Senden, Receiven wählen, aufhängen, irgendwie eine Datenübertragungstechnik.
Und zwar sind hier
zwei Zustände drin
Verbindungen, Herstellnachrichtenverbindungen und die eigentliche Übertragung von Daten.
Und das kann sich ändern, weil ich die Technik ändere,
weil ich die Daten zur Form ändere oder sowas.
Das nächste Prinzip, was wir bei dem Solit heißen,
hatten wir das O, das war das Open Closed Prinz Roll.
Der erste Satz ist ja wunderschön, kann man so sagen.
Offen für Erweiterungen, aber geschlossen bei Veränderungen. Das heißt,
ich darf sie benutzen, wie ich möchte,
aber ich möchte sie trotzdem erweitern können.
Und bei den Erweiterungen soll ich möglichst keine weiteren Änderungen der
übrigen Sachen haben. Das heißt, dieses Closed.
Wir möchten also wenig Abhängigkeiten haben,
die sich woanders hinprägen
Das nächste, dieses Prinzip hatte ich vorhin schon kurz genannt,
hat mit Vererbung zu tun.
Ich möchte nicht in Unterklassen Dinge überschreiben, die die Oberklassen vorgeben.
Also das hat was mit Vor- und Nachbedingungen zu tun.
Es sind wieder Begriffe, die so ein bisschen schwer zu
verstehen sind, aber man hatte ein ungefähres Verständnis.
Vorbedingungen ist etwas, ist eine Voraussetzung, die da ist,
damit ich überhaupt einfange. Nachbedingungen ist etwas, was ich
zusichere, was in jedem Zustand auf jeden Fall passiert.
Beispiel im Dateisystem, im Dateisystem ist es so,
dass man Dateien nicht nur einfach benutzt,
sondern man muss sie öffnen zum Lesen schreiben und man muss sie hinterher wieder schließen,
damit sie in einem konsistenten Zustand bleiben.
Und zum Programm, ich darf nicht einfach beenden,
sondern es muss auf jeden Fall diese ganzen Dateien widerschließen,
sonst kommt es zu solchen Sachen wie korrupte Dateien.
So ein bisschen so ähnlich wie wenn sie beim Windows-Rechner einen USB-Stick dranstecken,
den müssen sie wieder abmelden, bevor sie ihn abziehen.
Sonst kann es sein, der sagt dann,
ich bin nicht lesbar, bitte formatiere mich.
So und ich fähre es das auch und das wäre jetzt ein Zustand,
ich möchte auf jeden Fall erreichen, wenn ich so einen USB-Stick hatte,
dass der auf jeden Fall hinterher ordentlich abgemeldet wird.
Das könnte eine Nachbedingung sein. So,
wir haben jetzt hier Nachbedingungen und Vorbedingungen erwähnt
Die Methoden, die hier unten sind, die hier unten überschrieben werden,
sollten nicht stärkere Forderungen haben oder schwächere Nachbedingungen haben.
Das heißt, das Stärkste sollte eigentlich hier oben stehen,
hier unten sollte das nur weiter präzisiert werden, weitere bezüglich der Leistungen.
Also wir haben jetzt hier ein Beispiel,
dass eine Ellipse aus der Mathematik, wissen Sie vielleicht noch irgendwie,
das war so ein Kreis mit zwei Durchmessern,
längere Breite beziehungsweise im Kreis mit zwei Mittelpunkten.
Und wenn ich jetzt sage, okay,
der Kreis ist eine Spezialform der Elypse,
weil nämlich nur mit einem Mittelpunkt, beziehungsweise mit einer Achse,
dann wäre das ja, könnte ich sagen, ja,
gar kein Problem, ich mache das so.
Aber das würde jetzt genauere, stärkere Vorbedingungen haben als das hier oben.
Inversion of Control, das war das I von dem Solit.
Das I von dem Solit bedeutet, wer ruft denn wen auf?
Wozu ist das Ganze zuständig? Wozu brauchen wir das Ganze
? Wir wollen Zyklen vermeiden Und indem wir sagen,
zum Beispiel, nicht das Interface, also die Klassen,
die die schönen Fenster machen, die wir sehen,
die rufen uns auf, sondern wir rufen die auf.
Dann können wir aber nicht oben in Mausklick geben,
Klick und dann wird unten eine Methode ausgeführt,
sondern das muss irgendwie umgekehrt laufen oder über Nachrichten oder über Events.
Ich möchte aber vermeiden, dass das eine,
das andere aufruft und das Ganze wird ein großes Kuddelmuddel.
Und von wem geht das aus? Deswegen gibt es immer
dieses, dass mir die Steuerung aus einer Richtung nur macht
Und das D, das Letzte, von dem Solith,
der dritte Buchstabe, der fünfte Buchstabe, ist etwas,
wie man Abhängigkeiten mit Abhängigkeiten umgeht,
die Pendency Injection bedeutet Abhängigkeiten in einem Interface, möchte ich gerne von außen antriggern.
Nicht, dass das Interface sich abhängig macht, ich brauche aber das,
ich brauche aber das und ihr müsst das so und so und so machen,
sondern ich liefere eine Dienstleistung und diese Dienstleistung kann von euch abgerufen werden,
muss aber nicht.
Ich kann das meistens nicht in dieser Form so ganz theoretisch oder ganz Prinzipien treu machen,
weil manchmal brauche ich noch irgendwelche Voraussetzungen,
diese Frausätze müssen natürlich auch erreicht werden.
Das typische, wenn man solche Injection gibt, wenn sie Injection-Sachen benutzt,
sind Lister, Lizenor, die irgendwie eine Leistung liefern.
Ja, also hier ein Beispiel, ich habe einen Konstruktor und
dem Konstruktor gebe ich bestimmte Sachen mit und dann hat der die.
Und dann bekommt das Objekt, was ich damit aufgerufen habe,
hat gleich alles. Es muss sich nicht die Sachen selbst holen,
sondern es bekommt das beim Aufruf übergeben und ich kann von außen steuern,
wie das Verhalten ist,
wie das alles zusammenhängt
So, was wir auch noch haben damit ist,
dass die Kopplungen geringer sind. Hier ist jetzt so eine Kopplung
sehr lange und wir können jetzt hier die Kopplung etwas vereinfachen. So,
was uns, wobei uns das hilft, ist,
dass wir, dass jeder weiß, was tun die anderen,
dass jeder nur die Abhängigkeiten erzeugt,
die er wirklich braucht und dass wir damit es schaffen,
Änderungen voneinander unabhängig zu machen
Ich möchte hier schon mal den Begriff der Entwurfsmuster wieder zur Sprache bringen.
Ich glaube, das ist schon mal genannt worden.
Auf jeden Fall kennen Sie schon MVC. Es gibt für diese Möglichkeiten,
für die Sachen etwas Entwurfsprinzipien gut anzuwenden, immer Lösungen,
die wiederverwendbar, sie sie schon gezeigt haben,
dass sie gut sind, die wiederverwendbar sind.
Auf dieser Folie sehen Sie ein paar, die waren jetzt
nicht bei denen dabei, die ich schon rumgeschickt habe,
wie werde ich zur Ergänzung nochmal rumschicken.
Hier stehen einige dieser Entwurfsmuster dargestellt, die so die Grundlage sind,
die zuerst entwickelt worden sind, die man schon mal nennen kann.
Und diese Entwurfsmuster pattern, wir hatten vorhin schon den Begriff Andi Pattern,
sind immer dazu gedacht, dass ich eine bestimmte Klasse von Problemen löse.
Das erste zum Beispiel dieses Factory klingt immer so, ja,
Fabrik, was ist das, was wird da hergestellt?
Das ist eigentlich das New in Groß. Mit New erzeuge ich eine neue Instanz,
initialisiere diese, aber wenn ich in Geflecht von Objekten habe,
die irgendwie zusammenhängen,
dann ist es bei New irgendwie schwierig,
wen initialisiere ich denn zuerst und wie mache ich denn
das und wo kriegt denn der seine Daten her und wen
rufe ich denn zuerst auf
Factory hilft uns dabei,
dass in einem Satz zu machen und dann klar zu sagen,
so erzeuge ich das New für einen Satz von zusammenhängenden Teilen.
Das heißt dann, Factory klingt erstmal ein bisschen abgefahren, ist aber eigentlich ganz einfach.
Also deswegen ist meine Erklärung immer New für mehrere Klassen,
die irgendwie zusammenhängen. Das gibt es als der nächsten Folie.
Und ein kleines Beispiel dazu. Ich möchte,
so ein Pattern hat so eine Beschreibung, wo man steht,
der Zweck, Anwendbarkeit, dann gibt es noch viel mehr,
die ich jetzt hier nicht auf der Folie habe.
Wie funktioniert das genau, was sind verwandte Klassen und so weiter.
Ich möchte Sachen, die miteinander zusammenhängen, erzeugen, ja,
ohne mich darum zu kümmern, was da genau drin ist.
Wir gucken uns das mal ein Beispiel an.
Obwohl das Beispiel aus meiner Sicht doch ein bisschen kompliziert ist.
Ich möchte mich darum kümmern, dass ich Sachen zusammen mache,
die ein Fenster erzeugen. Ja, also ich möchte ein
Fenster haben und da, und diesen Fenster sollen scrollbar sein.
Und das Ganze soll Teil eines Editors sein,
damit ich die alle miteinander erzeuge, gibt es jemanden,
der kümmert sich drum, für das Widget,
das ist nochmal ein neuer Begriff hier,
für das Dokument,
das Dokumentfenster enthält
Dass ich dafür sowohl das Fenster als auch den Scrollbar erzeuge. Also wir brauchen es,
ich fürchte, das ist hier ein bisschen zu kompliziert,
merken sie sich einfach, ich erzeuge zusammenhängende Sachen und beauftrage jemanden,
kümmere dich mal darum, dass die richtig zusammenhängen.
Und dann brauche ich das nur einmal für ein bestimmtes Beispiel zu machen. So,
ich merke jetzt schon, ich bin ein bisschen zu schnell gewesen,
auch wenn ich, habe mich wahrscheinlich ein bisschen,
ist ein bisschen zu schwierig, mit ausgeblendeten Folien zu arbeiten.
Jedenfalls bin ich schon bei der Zusammenfassung für heute angekommen.
Was ich Ihnen heute mitgeben möchte, ist, dass wir uns,
wenn wir große Systeme betrachten wollen, immer darum kümmern müssen,
dass wir nicht alles machen, was technisch möglich ist,
sondern dass wir die Sachen machen, die so sind,
dass sie einfach genug sind, dass die anderen die auch verstehen.
Einfach, nicht nur weil die anderen dumm sind,
sondern weil bei ihnen von unseren Ideen nicht alles ankommt,
weil es immer, jeder hat seine eigenen Annahmen,
Voraussetzungen und Annahmen für Begriffsverständnisse und deswegen versteht jeder das ein bisschen anders.
Und das ist das, was dabei schwerfällt. Wir sollten versuchen,
uns immer noch an diese Entwurfsprinzipien zu halten,
weil diese Entwurfsprinzipien uns helfen, Dinge zuzuentwickeln,
dass sie gut sind, gut im Sinne von gut weiterentwickelbar.
Wenig abhängig, gut gekapselt. Wir haben mit diesem einfachen Entwurf erreichen wir,
dass nicht nur die Informationsverluste geringer werden, sondern wir erreichen auch,
dass der tatsächliche Arbeitsaufwand, wenn ich eine Änderung machen möchte,
was bei den anderen dann geändert werden,
dass dieser tatsächliche Arbeitsaufwand tatsächlich geringer wird.
Und zwar messbar geringer. Das Ganze spielt bei kleinen Systemen nicht die große Rolle,
sondern es spielt erst ab einer gewissen Größe die Rolle.
Also um mal mit Zahlen zu sprechen, man spricht zum Beispiel davon,
dass eine Architektur unumgänglich ist, ab 30.000 Zeilen Code.
Und etwas, wenn sie jetzt mal einfach die Mediathek nehmen,
die sie da haben, ich weiß nicht,
wie ob die 500 Zeilen Code hat oder 700 oder sowas, wissen jedenfalls weit weg davon.
Wir besetzen jetzt in einer Lehrveranstaltung im Masterstudium,
wo es um Re-Engineering geht, um die Verarbeitung oder Überarbeitung von Software,
haben wir ein Beispiel, das hat 100.000 Lines of Code,
das ist schon wirklich so, dass man das nicht schafft,
das in kurzer Zeit zu verstehen, obwohl der Entwurf wirklich brillant ist.
Die Namen sind gut gegeben,
die Klassen sind gut formuliert und ich kann mir aufgrund allein der Pakete oder Klassennamen mich relativ gut zurechtfinden,
aber es gibt immer wieder Punkte, sage ich,
denn das statt, hier findet es nicht statt,
hier findet es, Sie müssen wirklich den Debugger starten,
um Schrittbetrieb zu sehen, wo denn wirklich das stattfindet.
Also ab einer gewissen Größe ist es nicht mehr so leicht,
das einfach zu verstehen,
und da ist es dann umso wichtiger,
kleine Einheiten zu bilden, die gut entkoppelt sind,
wo ich mich dann durch das Information Hiding auch nicht drum kümmern muss,
was da intern passiert.
Ich weiß einfach, die machen das,
die sind dafür verantwortlich, diese Responsibility-Zuständigkeit.
Und damit kann ich das Problem tatsächlich für mich ein bisschen beharschbar machen.
Was wir bei Softwaretechnik auch immer im Kopf haben,
ist die Beschränkung des Kurzzeitgedächtnisses. Sie wissen alle,
diese magische Zahl, 7 plus minus 2,
das ist die Anzahl der Sachen,
die wir
gleichzeitig im Kurzzeitgedächtnis behalten können
Wenn das 8., 9., 10. dazukommt, rutscht irgendetwas raus.
Mal abgesehen davon, man hat viel Übung.
Also alle diese Zahlengenies, die machen das mit anderen Techniken,
die machen das mit ganz vielen Übungen.
Da kann man auch mehr behalten. Manch einer von ihnen
hat ein gutes Zahlengedächtnis und ein gutes Personengedächtnis oder sowas.
Man kann das schon trainieren, aber der Durchschnittsmensch hat
nur sieben plus minus zwei Informationen gleichzeitig im Kopf.
Und wenn das zu groß wird, wir hatten von der Gottglas gesprochen,
wenn ich den Überblick verliere, wenn ich zu viele Einheiten habe,
wird es schwierig für mich.
Ich mache Fehler und dann wird die Software nicht mehr
gut beherrschbar
Damit sind wir heute schon, und zwar deutlich vor
der Zeit, ein bisschen am Ende der Veranstaltung.
Ich war leider ein bisschen zu schnell.
Vielen Dank für Ihre Aufmerksamkeit. Ich freue mich,
Sie nächste Woche alle wiederzusehen.
Vielen Dank