Dann herzlich willkommen zur zwölften Vorlesung.
SE1, nein, SE2. Warum rutscht mir SE1 raus?
Weil wir ein kleines Projekt vorhaben und ich schon mal hier
so ein bisschen Werbung dafür machen will für dieses Projekt.
Wer von euch hat SE1 mitgemacht, wahrscheinlich ziemlich alle.
Genau. Wer von euch hatte einen Per-Partner oder
eine Per-Partnerin über den oder die ihr euch geärgert habt,
kam das mal so vor oder kam nicht so häufig vor.
Ab und zu
, okay
Ja, also wir haben immer wieder festgestellt,
dass es in den Übungen so, sagen wir,
Verhaltensweisen gibt, die dem Studium eher zuträglich sind oder auch Verhaltensweisen,
die dem Studium eher abträglich sind.
Und wir haben ja das Lehrlabor hier an der Mindfakultät,
das leere Innovationen fördert und finanziert.
Und da haben wir jetzt einen neuen Antrag gestellt,
dass wir für das Wintersemester,
für SE1, für den nächsten Durchgang,
sogenannte SE1-Clips drehen dürfen
Ja, ja, ich sehe das Erstaunen in euren Gesichtern.
Was ist das denn für ein Blödsinn? Ja, das ist unsere Idee davon,
wie man in manchen Situationen im Übungsbetrieb nochmal vielleicht den einen oder anderen auf,
sagen wir, unglückliches Verhalten hinweisen kann.
Also ich habe da so diese Idee gehabt,
dass man zum Beispiel mal darstellt in so einem Videoclip von,
es sind nur wenige Sekunden,
es muss nicht lang sein können, so Webcasts sein,
so YouTube-mäßig,
dass man da durchspielt,
dass jemand irgendwie völlig unvorbereitet in die Übung geht und dann
erstmal tausend Ausreden erfindet
Oder ich habe gerne gefragt, sag mal, wenn ihr nicht wisst,
was dieser Begriff heißt, wo könnt ihr das denn nachlesen?
Und dann kam immer so die Antwort Google. Und dann habe ich gesagt,
ja, ja, es gibt ja auch das Skript.
Und das sind immer so Sachen, die kommen immer wieder.
Und ich denke immer so, es wäre schön,
wenn man in dem Moment, wo jemand mir diese Antwort gibt,
wenn ich dann das Video rausholen könnte, Übungsbetrieb sagen könnte,
guck mal, das kennen wir schon.
Also das ist einfach, ist ein bisschen,
sagen wir einfach, ja, eher eine kreative Idee gewesen,
die wir da gehabt haben.
Und weil aber diese Clips möglicherweise nachhaltig wirken können,
sind wir da auch finanziert worden.
Also das heißt, wir werden jetzt gefördert,
haben also Geld
Und das soll im August jetzt losgehen, August,
September, Oktober werden wir Filmaufnahmen machen.
Und wir brauchen Darsteller und wir brauchen aber auch Regisseure.
Also wir brauchen auch Leute, die Lust haben an
so einem kleinen Projekt mitzuwirken. Wenn ihr Interesse habt,
wenn ihr euch das irgendwie witzig genug vorkommt und ihr Lust habt,
mal so ein bisschen Laiendarsteller zu sein oder vielleicht auch einfach Ideen beizutragen,
wie man diese Clips gestalten könnte,
welche Situationen euch in den Übungen besonders gestört haben oder welche
ihr besonders positiv fandet
Dann meldet euch einfach bei Timo Göttel. Der koordiniert das Ganze
und da könnt ihr euch jetzt mal unverbindlich Bescheid sagen,
dass wir einfach ein paar E-Mail-Adressen haben von Leuten,
die wir dann anmelden können, wenn es heißt,
so jetzt müssen wir irgendwie mal eine Massenszene drehen,
so mit den Gladiatoren und so.
Naja, ihr wisst schon, was wir da so brauchen.
Also so Übungssituationen halt. Genau, das ist also nur eine kleine Ansage.
Wir werden das sicherlich auch nochmal im Komsi bekannt geben,
im größeren Rahmen. Wir halten das für eine ganz,
ganz vielversprechende Idee und müssen halt sehen, wie es funktioniert.
Und das ist auch Natürlich sind wir darauf angewiesen,
dass auch von euch kreativer Input kommt.
Prima. Wer hätte denn ungefähr nochmal so mit so
einem kleinen Finger erhoben Interesse daran mitzumachen bei sowas?
Ja, so, ja, immerhin so, ja,
so eine Handvoll. Okay. Sehr schön. Worum geht
es heute? Jetzt geht es hier um den Inhalt.
Es geht heute um das Thema Refactoring. Das ist,
wenn man sich mit Softwareentwicklung beschäftigt, ein relativ wichtiges Thema.
Ich werde wieder eine Motivation machen, mal wieder über die
Tatsache, dass Software ja altert
Dann werden wir uns den Begriff mal ein bisschen genauer ansehen.
Wir werden uns so ein paar üble Gerüche in Software mal näher ansehen.
Dann schauen wir uns sehr genau die Mechanik von einem oder zwei Refactorings an.
Und dann spiele ich hier auch mal live so ein paar Refactorings durch,
also damit wir einfach mal so ein bisschen,
damit ihr auch mal seht, was da so dahinter steckt,
hinter diesem, hinter der Tool-Unterstützung,
die ihr möglicherweise in Eclipse schon wahrgenommen habt.
Und am Ende sage ich noch ein bisschen was zur Werkzeugunterstützung.
Literaturenweise dazu ist natürlich der Fouler sozusagen das Buch zum
Thema Refactoring
Das Buch ist sowieso empfehlenswert, wenn ihr euch für Softwareentwicklung allgemein interessiert,
weil es auch eine bestimmte Sichtweise auf die Softwareentwicklung darstellt und vertritt.
Denn das ganze Refactoring funktioniert nur, wenn man auch vernünftig testet.
Also wenn man auch testgetrieben möglicherweise seine Software entwickelt,
da ist eine ganze Geisteshaltung dahinter, von agiler Softwareentwicklung,
die in dem Buch auch sehr klar vermittelt wird.
Der Martin Fauler kann extrem gut schreiben,
also es ist wirklich ein lesenswertes Buch,
zumindest auch die ersten Kapitel, um in die Idee reinzukommen,
ob man jetzt den ganzen Katalog von Refactorings da durchgehen will,
das ist eine zweite Sache, da sucht relativ
Es sind, glaube ich, 60, 70 Refactorings,
die da drin stehen. Und dann habe ich noch ein
anderes Buch hier ein bisschen mit empfohlen. Das ist so
ein bisschen in den Hintergrund getreten, inzwischen Refactorings in großen Softwareprojekten,
weil man dann auch tatsächlich da nochmal andere Problemstellungen hat.
Das ist ein Buch, was zwei Kollegen von mir hier in Hamburg
damals mitgeschrieben haben. Und ja, gut. Okay,
was ihr wahrscheinlich schon mehrfach jetzt von mir hier gehört habt,
ist, dass sich Software verändert.
Und insbesondere eigentlich die Software selbst sich nicht ändert,
sondern eigentlich die Randbedingungen sich ständig ändern. Das heißt,
Das Umfeld von Software ist sehr dynamisch und deswegen muss Software erweitert werden,
die muss portiert werden, adaptiert werden und so weiter.
Und ich habe auch schon, glaube ich, mehrfach gesagt,
dass das eben üblicherweise nicht dieselbe Person ist, die das macht,
sondern dass es häufig verschiedene Personen sind und häufig einfach Leute mit dem Quelltext in Kontakt kommen,
die den nicht selbst gebaut haben.
Und klar, wenn Software nicht gepflegt wird,
dann kann man ziemlich sicher davon ausgehen, dass sie stirbt.
So, drastisch, das klingt,
aber es ist einfach so, Software,
um die sich keiner kümmert,
nach spätestens zwei Jahren ist die wertlos
Da passiert nicht mehr mit, viel mit.
Da sieht man so ein bisschen zum Beispiel an Violett OML,
falls ihr das mal so benutzt habt oder benutzen musstet in den Übungen.
Das Ding ist von 2007 und es geht immer noch,
das ist ja eigentlich erstaunlich, das ist wieder,
das kann man vielleicht auch Java ein bisschen zuschreiben,
aber da ist seitdem nicht mehr viel dran passiert.
Und es knirscht an vielen Stellen mit, Violett OML.
Es ist eben halt nicht mehr so toll benutzbar,
weil sich halt niemand mehr drum kümmert.
Als ich die Folie schon mal drauf liegen hatte,
habe ich das Zitat von David Partners gehabt.
Hier gibt es ein Zitat von Martin Fauler aus dem Refactoring-Buch
Das auch wieder deutlich macht, wenn man Software erwarten will,
muss sie natürlich wartbar sein. Und wie schreibt man wartbare Software?
Weil das formuliert eher etwas, finde ich, überspitzt.
Any fool can right code that the computer can understand.
Good program is right code it humans can understand.
Ist ein bisschen übertrieben, weil meine Annie fool can right code,
der Computercan understand heißt, man muss wissen, was ein Computer kann.
Man muss wissen, wie man Probleme so formuliert,
dass sie von einem Computer verarbeitbar werden.
Also man muss den Computer dazu bringen,
dass er das tut,
was man will
Das ist schon nicht so ganz einfach, sonst würdet ihr ja auch nicht hier sitzen.
Deswegen würde es auch kein Informatikstudium geben. Er überspitzt das hier,
weil er sagt, das ist das eine,
die Software zum Laufen bringt, dass sie irgendwie das macht,
was sie tut oder tun soll.
Aber so richtig gut ist man erst, wenn man Code
so schreibt, dass andere ihn auch verstehen können.
Und ein Schritt dahin, um verständliche Software zu haben,
ist zu refactoren. Und eine Motivation oder die Motivation für Refactoring
sind sogenannte üble Gerüche in Software. Und das ist einfach das,
was ich sage, was ich eben schon gesagt habe,
wenn Software sich nicht, wenn Software nicht gewartet wird,
nicht angepasst wird, dann entsteht mit der Zeit relativ viel Müll.
Und es kann auch sein, dass sich Entwürfe ändern müssen, weil sich die Anforderungen geändert haben.
Und wenn ich jetzt Änderungen in ein System reinbauen muss und dann feststelle,
oh, das ist aber hier jetzt schwer reinzubauen,
weil das ist irgendwie eine statische Begrenzung in der Software,
dann kann ich jetzt nicht einfach beliebig viele von anbieten in einem bestimmten Kontext,
was weiß ich, beliebig viele Dokumente öffnen,
statt nur genau fünf oder sowas.
Das sind so Dinge, die schon Ja,
teilweise durch den Entwurf, wie die Software gebaut ist,
erschwert werden können. Ja, und die Bad Smells,
die der Fouler auch in dem Buch beschreibt, das sind so klassische Hinweise,
dass irgendwas im Code nicht so ganz richtig gut ist.
Also, ja, eigentlich mehr oder wie das,
was ich auch schon in der Entwurfsregelvorlesung gesagt habe,
also in den allgemeinen Entwurfsregeln, Methode ist zu lang,
dieselbe Fallunterschadung wird an mehreren Stellen im System vorgenommen.
Also all diese Sachen, die so irgendwie,
das fühlt sich nicht gut an,
beziehungsweise es riecht nicht gut
Okay, also dann, was hilft dagegen? Refactoring. Also
eine Möglichkeit ist Refactoring und Refactoring ist aber sehr klar abgegrenzt.
Und das ist hier die Definition von Refactoring, die eigentlich generell gilt.
Refactoring bedeutet die interne Struktur an der Software zu verbessern,
ohne ihr beobachtbares Verhalten zu ändern.
Das ist eine ziemlich scharfe Anforderung, ohne ihr beobachtbares Verhalten zu ändern,
heißt, keine Änderung der Funktionalität.
Also wenn man neue Funktionalität einbaut, das ist kein Refactoring.
Oder auch wenn ich Fehler rausbaue aus einer Software,
das ist kein Refactoring
Oder ich ändere das Layout einer Gui,
ohne dass ich da irgendwie an der Funktionalität,
was tut, ist nur das Layout ein bisschen anders.
Selbst das ist kein Refactoring. Refactoring ist das,
was man nicht beobachten kann als Benutzer der Software.
Aber warum macht man das überhaupt? Naja,
weil es eben halt auch sowas gibt wie die Architektur,
wie die interne Struktur, wie den Quelltext.
Das habt ihr nun hoffentlich schon mehrfach erfahren.
Und dieser Quelltext kann teilweise auch in seinem Entwurf verändert werden.
Wir werden heute hier so einige Beispiele sehen,
dass die Funktionalität durchaus gleich bleiben kann,
aber das intern sehr unterschiedlich aussehen kann
Der Fouler hat dann auch noch mal später so was gesagt,
was ich auch ganz interessant finde. Er sagt hier,
refactoring is a very specific technique founded on using small behavior preserving transformations.
I'm sales and themselves call refactorings. Das heißt,
er sagt hier irgendwie, refactoring ist einmal eine Tätigkeit,
eine Technik. Und er sagt aber auch,
diese kleinen Änderungen, die heißen auch Refactorings.
Und if you doing refactoring assystem should not be broken
for more than if you minutes at a time,
I don't see, how you can do it?
Und something that doesn't have a well defined behavior. So,
also, wenn man das beobachtbare Verhalten nicht ändern soll,
muss man das beobachtbare Verhalten sehr genau kennen,
damit man dann eben halt auch dafür sorgen kann,
dass das sich nicht ändert
Ja, tatsächlich eine gewisse Verschärfung, dass er sagt,
das sollten eigentlich primär kleine Änderungen sein. Sehr kleine,
sehr minimale Änderungen, um sozusagen immer auf einen guten Stand
zu kommen oder auf einen guten Stand zu bleiben.
Das habe ich jetzt eben schon angedeutet.
Also man kann diesen Begriff jetzt differenzieren. Es gibt eigentlich
mindestens drei, drei Bedeutungskontexte für den Begriff Refactoring.
Erstmal eine bestimmte Restrukturierung. Also ein konkreter Zusammenhang,
eine konkrete Tätigkeit. Ich stelle fest, eine Methode
Bad Smell heißt irgendwie komisch
Gibt nicht das wieder, was ihr eigentlich tut?
Also benenne ich die Methode um. Umbenennende Methode füge ein
in der Klasse Liste. Den nenne ich um in Einfügen.
Das ist jetzt vielleicht nicht so ein wahnsinnig offensichtliches Beispiel,
dass es eine bessere Benennung ist.
Aber hier wird was umbenannt. An einer konkreten Klasse
wird eine konkrete Methode umbenannt. Oder sowas wie Extrahieren,
das Interface ist Melder aus der Klasse Hauptfenster,
falls ihr hier dieses komische Grafenprojekt,
was ich schon ein paar Mal gezeigt habe.
Das sind konkrete Änderungen im Quelltext,
die aber in dem Verhalten der Software eigentlich
keine Veränderung bewirken
Und dann kann man aber auch natürlich so eine ganze Klasse von Änderungen,
also sowas wie eine Methode umbenennen,
also nicht eine konkrete Methode umbenennen, sondern allgemein dieses,
die ganze Klasse von Umbenennungen, diese Tätigkeit,
dieses Konzept von einer Methode umbenennen.
Das ist also die ganze Klasse von Restrukturierung,
das ist hier mit so einem großen Kar mal hervorgehoben.
Also abstrakte Beschreibung, katalogisierbar, das ist das,
was der Fauler in seinem Buch beschrieben hat.
Der Fauler hat in seinem Buch nicht geschrieben,
ich habe hier ein System und dann nenne ich jetzt mal
das und das oben und so.
Er hat das natürlich abstrahiert. Also sind das hier
quasi Klassentypen von Restrukturierung
Also Methode extra hier, Extract Message, Interface,
extra hier in Extract Interface und ähnliches.
Und er hat selber auch in diesem Zitat,
was ich auf der Folie vorher hatte, gesagt, naja,
auch die Tätigkeit des ruhigen Strukturierens selbst ist ja auch Refactoring.
Wir machen gerade Refactoring. Wir sind gerade dabei, unser System zu restrukturieren,
um einfach die interne Struktur ein bisschen lesbarer, wartbarer zu machen.
Okay, und das habe ich dann auch versucht auf die nächsten Folien.
Das ist im Skript nicht so drin. Das ist relativ neu,
so ein bisschen dann immer zu kennzeichnen,
indem ich dann immer so einen Tee dranhänge für die Tätigkeit,
Refactoring, die Tätigkeit und für die Klasse.
Und wenn es einfach nur ein konkretes Refactoring steht, einfach nur Refactoring.
Also eine schlechte Metapher für Refactoring. So, und das
ist wieder genau der Punkt, der immer ganz interessant ist.
Viele Leute sagen, da wird ja nichts am Verhalten geändert.
Dann ist das auch nicht relevant. Eine Software, die
irgendwie intern in ihrer Struktur geändert wird, wie interessiert denn das?
Das ist doch langweilig. Also eine Zeit lang gab es da
so diese Idee, dass das so ähnlich ist wie Bilder aufhängen.
Also wir dekorieren unser Zimmer. Ich habe eine Wohnung und da
hänge ich jetzt mal ein paar Bilder auf und das Ganze
ein bisschen hübscher zu machen.
Ich haue nicht eine neue Tür in die Wand oder ich
baue da nicht ein Rollo ran oder was.
Also funktioniert wird nicht geändert,
sondern ich mache es nur
ein bisschen hübscher
Ja. Einfach, damit wir uns wohlfühlen. Wir als Entwickler
haben ja Entwurfsregeln, wir haben Quelltextkonventionen, damit das alles,
damit alle glücklich sind, halten wir uns da dran.
Und das ist aber genau eigentlich keine gute Metapher.
Das wird einfach dem Anspruch von der Tätigkeit Refactoring nicht gerecht.
Es geht nicht um Schönheitspreise oder Eleganz, sondern um ziemlich pure Notwendigkeit.
Und das werdet ihr erst erfahren, wenn ihr ein System
mal über einen längeren Zeitraum anpassen und warten musstet.
Die sehr viel bessere Metapher für Refactoring,
also für diese Tätigkeit des Refactorings ist,
Müll raustragen
Ja, ich weiß nicht, ob ihr das schon mal erlebt habt,
wenn ihr vergessen habt oder wenn ihr irgendwie, wenn ihr es überfällig ist,
dass der Müll mal rauskommt, dann quillt der Mülleimer über.
Ich habe das erlebt, als ich noch Vimi war in Ulm
an der Uni, da war ich auf einer Partyunterlagen,
dann irgendwie fünf gelbe Säcke vollgefüllt in der Küche rum und es roch etwas unerfreulich.
Und in so einer Küche, weiß nicht,
ob man da dann große Lust hat, irgendwie abzuwaschen zum Beispiel,
weil das Ring stinkt ja sowieso schon,
da muss man den Abwasch auch nicht mehr abwaschen,
kann man ja auch stehen lassen.
Also so, ja. Und in so einer, in so einer Umgebung
hat man dann auch nicht Spaß zu arbeiten. So,
und Das ist bei Softwareentwicklung ist das auch so,
wenn man so unter Hitze des Gefechts irgendwie ganz schnell,
was reinbaut und irgendwie was umbenennt oder neue Funktionalität reinbaut,
dann werden irgendwelche Leichen immer überbleiben.
Da gibt es Kommentare, die nicht nachgezogen sind,
da gibt es Klassen, die nicht mehr benötigt werden,
alles möglich, alles denkbar.
Und das Zeug kann man einfach liegen lassen oder man kann es wegräumen.
Und die Idee ist halt, wenn man das nicht tut,
dieses Wegräumen und Aufräumen, dann wird man irgendwann an seinem Müll ersticken.
Dann gibt es so einen Entropee-Creep, also so,
dann wird das System immer komplexer und immer unwahrtbarer und
am Ende ist es tatsächlich nicht mehr weiterentwickelbar
Diese Idee mit in einem nicht aufgeräumten Kontext hat man keine Lust,
ordentlich zu sein. Das ist, glaube ich, nicht
so ganz falsch. Es gibt da verschiedene Untersuchungen dazu.
Da gibt es zum Beispiel auch die Broken Window Theory.
Ich weiß nicht, wer da mal davon gehört hat.
Das war so ein Experiment in den USA.
Da haben sie ein Auto, mehrere Wochen auf einem leeren
Parkplatz stehen gehabt und da dem Auto ist nichts passiert.
Dann haben sie sehr gezielt eine Scheibe dieses Autos eingeschlagen.
Und dann verfolgt was mit diesem Auto weiter passiert.
Und dann innerhalb kürzester Zeit waren dann auch die anderen Scheiben eingeschlagen.
Irgendwann waren die Radkappen geklaut. Irgendwann waren die Räder abgebaut
Weil das ist ja sowieso schon kaputt. Oder ich erinnere mich,
als ich in Ulm war, da gab es irgendwie so ein Haus,
das war irgendwie abrussfähig und da waren lauter eingeschlagene Scheiben.
Dann war man schon mal versucht,
dann nochmal einen Stein hinterherzuwerfen und nochmal so ein Stück Scheibe zu erwischen,
was da noch irgendwie so stehen geblieben ist.
Habe ich natürlich nicht gemacht. Ich war nur versucht,
aber ja, also wenn da schon was kaputt ist,
dann, boah, ist man eher versucht, da auch nicht,
sich jetzt groß Mühe zu geben, da Ordnung zu halten.
Und das ist eben halt auch die Idee von Refactoring.
Also wenn ich in einem System arbeite,
wo alle Entwickler irgendwie machen, was sie wollen,
jeder hat seine eigenen Regeln, keiner hält sich an die Quelltextkonvention,
das ist irgendwie alles so,
ach scheißegal
Als Entwickler da reinkommt und sagt, ich möchte aber jetzt,
dass wir das hier irgendwie, als Einzelner ist das dann oft nicht so schwierig, nicht so leicht.
Gut, das ist so ein bisschen der Hintergrund, Hoaken,
Windows Theory und wie gesagt, die Motivation für Refactoring sind üble Gerüche.
Das heißt, woran erkenne ich denn, dass ein System jetzt Refactoring nötig hat? So,
und da gibt es eben halt so die klassischen Dinge,
die ihr auch schon von mir gehört habt,
sowas wie Code-Duplizierung, das ist problematisch,
weil an einer Stelle, wenn er ein bestimmter Quelltext abfüllt,
steht und er steht an einer anderen Stelle nochmal identisch,
dann erstens weiß man nicht, dass das,
was hier steht, da aufsteht,
weil da ist ja kein Kein Kommentar dran,
steht nochmal woanders.
Sondern das ist einfach so meistens. Und das heißt,
es gibt auch eine implizite Kopplung. Das heißt,
wenn hier was geändert wird, dann ist es ziemlich wahrscheinlich das,
was hier auch geändert werden muss, weil hier möglicherweise,
wenn hier ein Fehler war,
dann ist der Fehler vermutlich auch in der duplizierten Celle drin.
Und dann hat man schon eine implizite Kopplung,
die aber keiner erkennen kann. Außerdem ist es niedrige Korresion,
hier zwei Quelltextstücke, wo geht es denn hin,
eventuell eine dritte Stelle, weiß man nicht.
Auf jeden Fall ist das ein typisches Beispiel für einen üblen Geruch.
Und wenn man dann so etwas tut, wie diese Duplizierung aufzuheben,
dann ändert das nichts an dem Verhalten der Software,
aber die Struktur ist möglicherweise lesbarer und nachvollziehbar für Leute,
die es warten müssen
Weiteres Beispiel, große Einheiten, auch in dem Faulerbuch natürlich mit aufgeführt.
Er hat da eine ganze Menge von üblen Gerüchen in dem Buch auch aufgeführt.
Wie gesagt, das lohnt sich, auch das zu lesen. Ja,
die Gottklasse irgendwie riesengroß, alles ist da drin oder Methoden,
die mehrere Bildschirmseiten lang sind, ganz schlecht.
Oder Klassen mit mehreren hundert Methoden und Exemplarvariablen.
Das ist alles, das soll eigentlich nicht passieren.
So diese Bloadware, so Dinge, die irgendwie unwartbar groß sind.
Das ist ganz interessant. Er hat auch noch
einen üblen Geruch in dem Buch drin,
den ich jetzt hier in der Folie nicht als Beispiel
aufgeführt habe
Nochmal so reingeblättert und dann gedacht, das ist ja interessant, Kommentare.
Er hat Kommentare als einen üblen Geruch bezeichnet. So,
jetzt kann man die sagen, boah, das kann ja wohl nicht wahr sein.
Wir werden hier gezwungen, immer gute Kommentare zu schreiben.
Was er meint, ist, wenn man einen Kommentar schreiben muss,
ist das oft ein Zeichen für einen Bad Smell in dem Sinne,
dass man erklären muss, was da passiert.
Wenn man zum Beispiel bei einer Methode die ABC heißt,
erklären muss, dass sie Füge eintut,
dass sie etwas einfügt,
dann sagt er,
dann benenn doch lieber die Methode um und nennen sie wirklich
Füge ein und dann brauchst du
den Kommentar vielleicht nicht mehr
Ist, finde ich, ein bisschen übertrieben. Es gibt sicherlich
Situationen, wo das nützlich ist, Kommentare zu schreiben.
Was er aber auch sagt, ist,
was ein ganz gutes Argument ist für einen Kommentar ist,
nicht zu schreiben, was an einer bestimmten Stelle passiert,
weil da steht ja im Code.
Das sind also so Leute hier, Martin Fauler,
Can't Back, die vertreten die Haltung.
Der Code sollte für sich selbst sprechen. Der sollte so gut geschrieben sein,
dass er so lesbar ist, dass man keinen Kommentar braucht.
Aber was man in einem Kommentar schreiben kann, ist,
warum etwas da so ist. Sowas wie eine Entwurfsentscheidung zu sagen,
wir haben an dieser Stelle uns dafür entschieden,
das so und so zu bauen,
weil die andere Möglichkeit leider nicht in Frage kommen,
so, so, so.
Und dann hat der Kommentar plötzlich einen Mehrwert,
weil ein etwas festgehalten ist, was man am Quellentext nicht erkennen kann.
Okay, aber das ist nur so ein kleiner Seitenausschnitt.
Weitere üble Geruchsverletzung des Law auf die Miete,
das nennt er, glaube ich, ein bisschen anders.
Das ist so diese langen Aufrufketten hier, die werden da auch irgendwo benannt.
Das habe ich auch schon diskutiert hier. Also wenn wir irgendwie der Klient jetzt irgendwas an einem Studenten macht,
Get Record, Get Examentry at Result, also diese ewig langen Dinger,
habe ich auch erklärt, dass das bedeutet,
dass eigentlich der Klient an alle diese implizit, nenne ich explizit,
sondern explizit gekoppelt ist und deine Abhängigkeit besteht und man dann,
wenn sich diese Struktur irgendwie ändert, nicht mehr so flexibel ist,
dann muss man das wieder ändern.
Und deswegen eine bessere Idee hier sowas wie, ich mache eine New Scorecard,
also irgendwie da für die Ergebnisse einer bestimmten Klausur,
trage da die Ergebnisse ein in diese Scorecard und dann sage ich dem Studenten,
also der Klasse, dem Exemplare, der klassische Student,
trag doch mal Dienstscore,
der da eingetragen ist für dich in deinen Rekord ein.
Das heißt, der Klient hat eine klare Schnittstelle gegenüber
dem Studenten und sagt, hier,
trag das da ein
Und das ist dann deutlich, ja, knapper und klarer,
was da passiert. Okay, was ganz wichtig ist,
wenn man sich jetzt die Refactorings von fauler und näher anguckt,
ist, dass er die mit ihrer Mechanik beschreibt,
also die Mechanics von den Refactorings.
Und jetzt sind tatsächlich diese Klassen von Refactorings gemeint,
also sowas wie allgemein Methode umbenennen oder extrahiere Interface.
Die beschreibt er ja, das ist ja
dieser Katalog in seinem Buch
Und da versteht man eine knappe und präzise,
schrittweise Beschreibung, wie das Refactoring ausgeführt werden soll.
Das klingt erstmal so relativ harmlos, naja, logisch,
eine präzise und knappe Beschreibung. Und der Anspruch bei diesen
einzelnen Schritten von diesen Mechanics ist immer, oder meist,
dass das System nach jedem Schritt übersetzbar ist.
Also dass man sozusagen,
um von einem Zustand in einen gewünschten anderen Zustand zu kommen,
möglichst kleine, aber dann sehr sichere Schritte macht und dann immer wieder überprüfen kann,
ob noch alles funktioniert.
Statt irgendwie einmal so einen riesen Sprung zu machen und dann
irgendwie voll auf die Nase zu fallen,
werdet ihr wahrscheinlich,
wenn ihr Software entwickelt,
nochmal erleben
Sollten diese Schritte möglichst klein gewählt werden und immer wieder sich absichern,
dass auch alles noch funktioniert und übersetzbar ist.
Also Schritte von solchen Mechaniken, also Schritte,
einzelne Schritte können sein, erzeuge eine neue Klasse mit einem bestimmten Namen.
Also einfach nur so ein Teilschritt. Oder füge eine neue Methode hinzu,
kopiere den Quelltext einer Methode in eine andere, entferne eine Methode.
Das sind so, das sind so Bestandteile von Refactorings.
Aus denen sind diese Refactoring-Muster praktisch zusammengesetzt. Das hier ist
Ein Zitat aus dem Vorwort zu Faulas Buch von Erich Gammer.
Und er sagt, Some of the Refactorings may seem obvious,
but don't be foold understanding the mechanics of such refactorings is the key to refactory in the Disziplin way.
Also, das, was ich jetzt hier gleich erläutere,
diese Mechanik von einem Refactoring, das mag erstmal ganz offensichtlich sein,
aber es ist tatsächlich Talent stellenweise sehr tricky, was da passiert.
Und wenn man wissen will, was da wirklich passiert,
dann muss man sich das schon sehr genau angucken
Und das ist unter anderem auch deshalb wichtig,
damit man dann auch die Grenzen einzuschätzen weiß.
Wenn ihr in den Clips so von der Entwicklungsumgebung so nette
Refactorys angeboten bekommt und ich kriege dann immer so leichte Schweißausbrüche,
wenn dann so Studenten so vor meinen Augen irgendwie so,
oh, wow, Rettering, zack.
Und dann ist alles umbenenannt. Und ich bin dann immer so ein bisschen so,
habt ihr euch das auch wirklich gut überlegt und so?
Weil den meisten eben nicht bewusst ist,
was da alles so an Nebeneffekten dranhängen kann.
Und das kann man sich eben halt angucken,
wenn man mal so ein Refactoring durchspielt.
Wer von euch kennt, Erich Gamma,
wer hat schon mal von dem Namen gehört,
Erich Gamma
Tja, ja, so ein paar Leute, genau.
Das ist einer der ganz Großen der Informatik,
also der steht in meinem Weltbild so auf der anderen Stufe mit Dixtra und Horror und also es ist wirklich,
ja, aber er ist noch ein ganz junger Kerl,
also relativ jung zu den anderen, die ich genannt habe,
gilt aber schon als einer der Klassiker.
Er ist ein Mitautor von dem berühmtesten und meistverkauften Informatikbuch,
das ist das über Design Patterns, ja,
haben wir ja hier auch schon vorgestellt, Design Patterns,
da ist ja ein Mitautor, einer von den Vieren,
Außerdem ist er der Chefarchitekt von Eclipse.
Also er hat tatsächlich Eclipse maßgeblich mitentwickelt. Er hat bei
IBM OTI gearbeitet in Zürich und hat da Eclipse mitentwickelt.
Er hat dann nebenbei noch mit Cant Back zusammen Jae Unit entwickelt.
Also auch eine Software, die eine gewisse Relevanz hat,
so in einem bestimmten Umfeld von Java-Entwicklung.
Und hat ganz viel mit CPlus früher gearbeitet,
ist dann ganz stark auf Java gewechselt.
Und er ist außerdem noch eine ganz nette Person.
Also er ist ein sehr angenehmer Mensch. Er wird
schon mal erlebt in diversen Kontexten und das ist wirklich,
also wenn ihr was von dem liest, dann könnt ihr davon sicher,
könnt ihr sicher sein, dass das irgendwas Vernünftiges ist,
also dass man da was mit anfangen kann.
Es ist kein Spinner, er ist promovierter Informatiker,
aber hat dann den Weg in die Industrie genommen und hat eben halt da,
ja, macht er ja seit Jahrzehnten Softwareentwicklung.
Also kein Akademiker. Der Fauler übrigens auch nicht,
der Fauler ist auch kein Akademiker. Es ist jetzt hier kein,
ich würde keine Lanze brechen für Nicht-Akademiker,
aber in der Softwareentwicklung ist da tatsächlich ziemlich viel gekommen aus der Ecke von Leuten,
die es wirklich tun.
Und da entsprechend ihre Erfahrungen dann weitergeben
Okay. Hier ist jetzt mal ein Beispiel für die Mechanics von
einem Refactoring. Und zwar dieses Refactoring heißt Methode Umbenennen.
Und das ist hier schon vereinfacht. Wenn ihr das
im Fouler nachliest, dann sieht das deutlich umfangreicher aus.
Hier keine Berücksichtigung von Ober- und Unterklassen. Also das werden wir
auch dann gleich sehen, dass das eventuell zu einigen Problemen führt.
Wenn man das nicht berücksichtigt. Und hier ist einfach mal dieses
diese Mechanik benannt. Und erstmal kann man sich die Mechanik angucken,
um zu verstehen, was unser Gedanke ist,
hinter diesem Refactoring, also hinter dem, mit der cleveren Idee,
wie man das Refactoring durchführt.
Also die Idee ist, ich möchte also eine Methode umbenennen,
ich deklariere einfach erstmal eine neue Methode mit dem neuen Namen.
Also ich sage jetzt irgendwie, die soll A-Methode A soll
in B umbenannt werden. Dann führe ich erstmal die Methode
B ein und kopiere den alten Quelltext in die neue Methode
und mache die notwendigen Anpassungen, falls ich da irgendwie,
wahrscheinlich muss man da gar nicht so viel anpassen.
So, und dann übersetzt man, warum sollte man
da übersetzen? Was kann denn da schon schiefgehen
Methode einführt mit einem bestimmten Namen, ja? Ja,
das könnte sein, dass man es auch bald beschrieben. Ja,
es könnte sein, dass man es falsch geschrieben hat,
aber das ist nicht so schlimm,
weil der Name ist ja sozusagen erstmal frei wählbar,
ja, da hinten ist noch eine.
Genau, die Methode kann schon vorhanden sein,
möglicherweise gar nicht in der Klasse, sondern in einer Oberklasse, ja.
Klar, aber ich habe es ja gesagt, keine Berücksichtigung,
aber hier an dieser Stelle ist es einfach schlau,
erstmal zu gucken, ob die Methode möglicherweise schon da ist.
Das ist noch eine andere Meldung. Ja. Es kann auch sein,
dass man die Konvention nicht einhält,
ob die dann von dem Compiler überprüft werden, ist eine andere Frage,
ja, aber auf jeden Fall ist es hier vorgeschlagen,
direkt zu übersetzen.
Also tatsächlich auch dieses, mach einen kleinen Schritt und dann übersetze.
Dann ändere den Rumpf der alten Methode so, dass er
die neue Methode ruft. Aha, also aus der Methode A,
die ja von allen Klienten irgendwie aufgerufen wird,
wird jetzt die Methode B aufgerufen, die ja den gleichen Code enthält wie die alte Methode A.
Das ist eine Umleitung, die da gebaut wird.
Also irgendwie A ruft B auf und B macht dann das,
was A vorher gemacht hat.
Da wird wieder übersetzt und getestet. Da wird dann
auch getestet. Also tatsächlich, wenn man Testklassen hat,
werden die ausgeführt
Okay. Dann findet alle Referenzen, hier wird es natürlich jetzt spannend,
auf die alte Methode und ändere sie so,
dass sie auf die neue verweisen.
Also überall da, wo diese Methode A aufgerufen wurde,
muss ja jetzt das NB geändert werden.
Das möchte man ja. Und das ist das, was
das Refacting so unangenehm macht. Wenn ihr in eurer Klasse
eine Exemplarvariable umbenennt, dann ist der Schaden relativ gering,
weil ihr seid die einzigen Klienten von den privaten Feldern und von euren privaten Methoden.
Das heißt, das ist sehr klar überschaubar,
wer davon betroffen sein könnte
Wenn man an der Schnittstelle einer Klasse eine Methode umbenennt.
Ja, alle potenziell, alle möglichen Klienten könnten davon,
nee, müssen davon betroffen sein.
Und da muss man eben tatsächlich alle Referenzen finden.
Und dann an jeder Stelle wird das Ding geändert.
Und dann wird übersetzt und dann wird getestet.
Auch da wieder, man weiß ja nicht,
ob da möglicherweise irgendwas an der Stelle schief geht,
wo das jetzt da umbenannt wurde.
Okay. Und wenn man dann alle diese Stellen gefunden hat,
dann kann man die alte Methode entfernen.
Und dann kann man nochmal übersetzen und testen.
Und dann ist man fertig
Das ist so die einfache Idee von Methode umbenennen.
Methode umbenennen ist eines der am häufigsten benutzten Refactorings.
Tatsächlich ist es fürchterlich, wenn man dieses Refactoring von Hand
durchführen muss. Ich habe ja das BlueJ-Buch übersetzt,
ich habe ja ja tatsächlich dann diese ganzen BlueJ-Projekte auch übersetzt
und habe da natürlich auch die Methoden alle umbenannt und ich hätte ohne die Unterstützung von Eclipse,
wäre ich wahrscheinlich verzweifelt, weil das echt eine Wartungshölle ist.
Selbst diese kleinen Projekte sind da schon relativ unangenehm.
Die da in dem BlueJ-Buch auch drin sind
Deswegen gibt es ja in den Clips eine mechanische Unterstützung,
die werden wir uns auch gleich mal ansehen.
Okay, ich will dieses Refactoring jetzt mal live durchführen mit euch.
Also ich werde jetzt hier euch eine konkrete Aufgabe zeigen,
an der wir ein Refactoring durchführen wollen.
Und dafür werde ich ein bisschen ausholen, nämlich,
dass wir auch mit unseren Kinoticket-Verkaufssystemen über die Jahre gelernt haben,
wie unangenehm es sein kann, wenn so ein System degeneriert.
Wir haben das, was wir hier sozusagen predigen,
nur in diversen realen Projekten erlebt,
sondern auch in unseren Lehreprojekten hier,
dass so ein Projekt wie ein Kinoticket-Verkaufssystem über die Jahre von verschiedenen Leuten gewartet wird,
von verschiedenen Wimmies, von verschiedenen Studenten.
Irgendwie wird da was, dass das tatsächlich Gefahr läuft,
zu entarten, also zu verwartzen.
Da kommt immer mehr rein, was irgendwie da nicht reingehört.
Also ich kann zum Beispiel mal zeigen, hier Kinoticket verkauft
2013. Das kennt ihr. Das sieht so aus.
Da sind irgendwie diese vier Pakete, Fachwerte, Materialien,
Werkzeuge, keine Services, ein Start-up.
Das ist so die Struktur, die wir euch ja vermittelt haben.
Und dann nach dieser Struktur nutzen Entwurfsregeln ist das
auch gebaut
Ich kann das hier mal starten. Das sieht also dann so aus, hier Start-up-Kino
2013. Das ist das, was ihr kennt. Ja,
ein bisschen schneller könnte es schon gehen, aber immerhin,
es kommt dann. So, dann habe ich hier irgendwie
was auswählen und dann kann ich hier was verkaufen, Kino-Karten verkauft
2013. Kann ich hier verkaufen, dann kann ich hier
irgendwie sagen, 20 Euro Geld erhalten, herrlich.
So, wunderbar. Ihr seht hier so diese Oberfläche mit
diesen Kinoseelen und dem Datum und den Vorstellungen,
die da links angezeigt werden, das sieht ja ziemlich bekannt aus.
Das sah 2012 genauso aus
Also 2012 hatten wir auch schon mit den Entwurfsregeln gebaut.
Also hier sieht das genauso aus. Kann man auch mal starten,
dass sie dann wirklich genauso aus Start-up-Tino-Ticket 2012. Und da sieht
das also, ja, genauso aus, würde ich sagen.
Mal gucken, ob hier irgendwie sich was verändert hat.
Ja, nö, das sieht also auch genauso aus, ja.
So, ja, man kann auch hier irgendwie weiterklicken und
so weiter. So, dann hatten wir aber 2010,
und das ist jetzt ein Sprung,
hatten wir ein völlig anderes System, nicht völlig anders.
Also auch das kann ich erst mal zeigen in der Ausführung,
das sah sehr ähnlich aus,
ungefähr so
Also auch hier wieder dieses Panel mit diesen ganzen Plätzen.
Man kann hier mit dem Datum irgendwie blättern,
dann kann man sich hier irgendwie, und war aber das
hier ein bisschen anders gebaut mit den verschiedenen Vorstellungen.
Das waren die verschiedenen Kinoseele, konnte man hier noch auswählen.
Kino, Luxus, Kino gehoben, was weiß ich,
ja, gehoben ist. Und dann Luxus war dann irgendwie
ganz viel Platz zwischen den Sitzen mit, was weiß ich,
Tischchen, wo man seine Nachos draufstellen kann.
Ja. Und das haben wir dann geändert. Also da
ist tatsächlich die Oberfläche ein bisschen anders. Aber eigentlich in
der Funktionalität relativ gleich, das ist jetzt auch ein Update-Problem,
gerade, ja, sieht nicht so gut aus. Okay,
also das seht ihr, das ist eigentlich das gleiche System,
man kann da durchblättern, man kann eine Vorstellung auswählen,
kann dann was verkaufen, ich weiß nicht,
ob das hier funktioniert mit dem Verkaufen,
mal gucken
Das ging dann jetzt, ohne da ist das anscheinend noch nicht reingebaut mit dem Barteilungsding.
So. Dieses System sieht aber intern ganz anders aus.
Das sieht ungefähr so aus. Da gab es irgendwie Fachwerte,
dann gab es UI, dann gab es Vorstellungen und dann irgendwie ein Start-up.
So. Mit unserem, mit unserer Einstellung, wie sowas gebaut werden soll,
wenn wir heute sagen, oh, das ist ja irgendwie komisch.
Das ist also irgendeine Paketstruktur. Irgendeine, so. Und das ist passiert,
weil Leute, das System der Vorjahre irgendwie überarbeitet haben und festgestellt haben,
oh, das müsste man eigentlich zusammenfassen, die Sachen,
die irgendwie mit der UI zu tun haben,
die gehören irgendwie in die UI-Package
Also so quasi so anhand von, ja, da hat sich jemand überlegt,
wie er es restrukturieren würde, hat es dann restrukturiert.
Also da intern sieht es ganz anders aus,
aber es ist quasi das gleiche System.
Dann, also die Entwurfsregeln haben wir 2011 eingeführt. 2011,
2012 ist das dritte Jahr, jetzt hat die Entwurfsregeln bei
uns hier propagiert werden und auch durchgehalten werden von uns.
Vorher war das halt irgendwie. Aber das ist nicht ganz richtig,
weil wir hatten ganz früher schon mal ein System,
das nach solchen ähnlichen Regeln gebaut war.
Und das von 2008 ist auch nochmal lustig,
weil das sieht dann so aus.
Das steht alles im Deport Package
Alle Klassen hier, in dem Default Package.
Das war damals noch die Zeit, als das Kinoticket-System von
den Studierenden dann in Pakete aufgeteilt werden sollte.
Also das, was wir mit euch jetzt in der Mediathek
machen, haben die mit dem Kinoticket-Verkaufssystem gemacht damals.
Aber das sieht dann, wie gesagt, sehr ähnlich aus.
Ich kann ja auch nochmal das Start-up hier benutzen
2008. Das sah so aus. Also auch wieder sehr ähnlich
wie das von 2010. Hier konnte man irgendwie das Kino auswählen,
dann könnte man hier irgendwie einen weiterblättern.
Dann konnte man hier irgendwie was auswählen und dann könnte man
auch hier wieder irgendwas selektieren und verkaufen.
So. Also auch das eigentlich das gleiche System.
Immer noch das gleiche System. Funktionalitäten mehr oder weniger gleich
Oberfläche ein bisschen anders, aber so das Gleiche.
Aber auch wieder, naja, also mit gar keiner Struktur.
Und das zeige ich euch jetzt mal in Blue Jay.
Weil das ist noch relativ klein.
Man kriegt das im Blue Jay ganz gut dargestellt.
Ja, ja, das ist doch übersichtlich, oder nicht?
Also man hat hier wieder diese Start-up-Klasse und dann sieht man hier,
gibt es irgendwie so ein, was man hier jetzt,
was man nicht sehen kann, unbedingt,
aber was ich jetzt hier mal eben beschreibe, ist,
hier gab es einen Schnitt,
einen logischen Schnitt
Haben wir das damals so gebaut, das System für
die Studierenden, dass der ganze Gui-Kram schon da ist.
Wir wollten die Studierenden keine Gui bauen lassen aus dem,
das war in den alten Zeiten noch vor SE1 oder SE2.
Wir sollten nur sozusagen hier diese Materialien bauen und den Service und
also sie sollten sozusagen, das sollte gebaut werden hier.
Aber das sollte eigentlich unverändert bleiben. Diese Gui hier sollte nicht
angefasst werden. Also haben wir eine relativ klare Schnittstelle definiert.
Ticketservice. Und über diesen Ticketservice werden nur Fachwerte durchgereicht.
Fachwerte und normale Werte, also in Buglien,
was weiß ich was.
Aber da werden keine Materialien durchgereicht
Das war tatsächlich mal von Leuten ursprünglich so gebaut worden,
dass das irgendwie eine wunderbare Trennung ist,
dass über diese Schnittstelle hier keine Materialien durchgeschickt werden.
An diese Oberflächenelemente. Das ist ganz wichtig als Entwurfsregel,
ganz schlau, wenn ihr irgendwelche Materialien habt,
die einen veränderlichen Zustand haben und ihr blast die da irgendwo in die Gui-Elemente rein,
keine gute Idee, weil diese Gui-Elemente laufen im anderen Thread
und dann kannst du dazu parallelen Veränderungen kommen und so weiter.
Also am besten gar nicht machen,
sondern alles über eine entsprechende Schnittstelle machen.
Das war damals auch so gebaut.
Warum erzähle ich das alles? Weil ich eigentlich nur auf
einen Punkt hinaus will. Ich wollte euch die Situation jetzt
näher bringen, die ich jetzt hier als Refactoring vornehmen will.
Nämlich in diesem Multiplex-Ticket-Service. Da gibt es jetzt eine Methode,
ich suche die mal, gib Phil.
So. Diese Methode gibt Film. Was fällt euch an dieser Methode
auf? Wer hat wer... Könnt ihr das erkennen,
Joa, kann man lesen, ne?
Ja. Da, was meinst du
Bitte? Oh ja, ja, also wenn man in
den Rumpf guckt, das sieht schon lustig aus.
Vorstellung der Datum geht hin und sagt, Uhrzeit, ja,
genau, also so, das ist so ein Beispiel für,
ne, läuft die Mieter massiv verletzt.
Aber was fällt euch schon in dem, in dem,
in der Signatur auf, dieser Methode, ja?
Gleich betitelt ihr das. Aha, er sagt, sollte vielleicht
Gip für einen Titel heißen. Warum sollte es Gip für einen Titel heißen? Naja,
weil in diesem System eine Klasse Film existiert,
die Operation heißt Deep Film, gibt aber kein Exemplar der Klasse Film raus,
sondern Sie liefert über diese Schnittstelle, über dieses Interface,
was ich gerade beschrieben habe, für die Gui,
eine Darstellung eines Films, damit der an der Oberfläche als Trink dargestellt werden kann.
Also wäre zum Beispiel, gibt Filmtitel schöner.
Jetzt können wir also sagen, na, wir wollen das jetzt mal umbenennen.
Wir wollen das also in Gip-Filmtitel umbenennen. Da ist eine Frage,
Benni, weil das ist schon ein Signatur, also dem Kinosaal,
vom Datenschutz hin zu machen und Geburtstag gefügst zu trinken,
das ist auch noch so etwas, wo man überlegen könnte,
ist, das konnte er heilen lassen.
Okay, er sagt, es ist, was auch komisch ist,
ist, dass hier Kinosaal und Datum und Uhrzeit hier als Int übergeben werden,
als String, das ist tatsächlich genau diesem Umstand geschuldet,
dass da irgendwann mal jemand diese Idee hatte, über dieses Interface,
über dieses Interface hier, Ticket-Service, sollen keine Materialien durchgereicht werden.
Also wurde das sozusagen flach geklopft und dann durch diese Schnittstelle,
durch diesen Flaschenhals durchgeschickt, in atomatisiert,
atomisiert in Dinge wie Ins und Ähnliches,
damit die auch angezeigt werden können, damit man sozusagen da eine String-Darstellung hat.
Ja, Uhrzeit hätte man als Fachwert bauen können.
Klar, also das ist vollkommen richtig. Also wie gesagt,
man sieht hier, dieses System ist von 2008,
das ursprüngliche System, war von 2003.
Also das ist über die Jahre anscheinend degeneriert.
Also weil Leute bestimmte Entwurfsregeln nicht mehr im Kopf hatten.
Und das ist keine Überraschung. So, ich würde jetzt gerne,
vielleicht nicht jetzt, sondern gleich nach der Pause,
ganz konkret dieses Refactoring Renay Method oder benennen eine Methode um,
durchführen in Blujay Jay, Blue Jain., hat keine Refactoring-Un-Uterstützung.
Das heißt, wir müssen wirklich die mechannigs mal durchspielen.
und wir werden dabei so einiges beobraften, was da so passieren kann.
d. Und dann dürt, das ist das ist minde,
de. Und dann de la de
Okay, dann würde ich sagen, lasst uns weitermachen. Also,
Methode umbenennen, ja,
das ist eine Klasse von Refact Andre,
ein Typ von Refactoring und wir machen jetzt ein konkretes Refactoring und wir machen das jetzt einfach mal so,
dass ich diesem Mechanics hier folge,
also deklariere eine neue Methode mit dem neuen Namen,
Ich kopiere den alten Quelltext in die neue Methode und mache die notwendigen Anpassungen.
Okay, also würde ich jetzt an dieser Stelle tatsächlich
mal jetzt diese Methode hier erstmal hernehmen. Ja,
ist jetzt die Frage, macht man das mit Kommentar oder ohne?
Ja, ich würde mal sagen, wahrscheinlich eher mit.
Copy. So, dann habe ich jetzt hier
Gib Film und da habe ich nochmal Gib Film.
Und jetzt kann ich diese Methode ja umbenennen.
Gib Filmtitel. Und was sagen die Mechanics
Und man kopiere den alten Quertext in die neue Methode und mache
die notwendigen Anpassungen. Also das habe ich jetzt tatsächlich gemacht.
Also ich habe sozusagen diese neue Methode hier eingeführt.
Das kann ich jetzt mal übersetzen. Das lässt sich übersetzen
. Da ist eine Meldung. Ja,
so ist aber bei der Gelegenheit dann nicht am besten auf deinen Kommentaren,
weil das glaube ich bestimmt lieber dem Film einer Vorstellung,
sondern über den Titel.
Okay, er sagt, da sollte man an der Stelle
nicht vielleicht schon den Kommentar auch mit ändern.
Vollkommen richtig. Also wenn ich jetzt hier sage,
gib Filmtitel und hier oben steht, gib Film,
dann könnte man ja hier sagen, liefere den Film Titel einer Vorstellung.
Machen wir das doch mal, ist doch
viel schöner.
Habe ich gemacht, habe ich übersetzt. Muss ich noch
was tun und erstmal nicht. Ändere den Rumpf der
alten Methode so, dass er die neue Methode ruft.
Also was wir bis jetzt gemacht haben, es ist noch
nichts passiert. Das System läuft noch völlig weiter.
Wir haben nur eine weitere Methode und haben festgestellt,
die ist als neues Mitglied in der Gemeinde aufgenommen.
Und jetzt machen wir das so, dass wir hier
diese andere Methode aufrufen. Also hier Return, pop,
pop, pop, pop, return, gib Filmtitel.
Und da muss ich jetzt als Parameter hier irgendwie Kinosaal,
Und Datum übergeben. Ich weiß nicht, ob das funktioniert.
Das lässt sich übersetzen. Jetzt habe ich also eine Umleitung eingebaut,
dass die alte Methode, die neue Methode aufruft,
da ist eine Frage. Die Frage ist,
ob er das hört, ob man das da lassen würde.
Ich denke ja, das ist hier an der Stelle
ja sinnvoll angebracht. Es überprüft eine Vorbedingung und die Methode
ist ja noch da und wird auch noch aufgerufen.
Also für das Refactoring ist das erstmal was,
wo ich jetzt sagen würde, ja,
ich lasse es da stehen.
Man könnte natürlich auch jetzt sagen,
eigentlich wird das Ding ja hier auch gleich rausgeschmissen
Es ist egal, ob es stehen bleibt oder nicht,
stehen bleibt, ja? Ich wollte es ja mal jetzt sagen,
du hast es ja nicht vergessen, mein Papier beispielsweise,
beim Sitzer, dann werden wir ja in dem Fall jetzt mal nicht sichergestellt haben,
was der vom Kilo Vorgang mit der anderen,
also um das auch zu funktionieren.
Okay, also er sagt, wenn man jetzt da tatsächlich
was kopieren musste und dann vielleicht dabei irgendwie einen Fehler gemacht hat,
dann könnte es sein, dass mit dem Assert vielleicht was aufgedeckt wird,
dass man an der Stelle... Ja, könnte sein,
genau.
Also von daher, also ich würde jetzt dazu neigen,
das Assert stehen zu lassen,
aber genau
Die Mechanik sagt jetzt, also alte Methode,
ist die neue Methode ruf, übersetze und teste.
Gut, wir haben jetzt übersetzt. Das heißt, wir
können das mal schließen. Wir müssen jetzt alles übersetzen,
weil wir natürlich jetzt hier auch es geändert haben,
so müssen wir mal die Tests alle ausführen hier.
Nee, nicht so, sondern tatsächlich. Du,
nee, Quatsch. Ach, ich weiß schon.
Werkzeuge, Einstellungen, diverses Testwerkzeuge anzeigen. Wollt ihr
eigentlich vorher gemacht haben? So Tests starten. Ja,
also die Tests laufen noch durch. Überrascht uns nicht,
dass die Tests noch durchlaufen,
weil wir ja noch wirklich nicht viel geändert haben
So, jetzt findet alle Referenzen auf die alte Methode und
endet sie so, dass sie auf die neue verweisen.
Jetzt wird es unangenehm. Also in den alten Tagen der Programmierung,
und das wird ja in Blue Jay so ein bisschen,
sagen wir, euch nochmal so nahe gebracht,
da hatte man nicht eine tolle IDE, wo alles integriert war.
Und man konnte da auch jetzt nicht einfach über alle Quelltextdateien hinweg suchen.
In Blue Jay kann ich innerhalb eines Editors suchen,
aber ich kann nicht suchen innerhalb des gesamten Paketes.
Oder das ganze Projekt ist. Okay, das ist ja
aber zum Glück alles in einem Verzeichnis hier. Das heißt,
ich kenne jetzt einfach mal hier in dieses Kinoticket-Verkauf-Verzeichnis reingehen,
das ist das Verzeichnis,
in der der ganze Quelltext steht
Und ich kann jetzt mir mal diesen Pfad hier kopieren und
mache mal wieder, was euch hoffentlich nicht zu sehr erschreckt.
Also benutze hier mal ein Command-Tool, so.
Und dann sage ich hier CD, einfügen, zack,
eins stehe ich in dem Verzeichnis. Bin also jetzt tatsächlich
in diesem Verzeichnis. Und hier kann ich jetzt sagen,
Feind, finde, alle auftreten und dann sage ich ihnen da irgendwie,
wie war das irgendwie, ich glaube so eng,
dann wird die Nummer mit ausgegeben, an der Stelle in die Datei,
wo dann diese Stelle gefunden wurde, gibt Film
Und zwar in Stern. Java. So,
in allen Java-Dateien, also dieses Stern ist eine Wildcard,
in allen Java-Dateien sollen nach Gip-Filmen gesucht werden.
Das ist hier sozusagen der nackte, der nackte Suche in den Textdateien.
So, dann kommt hier was dabei raus,
dass uns ja dann die ganzen Stellen liefert,
an denen wir vermutlich jetzt unseren Gipfeln in Gip-Filmtitel umändern müssen.
So, da sieht man jetzt hier, da kommt einiges raus.
Erstmal werden hier alle Dateien aufgelistet, in denen auch nicht
gefunden wurde. Ja, ein bisschen lästig. So,
dann sehen wir hier als erstes Kassenwerkzeug. Aha,
streng Film ist gleich Ticketservice,
gib Film
Okay, das würden wir wahrscheinlich dann ändern wollen,
weil da wird ja wirklich ein String geliefert.
Dann haben wir hier Multiplex, Ticketservice Java, da haben wir es gerade geändert.
Da gibt es natürlich noch unser altes Gipfel. Und dann haben wir hier,
gibt es für einen Titel, da wird das Win-Titel aufgerufen,
unser neues, ja okay, weil in Gipfel gibt es Filmtitel,
natürlich Gipfel mit drin, deswegen wird es auch gefunden.
So, und dann haben wir hier, oh, schön.
Dann gibt es hier Ein Multiplex-Ticket-Service-Test, eine Stelle,
wo dann dieses Gip-Film auch aufgerufen wird.
Auch anscheinend dieses von dem Ticket-Service, also Gip-Film,
das ist genau das, was wir da irgendwie brauchen.
Und dann gibt es hier noch eine Stelle,
gibt Film von dem Ticket-Service. Ah, okay, Ticket-Service.
Ticket-Service ist das Interface, was wir implementieren. Okay,
dann müssen wir gleich mal gucken, wie wir das dann angehen.
Dann gibt es hier noch einen Vorstellungpunkt Java und da gibt
es auch einen Gip-Film und das lief wirklich ein Film.
So, jetzt sind wir schon den ersten Aspekt,
so eine Umbenennung
Wenn die jetzt einfach mit textueller Ersetzung arbeiten würde,
also so ein Werkzeug, das irgendwie sagt,
ersetze alle Auftreten von diesem String durch den anderen.
Würde nicht funktionieren, weil ja semantisch dieses gibt Film und
das andere, die verschiedene Methoden sind.
Also ein flaches Textersetzungswerkzeug würde uns hier schon nicht so richtig weiterhelfen.
Aber wir haben ja jetzt erstmal nur alle Stellen gefunden,
an denen wir was tun wollen und können ja jetzt mal einfach diese Stellen durchgehen.
Also das ist jetzt ja auch nicht so ein Riesenaufwand,
zum Glück sind es ja nicht so viele Stellen.
Also Kassenwerkzeug hier, Ticketservice gibt Film,
ändern wir jetzt mal in Gip-Filmtitel.
Also gehen wir hier in das Kassenwerkzeug rein
Suchen mal nach, gib Film. Aha, da ist
der Aufruf. Gut, dann sage ich jetzt hier einfach,
gib Film Titel. Ja, ich kann das mal speichern.
Ich kann das mal übersetzen. Jetzt gibt es ein Problem.
Was ist das Problem? Wer weiß, was hier schiefgelaufen
ist gerade? Ja, wir machen das Ding des Services.
Mütterplaces. Richtig. Also, wir haben hier die Spezialsituation.
Er sagt, er nimmt an,
dass das Ticketservice ein Interface ist und in dem Interface gibt
es ja noch keinen,
gibt Filmtitel
Da wird es schon jetzt ein bisschen unangenehmer, ja.
Wir haben also tatsächlich die Situation, dass diese Klasse hier dieses Ding implementiert.
Und eigentlich müsste, wenn wir die Methode hier umbenennen müssen,
natürlich dann auch die entsprechende Methode im Interface umbenannt werden.
Was machen wir jetzt? Was machen wir jetzt? Ja.
Ich denke, man könnte jetzt mit dem Interface genauso plattfahren,
wie in der Revitation vorher. Das heißt, nach demselben Ablauf,
wo eine Methode erstellt, die die neuen Damen hat,
dann wird es sofort fahren und in der Revitation löschen bleiben,
dann wurde auch die Methode aller Methoden.
Genau, also er sagt, Was er machen würde,
ist, genauso vorgehen. Das heißt,
im Interface diese neue Methode einführen, diese neue Operation.
Also würde man das jetzt hier tatsächlich mal einführen.
Ich würde also jetzt hier in den Quelltext gehen,
würde nach Gib Film suchen und würde jetzt genauso hier diese
Operation hernehmen und kopieren und die neue Operation hier gibt,
Filmtitel nennen.
So, das kann ich hier erstmal übersetzen.
Und jetzt kann ich auch tatsächlich
das Kassenwerkzeug übersetzen
Ja, weil das tatsächlich jetzt mit diesem Interface,
das war jetzt ein anderer Fehler. Und jetzt kann ich hier
hoffentlich wieder übersetzen, okay, ich kann also noch übersetzen.
Und ich kann auch noch tatsächlich die Tests wieder ausführen.
Also hoffentlich geht das noch alles. Ja,
das klappt noch alles. Okay, das heißt,
ich habe jetzt nicht nur die Methode dupliziert im Multiplex-Dicket-Server,
sondern auch den zweiten Kanal geschaffen über das Interface.
Und das Kassenwerkzeug hat das Ding benutzt und deswegen funktioniert das
jetzt auch mit dem Klienten.
Gut, was hatten wir noch für Stellen, Kassenwerkzeug,
Multiplex-Ticket-Service, Java. Da haben wir ja schon was gemacht.
Der Ticket-Service-Test, aha
Multiplates, Git-Service-Tests, da gucken wir da noch mal rein.
Wir suchen mal nach Gipfeln. So, testet die Operation Gipfelm,
Test-Gipfelm, okay. Jetzt würde man wahrscheinlich hier Get-Film-Titel hinschreiben.
Geht für den Titel und get für den Titel. So,
was wir jetzt natürlich auch an dieser Stelle wieder gleich sehen,
wurde ja eben schon angemerkt, wäre es nicht schön,
wenn wir dann auch den entsprechenden Kommentar hier anpassen würden.
Also hier gebt für den Titel. Und eigentlich wäre es
sogar schön, wenn man die Methode,
auch die Ted-Methode hier umbenennen würde,
get für den Titel
Weil das ist ja das, was man da testet.
Gut, wir übersetzen das mal. Das lässt sich übersetzen,
wir testen, wir setzen alles, wir starten die Tests und das läuft.
Wunderbar. Also, was ist die nächste Stelle?
Platzpaaren, Panel, Tickets, Service haben wir schon geändert.
Da ist das Gipfel mir jetzt umbenannt, beziehungsweise wir haben eine zweite Operation eingeführt.
Und dann in Vorstellung Java. Und wir wissen jetzt,
durch Draufschauen, dass es ein anderes Gipfel ist,
deswegen ändern wir das jetzt nicht.
Also haben wir noch hier Vorstellungstest, da gibt es noch
einen Gipfel, also das wird nicht geändert.
Also sind wir eigentlich mit dem nächsten Schritt fertig.
Da ist eine Anmerkung
Ich fasse von der Bar aus, jetzt erst mal 14,
14, 1, 2, 1, 0, 0,
0, 0, so was in ein paar Jahren zu lassen.
Ein Kopf, wo es geschehbar werden soll, dass man eben dauert,
wenn der Bruder auch jemand dauert, schon vor Materie gefüllt,
was ist denn das für ein Schuldottitel, wo irgendwas das für macht,
weil das Gleiche hat das großartig gesagt, ja, was passt.
Okay, also er sagt, das kannst du so einem Schneeball-Effekt führen,
also wenn man jetzt alle Stellen ändert,
alle Klienten ändert und was du aber, glaube ich,
sagen willst, ist,
dass es kann an irgendeiner Stelle kann es ja krachen,
das heißt,
ich habe das jetzt an vielen Stellen gemacht und jetzt irgendwie bei der 70. Stelle stelle ich fest,
oh,
das funktioniert ja da jetzt nicht mehr.
Also man sollte ja hoffen, dass diese Änderung so
eigentlich durchführbar ist
Aber es kann eben halt an vielen Stellen krachen, genau.
Deswegen, dieses Unbehagen, das du jetzt da formulierst,
das will ich euch in die Köpfe pflanzen,
dass ihr das auch habt,
dass ihr eben halt nicht so sehr euch auf diese Tools verlasst.
So, ich gehe erstmal nochmal in die Mechanics rein.
Was steht jetzt hier? Übersetzer und Teste, finde
alle Referenzen haben wir gemacht. Entferne die alte Methode.
So, jetzt wird es interessant. Jetzt entfernen wir
die alte Methode. Wie gehen wir jetzt vor?
Wo entfernen wird die Methode? Ja? In die Kooperation
aus dem Internet, entfernen. Das ist ein Arm aus
der Integration
Okay, er sagt, ich würde zuerst die Operation aus
dem Interface entfernen und dann die Implementation, also die Methode.
Andersrum würde es auch nicht funktionieren. Also,
weil wenn ich zuerst die Implementation wegschmeiße, dann wird ja gesagt,
klasse, du implementierst nicht das Interface.
Also genau der richtige Weg. Man nimmt aus dem Interface
jetzt das GIP-Film raus. Okay, das machen wir mal
hier. In Forten übersetzen, das lässt sich übersetzen.
Auch da wieder nur um so eine blöde Warnung,
weiß ich jetzt nicht genau, was es ist.
So, und wir können auch die Tests nochmal durchführen.
Ja,
das klappt
Jetzt haben wir es da weggenommen. Und jetzt können wir
als nächsten Schritt auch hier die Methode wegnehmen.
Also das gibt Film, wird jetzt hier rausgenommen.
Und es dürfte auch niemandem mehr wehtun, weil es ja
von jemandem mehr benutzt wird und auch nicht mehr im Interface gefordert wird.
Also weckt damit, speichern, übersetzen, klasse,
alles übersetzen, alles nochmal testen.
Und wir sind mit dem Refactoring fertig.
So, das war jetzt mal ein Refactoring schrittweise durchgeführt.
Das Gleiche können wir jetzt mal in Eclipse machen
Ineclips ist das natürlich deutlich einfacher. Da kann ich nämlich
jetzt einfach sagen, ich gehe hier in meinen Multiplex-Ticket-Service
rein und kann jetzt hier wieder nach Gyp Film suchen.
So, hier ist Public Strang Gyphil. Wunderbar. Diese
diesen Bezeichner hier, da kann ich jetzt mit einem Rechtsblick sagen,
Refactor, Renay.
Also so ein Refactoring,
das eingebautes Ineclips
Und das Coole ist jetzt,
wenn wir das jetzt machen, dann sagt er hier,
Anton you name, Press Enter to Refactor.
Und man kann aber, also ich kann das jetzt erst mal machen,
ich kann jetzt hier sozusagen getfilmen, gibt für den Titel einfügen.
Wenn ich jetzt Enter drücke, dann wird das einfach durchgeführt.
Wir wollen jetzt uns mal angucken, was da passiert,
das ist ganz schön in den Clips,
da kann man sich das nämlich auch angucken, was denn passieren würde.
Preview oder Preview. So, dann sieht das so aus.
Man sieht hier alle Stellen, an denen er jetzt irgendwas ändern würde.
Also zum Beispiel sagt er hier ein Kassenwerkzeug,
ändere ich diese eine Stelle hier
Update Method Reeference. Also hier wird irgendwie, am alten
wird Gip-Film benutzt und im nächsten wird es dann Gip-Film-Titel.
Das sieht ja schon mal ganz gut aus.
Das ist auch die einzige Stelle, die wir hier haben.
Also wunderbar. Man kann jetzt hier so richtig schön
die nächste Änderung auch anwählen. Da kann man sagen,
aha, hier wird irgendwie, ach,
da hast du dieses Gip-Film-Gip-Film-Titel, das ist der Aufruf.
So, dann haben wir hier in dem Multiplates-Ticket-Service,
ja, da heißt die Methode, da hieß die Methode,
die Filme hier sich einfach umbenannt in Gip für den Titel.
Passt auch, haben wir ja gemacht. Dann gibt es hier den Test,
ja, da würde er das an dieser Stelle ändern.
Die Filme gibt für einen Titel an dieser Stelle auch.
Was wir hier sehen ist, was wir in unserem von
Handrefactoring gemacht haben, das würde er hier nicht vorschlagen.
Er wird jetzt hier nicht sagen, Teste gibt Filmtitel.
Kann den Clips auch nicht vorschlagen, weil der semantische,
der semantische Zusammenhang, der ist für ein Tool einfach nicht erschließbar.
Also auch hier oben, der Kommentar wird jetzt nicht mit vorgeschlagen.
So, gucken wir uns noch mal an, was er noch ändern würde.
Im Ticket Service hat er tatsächlich das gleich mitgeändert.
Also hat tatsächlich in dem Service Interface das auch umbenannt vom Gipfel in die Filmtitel.
Und das dürfte schon die letzte Änderung gewesen sein.
Und das ist jetzt, wenn wir ja wissen,
dass wir alles das gemacht haben, wissen wir, das ist okay.
Aber wir wissen jetzt auch, dass zum Beispiel in der Testklasse.
Unser tolles gibt Film. Jetzt nicht mehr so schön ist,
weil jetzt hier heißt die Operation Teste,
gibt Film und hier auch gefilmt.
Aber steht tatsächlich, gibt Filmtitel da. Die ersten Zeichen
des Verfalls. Das ist sozusagen ein Beispiel wieder ein Kommentar und Code auseinanderlaufen,
einfach weil man das nicht bedacht hat an der Stelle.
Also wenn man da jetzt nicht genau hingebracht hätte,
würde man es gar nicht merken.
Und so wird dann so nach und nach der Quelltext immer mehr verwahrt.
Das ist jetzt hier nicht so schlimm,
weil die Änderungen,
sagen wir,
sinnerhaltend ist
Ja, also das ist, was heißt denn erhalten?
Also diese, dass da ein falscher Kommentar steht,
das verfälscht nicht die Ausführung des Programms.
Das ist nur einfach unschön. Wenn wir mit diesem Unterricht fällt,
ist es grundsätzlich nicht, ist es die Beweise allein.
Sehr gute Frage. Er sagt, findet die Suche
nicht auch etwas, was in den Kommentaren steht.
Es gibt beim Refactoring tatsächlich die Möglichkeit, dass so ein Feld,
wo man das mal selektieren kann, berücksichtige auch Kommentare.
Und dann wird in einem bestimmten Maße werden auch Kommentare
mit angepasst
Aber da würde ich mich auch nicht darauf verlassen,
dass die jetzt wieder alle Stellen entdecken, die wir so relevant fände.
Was wir aber jetzt gesehen haben, ist,
er hat auch nicht diese Stelle geändert,
an der das andere Gipfel im Stand. Also ganz wichtig,
Eclipse kennt das Typsystem von Java und hat nicht einfach stumpf gesagt,
überall, wo dir Film steht, mache ich jetzt mal,
geb für einen Titel draus, sondern es hat erkannt,
naja, er soll diese Methode umbenannt werden.
Also wird auch nur die umbenannt, wo ein Springer als Ergebnistyp definiert ist.
Und nicht die, wo ein Film als Ergebnistyp definiert ist
. Ist also extrem hilfreich für diese Entwicklungsumgebung.
Also ihr könnt euch vorstellen, wie viel Cleverness
in diese Refactorings reingebaut ist
Da steckt richtig viel Aufwand dahinter, das in diese Idee reinzubauen,
auch mit einer Vorschau und allem drum und dran.
Okay. Also, wir haben jetzt mal ein Refactoring durchgenommen hier, haben uns die Mechanics angeguckt.
Ich würde noch gerne eins nochmal näher am Betrachten, nicht ganz so ausführlich, nämlich Methode extrahieren. Also,
wenn der Fauler sagt,
Kommentare sind eigentlich immer ein Zeichen von einem üblen Geruch,
also wenn man zum Beispiel schreiben muss,
was eine Methode tut, weil sie vielleicht zu viel tut,
muss ich einen Kommentar schreiben, dann sagt er,
ja, dann könnte es ja auch helfen,
einen Teil der Methode auszulagern und dann diese Methode entsprechend so zu benennen,
dass dann viel klarer wird, was denn die Methode tut.
Ja, also Methode extrahieren ist oft sinnvoll, wenn eine Methode
sehr groß ist. Okay, die Mechanics mal wieder,
deklariere eine neue Methode mit einem sprechenden Namen,
tut hoffentlich erstmal nicht weh, man muss es aber übersetzen,
ob der Name nicht irgendwie kollidiert.
Kopiere den zu extrahierenden Abschnitt in die neue Methode. Okay,
suche in der neuen Methode nach Referenzen auf lokale Variablen und
da muss man eben halt die ganzen Parameter damit rüberziehen und die lokalen Variablen,
die in dem Abschnitt benutzt werden,
da muss man übersetzen und testen und dann ersetzt man in
der alten Methode den extrahierten Quelletext mit dem Aufruf der neuen Methode
So, das gucken wir uns jetzt auch mal an einem konkreten Beispiel an.
Und zwar habe ich hier mal mir das Start-up genommen,
Start-up Multiplex-Kino, das ist das Start-up,
wo halt so am Anfang so ein paar Dinge erzeugt werden.
So ein paar Filme und ein paar Uhrzeiten und so weiter
seht ihr hier, also Uhrzeit und Vorstellungen werden hier erzeugt.
Man sieht dieses Start-up, ist eine statische Methode,
Static Void Maine. Da wird jetzt passiert jetzt einiges und
das geht schon über eine Bildschirmseite hinaus. Wir wissen,
Methoden länger als die Bildschirmseite sind eigentlich nicht schön,
weil man kann nicht auf einen Blick sehen,
was sie denn tut
Also, was können wir machen? Wir können tatsächlich sagen,
das hier, dieses, das sieht bei mir aus
wie ein ziemlich großer Chunk von Software.
Das würde ich jetzt gerne mal extrahieren.
Also einfach Auslage in eine eigene Methode. Aha,
Storesi, du wirst gleich hoffentlich trotzdem funktionieren.
Ich weiß nicht, was heute los ist.
Ich fliege ständig aus dem Netz raus. So,
ich kann also jetzt bei diesem selektierten Abschnitt sagen, Refactor, Extract Method.
Dann sage ich, Eclipse, mach mal diese Extraktion.
So, das ist jetzt schon ziemlich viel,
was Eclipse da für mich tut.
Ihr seht, da sind ganz schön viele Parameter,
die da übergeben werden müssen
Datum, Uhrzeit, Film und so weiter, alles Mögliche.
Und ich muss jetzt hier, wird gefragt,
wie soll die denn heißen? Also ich nenne jetzt mal
, erzeuge Vorstellungen. Da werden diese ganzen Vorstellungen erzeugt.
Und dann kann ich mir auch wieder ein Preview machen lassen,
mache ich jetzt mal, machen wir mal, machen wir mal.
Obwohl, man sieht da, glaube ich,
nicht so wahnsinnig viel, hey, machen wir einfach mal nicht,
gucken wir uns das mal an,
was er da jetzt draus gemacht hat.
Man sieht jetzt hier im Rumpf von Main,
der ist jetzt, der passt auf eine Bildschirmseite,
das ist der Rumpf von Main.
Und mittendrin steht jetzt hier dieses Array von Vorstellungen,
da wird jetzt was Erzeugevorstellungen geliefert hat,
wird dann sozusagen zugewiesen
Und dann hat man direkt da drunter die statische Methode,
erzeuge Vorstellung mit diesen ganzen Parametern, ein bisschen hässlich.
Und da steht dann dieses Zeug drin. Also wir haben
zwei kleine Methoden, die beide auf eine Bildschirmseite passen,
deutlich nettere Struktur. Aber was da an,
also wenn die das jetzt von Hand gemacht hättet,
das wäre ein fürchterlicher Aufwand gewesen,
erstmal die Mechanics zu befolgen und hier irgendwie diese ganze Parameterliste mit zu erzeugen und zu übergeben.
Also da sieht man dann schon, der Wert von diesen Toolunterstützungen,
um sowas zu extrahieren, ist relativ hoch.
Und das ist eine private Methode. Das heißt,
wenn wir nach dem Geheimnisprinzip arbeiten und sagen, naja,
da ist jetzt in der Rumpf der Methode ist ja sozusagen Teil der Implementation gegenüber dem Klienten.
Und das wird rausgezogen, natürlich in eine private Methode,
weil es auch Privatsache ist. Da ist eine Frage.
Die Tatsache, dass da ein Impuls jetzt aber, naja,
jeder hat das gehört, um alles, der ist immer allein schon.
Sehr gute Frage. Er sagt, inwieweit ich das jetzt einschätzen würde,
dass das, was jetzt hier passiert, nämlich,
dass eine Methode aufgerufen wird mit acht Parametern,
ob das ein Bad Smell ist.
Ist ein Bad Smell. Große Parametalisten sind immer ein Bad Smell. Da könnte man jetzt nicht überlegen,
ob man dann diese Dinge hier vielleicht zu,
also die Uhrzeit und zu Klassenvariablen macht,
die dann irgendwie in dem anderen Rumpf einfach zugreifbar sind und sie nicht explizit als Parameter übergibt, wie auch immer.
Also hier gibt es verschiedene Möglichkeiten, da ist vielleicht eine Anmerkung.
Ich sehe es zwar gar nicht voll schnell,
aber würde es an der Stelle nicht sogar funktionieren,
wenn man das erzeugt in der ganzen Uhrzeit, wirkliche Methode,
als solche Vorstellungen reinnehmen, 100, oder wenn man was woanders erlebt.
Das Vorstellungsarray, ja, naja,
also man könnte tatsächlich das, ja,
aber das ändert ja auch nichts
Ja, ja, also man könnte jetzt,
also das Erzeuge Vorstellung musste,
man muss hier gar nicht eine lokale Variable-Diktorin,
sondern könnte das, ja, also, na gut,
also es gibt da, aber das ist tatsächlich ein guter Hinweis.
Lange Parameterlisten sind auch bei Ads Mels und man könnte sich jetzt überlegen,
wie man da jetzt vielleicht wieder besser machen könnte.
Auch da gibt es entsprechend Refactoring-Hinweise bei dem Fowler.
Vielleicht kann man die ja anwenden. Gut. Soweit
, so gut. Der Fowler hat ja jetzt,
wie gesagt, einen Riesenkatalog beschrieben. Ich bin 60,
70 verschiedene Refactorings. Also sehr viele in der Kategorie Refactoring
, also ein Element
Ein Paketklasse-Methode variabler, was weiß ich, wird im Quertext umbenannt.
Dann sowas wie Move, also irgendetwas bewegen in einen anderen Kontext,
also eine Methode, zum Beispiel in eine andere Klasse schieben.
Change Signature, also tatsächlich Parameter rein hinzunehmen oder welche wegnehmen, solche Geschichten.
Bewege in der Hierarchie irgendwie eine Methode nach oben und nach unten schieben.
Extrahiere, das ist etwas, was relativ häufig vorkommt.
Also ich habe eine Klasse, die eine Schnittstelle hat,
die definiert es über ihre öffentlichen Methoden.
Und ich habe jetzt einen Klienten und möchte jetzt,
dass der nur über eine schmale Schnittstelle dieses Objekt benutzt, diese Klasse
Also sage ich, Extract Interface. Und dann kann man
tatsächlich sich die Sachen da auch mal rausziehen lassen.
Da ist eine Frage. Unterstützt ihr Kids auch,
das Unbenennen von ganzen Klassen oder Körperpaketen? Ja,
also ich lebe es, unterstützt auch das Umbenennen einer ganzen Klasse.
Ich könnte jetzt zum Beispiel hier diese Klasse umbenennen in etwas anderes.
Rename. Und dann schlägt er mir hier auch was vor.
Also auch das führt dazu, dass an allen Stellen,
an denen jetzt Variablen von diesem Typ deklariert werden,
das natürlich mit angepasst wird und so weiter
Unsagbar nützlich, dass das Werkzeug, dass das Eclipse das mit anbietet.
Weil man sonst wirklich gebremst wird darin, den Code lesbarer zu machen.
Wenn es für mich bedeutet, diese Methode ist schlecht benannt.
Ich weiß, der andere Name wäre besser,
aber ich scheue davor zurück, diese Umbenennung vorzunehmen,
weil ich war einfach, oh, ein tierischer Aufwand,
es muss der sämtliche Klienten durch und das überall ändern,
habe ich keine Lust zu.
Also lasse ich das so. Ich werde also sozusagen durch blöde Umstände,
weil es einfach umständlich ist, davon abgehalten,
etwas Gutes zu tun im Quelltext,
nämlich eine Methode besser zu benennen oder eine Klasse
Jetzt. Ich habe gerettet, den Samenrat. Und
er war so voller, hat es auch voll entdeckt.
Was hat Dinge, was fort extern 9 gemütlich befördert,
dann werden die einfroren. Und dann musst du was verleckern
und zeigen. Parallelen. Ja, er sagt,
was ist denn, wenn man jetzt etwas baut,
was von externen Klienten benutzt wird?
Also wenn man etwas an der Schnittstelle nach außen in die Außenwelt sozusagen ändert.
Ich würde sagen, das ist dann kein Refactoring mehr.
Das ist dann sozusagen aus Sicht,
von außen ist es dann eben halt
keine Verhaltenserhaltende Änderung
Sondern da wird tatsächlich was an der Schnittstelle geändert. Was,
das ist was, was API-Designer natürlich beachten müssen,
dass die irgendwie vielleicht was falsch benannt haben,
was dann üblicherweise passiert in Java,
was ihr auch schon gesehen habt, ist,
die Methode wird als depricated gekennzeichnet, bleibt bestehen.
Es gibt eine neue Methode, die man eigentlich aufrufen soll.
Und dann irgendwann wird die Methode in der übernächsten Version dann rausgeschmissen.
Ja, genau. Man kann sich das auch noch freuen,
dass es natürlich passiert wird,
dass es sechs passiert oder was man da macht
Also beobachtbares Verhalten liegt natürlich im Auge des Betrachters.
Also wenn ich an dieser Klasse jetzt irgendwas ändere,
dann kann man sagen, da ändert sich das Verhalten.
Weiß ich nicht. Also Refactoring sagt schon relativ deutlich,
dass jemand, der die Software benutzt,
das nicht mitbekommt, dass sich da was geändert hat.
Und wenn ich jetzt eine API habe und da etwas,
was jemand anders benutzt, ändere, dann habe ich quasi,
dann ist sozusagen, das eine ist der interaktive Benutzer,
aber er gehört auch nicht zum System.
Oder ich habe eben halt ein anderes Softwarestück,
dass irgendwie meine Schnittstelle benutzt.
Das ist das Gleiche. Also es ist sozusagen nach außen
beobachtbar. Und deswegen ist es eben halt
kein Refactoring
Aber wie gesagt, um die Frage dann doch zu beantworten,
das macht man eben halt dann üblicherweise mit mit dem Mechanismus von Depricated in Java zumindest.
Okay. Refactoring. Ach ja, hier noch so eine kleine Geschichte.
Es gibt auch Refactorings zum Thema Werte und Objekte.
Change Value to Reference, Change Reference to Value.
Und hier dieses Change Value to Reference, das ist ganz interessant,
weil ich habe ja in der letzten Vorlesung was erzählt über Werttypen,
ein relativ, sagen wir,
ungewöhnliches Konzept,
wird man auch in vielen Lehrbüchern
nicht finden
Aber was irgendwie dann auch wieder ein Hinweis ist,
dass das eben halt nicht nur, sagen wir,
unsere wilde Idee ist, sondern schon eine gewisse Relevanz hat.
Der Fouler beschreibt es auch, you can make a useful
classification of objects in many systems, reference objects and value Objects.
Er macht das ein bisschen, er nennt die jetzt unbedingt
Reference Objects, okay. Reference Object fehlt das S,
are thing is like customer all account, customer,
meine Güte, das ist nämlich schlecht kopiert oder schlecht abgeschrieben.
Each Objects stands for one Object in the real world and you
use the object and in to test where that they are equal.
Also das ist so das, was wir in unserer Materialien
verstehen, so veränderbare Objekte,
überhaupt all meine Objekte
Und Value Objects are things like date or money, aha,
oh, kennen wir ja. Naja, die Find and
Tiley's through their data Values, you don't mind that copys exist.
You may have hundreds of erster erster erster 2000 Objects around your system.
You do need to tell what are two of their equal.
So you need to overright the equals method and the hash
cold method 2. Also, das ist dann diese Idee,
wenn ihr sowas baut, solche leichtgewichtigen Dinger,
dann werden die eigentlich mit Equals verglichen und nicht mit Referenzgleichheit.
The decision between reference and value is not always clear. Das ist tatsächlich so,
wenn man so Entwurfsentscheidungen kommt, wo man dann sagt,
es ist jetzt ein Wert, es ist ein Objekt,
Wir haben versucht, hier euch ein bisschen konkretere Hinweise zu geben,
wann etwas ein Wert und wann ein Objekt ist.
Er sagt, das ist nicht so klar,
aber er hat sich damit auch nicht so intensiv beschäftigt.
Gut. Das nur noch mal so als Ergänzung.
Dann die Werkzeugunterstützung, die habe ich schon beschrieben.
Ich habe schon erwähnt, dass es aufgrund dieser starken Mechanisierung,
also weil eben halt der Foul oder das so schön detailliert beschrieben hat,
war es sehr volllockend, die Dinge dann auch nachzubauen.
Und das haben die Leute dann auch gemacht,
also in Eclipse oder in IntelliJ Idea oder in Net Beans
sind solche Refactorys
ja verbaut
Die werden auch kontinuierlich weiterentwickelt. Das heißt,
man konnte so richtig so sehen, wie über die Jahre
in den Entwicklungsumgebungen, immer mehr von diesen Refactorings angeboten wurden.
Es war am Anfang so, dass Eclipse so die ersten waren,
die das wirklich angeboten haben. Man sieht hier also,
wenn man jetzt nochmal so guckt, Refactor,
da gibt es schon so einige Extract-Interface, Use Supertime,
Pull-Up und was weiß ich was.
Das ist ganz schön, aber man muss auch wirklich gucken,
wie hoch ist der Aufwand,
die zu implementieren und wie sehr lohnt sich das
Der Mitarbeiter von einer der Mitarbeiter von Erich Germann,
Dirk Bäumer, der hat mal bei Heinz Zülichhofen mal promoviert,
also den haben wir einen ganz guten Kontakt,
der war bei uns mal im Oberseminar und hat dann erzählt,
wie viel Arbeit das ist,
so ein Refactoring in die Clips reinzubauen.
Und er sagt, die machen auch Messungen und kriegen halt
auch unter anderem mitgeteilt, wie oft diese Refactorings benutzt werden.
Und das mit Abstand am meisten benutzte Refactoring ist Renay Method.
Das wird wahnsinnig viel benutzt. Das heißt, jede Entwicklertag,
den die da investieren bei OTI damals, zahlt sich millionenfach aus,
weil irgendwie tausende von oder Millionen von Benutzern das einfach benutzen können.
Das heißt, da lohnt sich das. Andere Sachen,
da muss man wirklich extrem aufwendige Sachen tun,
um ein sehr seltenes Refactoring zu unterstützen.
Also das trägt nicht beliebig weit. Also diese Refactorings sind da nicht
so häufig genutzt. Es gibt also eine ziemliche Spannbreite,
wie oft bestimmte Refactorings benutzt werden. Renay Messed Extract Interface,
alles total häufig, aber dann gibt es eine ganze Menge,
die werden sehr, sehr selten benutzt.
Und sie sind auch sehr oft sehr spezifisch für einen
bestimmten Kontext.
Also nicht so generalisierbar
Und nicht so automatisierbar. Das ist das eine,
also dass man irgendwie auf sich klar ist, diese Refactorings,
die tragen, bis zu einem bestimmten Punkt ganz gut,
aber dann wird es relativ schnell esoterisch.
Die paar Dinger, die man da jetzt in den Clips hat,
die will man unbedingt haben, weil die einfach wirklich nüsslich sind.
Ein anderer Aspekt, der einem auch klar sein muss. Ich habe jetzt gerade gezeigt,
dass die IDE das Typsystem von Java kennt, also Eclipse, Past,
das gesamte Java-System, was es so unter Kontrolle hat,
hat also so ein Upstract-Syntext-Tree, also so ein Syntax-Baum von dem,
was da gerade vorliegt und kann eben halt dann auch sehr schnell Dinge ableiten,
die man aus dem flachen Quelltext nicht so sofort erkennen würde.
Also dieses Gip-Film-Titel haben wir ja gerade gesehen. Ist so
ein Beispiel. Und das funktioniert in Java besonders gut,
weil Java so ein wunderbares, klares Typsystem hat.
Auch das war eine Auskunft, die wir von dem
Dirk Bäumer bekommen haben. Es ist viel leichter,
eine Refactoring-Unterstützung für Java zu bauen in den Clips,
als zum Beispiel für CPlus.
Es gibt ja auch eine CPlus-Ausprägung von Eclipse.
Die Sprache ist leider sehr, sehr komplex und hat sehr viele Sonderfälle.
Und da ist es ungleich schwerer,
ein Rename-Method oder Function reinzubauen
Das ist also auch etwas, was man sich klarmachen muss,
dass eine typisierte Sprache extrem viele Vorteile bietet für Refactorings.
Das ist für mich immer so ein Argument,
wo dann die Leute immer sagen, ja,
warum man überhaupt eine typisierte Sprache, warum denn Java,
warum die Ruby oder warum nicht,
Python ist doch alles viel einfacher,
da muss man nicht ständig so die Typen von Variablen deklarieren.
Schön, schön, schön. Aber wenn ihr dann so
ein System gebaut habt in einer nicht getypten Sprache und wollt dann ein Refactoring machen.
Viel Spaß. Da weiß der Compiler nicht mehr genau,
an welchen Stellen er was ändern darf und an welchen
Stellen nicht
Also es ist schon ganz schlau. Typisierung in einer Programmiersprache zu haben.
Unter anderem, damit man eben halt Refactoring-Automatisch unterstützen kann.
Dann beschreibt der Forderer auch nochmal, wie man vorgehen sollte beim Refactoring.
Und er macht eben halt hier einen entscheidenden Punkt.
Er sagt, wenn man in ein bestimmtes Feature in
ein System einbauen will, also eine neue Funktionalität.
Und die Software ist nicht in dem Zustand, dass das
gut reinbaumbar ist. Habe ich eben schon so angedeutet.
Es kann ja so Situationen geben, wo man sagt,
wenn wir das jetzt reinbauen, dann wird es richtig hässlich.
Dann sagt er, sollte man zuerst das System refacten,
damit dann die Änderungen leichter wird
Also eine Refactoring machen das vollständig verhaltenserhaltend ist. Und dann
sollte man anschließend das Feature einbauen, als einen getrennten Schritt.
Und bevor you start refactoring checkt, hat die Helpe Solid
Suite of Tests, he's test must be surf checking.
Also diese Idee von automatisierten Tests,
die ja für euch nicht unbekannt ist,
aber die zu der Zeit, als er das geschrieben hat,
noch nicht so selbstverständlich waren im Jahre
2000. Das heißt, wenn wir refactoren,
besteht immer die Gefahr, dass wir neue Fehler in
den Quelltext einbauen
Deswegen sollte man sehr,
sehr gut mit Testklassen abgedeckt sein und ohne ausreichende Testabdeckung
ist man es eigentlich so ein bisschen so wie Autofahren oder Sicherheitsgurt.
Also keine besonders komfortables Gefühl. Okay, das ist auch schon das,
was ich heute erzählen wollte. Also nochmal zusammengefasst,
Software wird fortlaufend verändert und es entstehen dann leicht üble Gerüche.
Refactoring ist eine Restrukturierung von Software, die deren Funktionalität erhält.
Es gibt dann eine ganze Reihe von etablierten Refactorings,
die können auch in ihrer Mechanik beschrieben werden. Das gehört zum Handwerkszeug,
der Softwareentwicklung, solltet ihr beherrschen, solltet ihr kennen,
solltet ihr euch mit Wohlfühlen und eine gute Entwicklungsumgebung kann für gute Programmiersprachen,
bei vielen Refactorings automatisierte Unterstützung anbieten.
So, jetzt fällt mir noch ein,
ich habe ja hier auch noch Sturesi,
mal sind aber die Sturesi jetzt hier irgendwie zum Laufen kriege.
Machen wir mal eine kleine kleines Quiz wieder. So,
ich starte da schon mal, dann könnt ihr euch
schon mal die Frage in Ruhe an durchlesen.
Durch welche Maßnahmen wird beim Refactoring das Fehlerrisiko am ehesten gering gehalten?
A, durch das Vermeiden über Gerüche,
B durch eine möglichst hohe Testabdeckung,
C durch das Einhalten von Quelltextkonventionen,
D durch das Einhalten gängiger Entwurfsregeln
Okay, wir nähern uns der 40 Personen,
der 40 Stimmengrenze. Es sind doch mehr als 40
Leute hier
Aber nicht alle geben ihre Stimme ab. Okay, ich denke mal,
das reicht jetzt so. Wir gucken uns die Verteilung an.
75 Prozent durch eine möglichst hohe Testerdeckung. Das ist auch das,
was ich mir erhofft habe, dass das euch klar ist,
dass das das Entscheidende ist, weil beim Refactoring,
also ich, weil ich bestimmte Dinge nicht getan habe,
also keine üblen Gerüche vermieden habe, die Kalttech-Kommentare,
komme ich in die Situation,
dass ich dann refactoren muss.
Aber wenn ich Refactory, dann will ich natürlich möglichst,
dass das viele Risiko geringer hat, indem ich eine hohe Testerdeckung habe.
Das ist also jetzt auch eine einfache Frage gewesen,
an die nicht ganz so einfache Frage ist,
diese hier
Warum sollten Refectoring und Erweiterungen klar getrennt werden? Weil dann
die Semantik bestehender Tests beim Refactoring nicht verändert werden muss oder um
dem Kunden die Erweiterung besser in Rechnung stellen zu können oder C,
weil Veränderungen an bestehende Quelltags schon schwierig genug sind oder D,
weil wir Korrision auch auf unser Vorgehen anwenden sollten.
So, jetzt wollen wir mal sehen,
was ihr euch teilt und dazu überlegt.
Maltible Choice ist nämlich auch manchmal
ganz schön schwierig
. Okay, 38 Stimmen, wir sind wohl nicht da.
Wir gucken mal auf die Verteilung.
Ich würde jetzt mal wetten, dass das nicht ganz so
klar ist
Ja. Ja, also das ist tatsächlich sehr schön,
irgendwie so, ein Drittel hat sich für zwei Antworten entschieden,
ein weiteres Drittel für eine dritte und ein weiteres Drittel für die vierte.
Es gibt keine richtige Antwort an dieser Stelle. Ja,
ich wollte eigentlich nur, dass ihr euch da mal Gedanken darüber macht,
warum das überhaupt irgendwie sinnvoll sein kann. Es hat alles so seine,
naja, also um dem Kunden die Erweiterung besser in Rechnung stellen zu können,
klar, wenn ich das klar trennen kann,
also auch tatsächlich bei der Softwareentwicklung weiß,
jetzt habe ich nur Refactor und jetzt habe ich wirklich zwei Mann-Tage in die Erweiterung gesteckt,
habe ich möglicherweise klarer, was ich in Rechnung stellen kann,
habe aber auch das Problem, dass ich das Refactoring irgendwie auch abrechnen muss.
Das kann man dem Kunden oft nicht verkaufen. Weil dann
die Semantik bestehender Tests beim Refactor noch nicht verändert werden muss,
ja, wenn ich eine Erweiterung baue, muss ich auch die Tests anpassen.
Es wäre gut, wenn man das erst mal macht,
ohne die Tests anzupassen. Also vielleicht nur das, was
beim Refactoring notwendig ist. Hat also durchaus auch seinen Wert.
Kurision auch auf das Vorgehen anwenden, ja klar,
also wenn ich schon die Dinge verschieden benennen kann,
also ich mache jetzt ein Refactoring und es ist auch eine Erweiterung,
die ich das trennen kann, sollte ich es auch getrennt tun.
Das ist vor allen Dingen sinnvoll,
wenn man mit einem Quelltext Reportitory arbeitet,
mit mehreren Personen,
dass man das auch dann später rekonstruieren kann,
was ist denn da überhaupt passiert
Und weil Veränderungen an Bestehenden können schon schwierig genug sind.
Deswegen sollte man das auch ein bisschen trennen. Ist auch
so ein Argument, ja, kann man gelten lassen.
So, das war nur so ein bisschen zur Diskussion.
Wenn es keine Fragen gibt, dann sind wir fertig
für heute.
Vielen Dank