Wir kommen zum Abschnitt 4-3 Refactoring. Dabei geht es darum,
wie kann tatsächlich die Struktur des Codes verändert werden?
Dabei haben wir hier zwei Fragen, nämlich die Frage 5.
Was sind Betsmelz? Nein, drei Fragen sind es.
Sechs. Wie ist es das mit dem Fehlerrisiko aus?
Und sieben, wo es um Clones geht,
das ist tatsächlich eine von den Refactoring-Maßnahmen.
Lassen Sie uns damit starten, was Refactoring überhaupt ist
Dazu schließen wir an das ein, wo wir gerade waren.
Und wir brauchen hier eine neue Seite.
Und zwar beginne ich damit, weiß Refactoring überhaupt ist.
Nach der Definition von Martin Fauler.
Martin Fauler definiert das so.
Made to the internal structure. Offene Software, to make
it easier to einer stand. Encheaper to motify with out changing,
it's absolutely behania, Baby. Das war, ich hole 1999,
also schon eine ganze Reihe von Jahren weg, das ist die Definition.
Und wenn man es diese Definition anschauen,
so sind die wesentlichen Punkte, dass wir die interne Struktur ändern,
ohne das äußere Verhalten zu verändern.
Das ist das Wesentliche. Also wir bauen keine neuen Features ein.
Wir optimieren nicht den Ablauf. Wir beheben keine funktionalen Fehler.
Das ist auch ganz wesentlich. Es geht nicht um funktionale Fehler,
sondern die Ziele mache ich jetzt hier mal mit grün.
Ja, to make it easier to understand and cheaper to modify.
Das sind die Ziele. Wir wollen die Verständlichkeit erhöhen,
die Wartbarkeit erhöhen und dabei das Verhalten nicht verändern.
Dass sie steht. Sie steht damit einher mit dem,
was wir in Kapitel 1 über Ingineering gesagt haben.
Das reine Reengineering beschäftigt sich nicht mit der Veränderung des funktionalen Verhaltens
Wir setzen das dadurch um, dass wir so
eine Zwei-Hüte-Metapher haben. Also zwei Hüte im Sinne von,
ich als Entwickler bin manchmal der Reengineering macht und manchmal der,
der Veränderungen funktioneller Art vornimmt.
Zum Beispiel das, was der Kunde wirklich will,
eine Umumbau, eine Veränderung oder sowas.
Die vorgehendes Vorgehen, was wir da ganz zu Anfang besprochen hatten,
ist der Vorschlag,
eine klare Trennung zu haben
Auch wenn das häufig wechselt. Und zwar haben wir einerseits...
Ich mache das mal ganz klar mit erstens und zweiten Indrich ja nochmal.
Erstens, Refactoring ohne Änderung des Verhaltens.
Das ist das, was die Definition sagt.
Ich lasse eine Zeile frei,
da kommt noch was dazwischen
Und das zweite, dass man Erweiterungen, das existierenden Codes vornimmt.
Das ist das, was noch häufig der Auftraggeber sehen will.
Und es ist typischerweise ganz schwierig, in realen Projekten
dem Auftraggeber zu vermitteln, dass wir ein Re-Engineering durchführen.
Wir investieren Zeit, wir arbeiten da drei Monate dran.
Das ist ganz anstrengend und ganz schwierig und ganz risikoreich,
aber wir ändern nichts.
Wozu macht ihr das,
wenn ihr nichts ändert
Weil die Ursache ist, dass für den Auftraggeber häufig das
Konzept Softwarequalität und so auf das Konzept Wartbarkeit und Wartungsaufwand nicht verständlich ist.
Er merkt, dass maximal daran, dass sie dem Entwickler
ihm sagen, sorry, geht nicht mehr.
Ja, wir kriegen das Programm nicht stabil.
Es geht nicht, diese Änderung geht nicht durchzuführen.
Dann ist es aber zu spät. Dann sind wir in
dem Stage-Model schon ganz weit unten und dann können wir es
eigentlich nur noch abschalten.
Wir müssen versuchen, vorher einzugreifen. Deswegen kommt es uns
darauf an, diese Dinge hier zu kombinieren
Wir kriegen es nicht hin, dass wir nur Regineering durchführen.
Das ist meistens dem Auftraggeber nicht zu vermitteln,
sondern wir versuchen, das durch Kombination weiter Sachen zu machen.
Warum in dieser Reihenfolge? Weil wir die vorhandenen Testfälle weiterhin gültig haben,
wenn wir das, solange wir das Verhalten nicht verändern.
Das gibt uns bei den Veränderungen Sicherheit.
Sie müssen wissen, dass Entwickler sehr stark risikobewusst arbeiten.
Keiner arbeitet dort leichtfertig bei einem existierenden,
bei einem Legacy-System für einen hohen Geschäftswert
Da werden alle sehr vorsichtig sein, diesen Spruch,
never touch a running system hätte ich schon mehrfach erwähnt.
Alle werden sehr vorsichtig handeln. Und dieses sehr vorsichtige Handeln bedeutet sich darum,
dass sie nur die minimalen, nötig, nötigen Änderungen machen.
Und Refectoring wird dazu nicht gehören. Man macht nicht mal
strukturierte Tabelle um, weil sie dann besser effektiver ist.
Man teilt eine Klasse auf, weil sie dann besser
die fachlichen Zuordnungen entspricht. Das würde man nicht tun,
weil das Risiko zu hoch ist. Und das ist aber
genau das, was ich Verständlichkeit und Wartbarkeit dann beeinträchtigt,
weil die Klassen immer größer werden.
Es ist unübersichtlich, welche Klasse tut denn was und so weiter.
Wir wollen Refectoring durchführen und das geht nur dann gut,
wenn wir
durch Testfälle abgesichert sind
Und das ist hier der Punkt, die Testfälle bleiben gültig,
wenn wir, solange wir nur das Refactoring durchführen, ohne Verhaltensänderung.
Deswegen unbedingt diese Trennung. Testfälle bleiben hültig, keine neuen Tests erforderlich. So,
dann sollten wir durchaus das machen, was der Auftraggeber von uns wollen,
wofür sie uns wirklich bezahlen wollen, nämlich das machen,
was sie an neuen Features,
an Optimierung von Abläufen oder so etwas brauchen.
Dann müssen wir allerdings auch Die Testfälle erweitern und anpassen.
Und wir machen es genau in dieser Reihenfolge,
weil wir die Basis schaffen durch führt die Veränderungen,
indem wir durch Reflektoren die Wartbarkeit verbessern.
Also Reflektoring verbessert die Wartbarkeit, das stand hier oben in der Definition,
easy jetzt woanders, denn Cheaper to Multify,
wir schauen uns gleich an, wieso, wie das passiert.
Und danach erst machen wir, ändern wir die Funktionalität,
das, was der Auftraggeber wirklich möchte.
Und das gibt uns auch ein bisschen,
gibt ihnen jetzt auch ein bisschen die Information darüber,
wo mache ich das denn
Tatsächlich werde ich das dort machen, wo ich gerade Funktionalität ändern muss.
Das werde ich mir vorher angucken, weil wir sagen,
okay, da mache ich mal vorher das und das Refactoring.
Ich schneide die Klasse mal vorher neu und dann ist es viel leichter,
nur ein Teil der Klasse zu ändern, weil der Auftraggeber das und das möchte.
Statt einfach mal irgendwo das und das zu tun,
das macht man eher selten. Hier ist sozusagen der Anlass,
ist das, was wir unter zweitens haben und das,
was wir als Vorbereitung tun, ist das,
was wirklich Wert schafft im Sinne von Verbesserung der Erwartbarkeit.
Wichtiger Punkt hier, beide Tätigkeiten klar getrennt, Zur Verminderung,
das ist immer ein bisschen besser, zur Verminderung des Risikos.
Wir haben immer wieder Kollegen, die der Meinung sind,
ach, ich checke die Klasse aus,
ich mache das noch mit einmal, hier, Endrich weiß,
da schiebe ich die Methode ein bisschen nebenher,
da habe ich das gleich optimiert und das ist
ein bisschen klarer gegliedert und dann mache ich die Funktionalität.
Ganz falsch
Man sollte erst die Veränderung vornehmen zum Richtrukturierung und die Testfälle bleiben gültig.
Das wäre das, was Punkt eins ist.
Wir können das durch Tests absichern. Und danach machen wir erst
die Veränderung der Funktionalität, wo wir neue Tests brauchen.
Dieses Absichern zur Verminderung des Risikos sollten wir machen.
Der Schritt macht sich allemal bezahlt, statt dann die Welt
überall fehler zu suchen, fehler zu lokalisieren.
Vor allen Dingen ist ja das Schwierige, um sie dann zu beheben.
Lassen Sie uns weiter zu weiteren Zielen sprechen. Ziele des,
wir brauchen eine neue Seite, Wir haben ja schon in
der Definition gesehen, dass es da zwei Ziele gibt.
Generell verbessern, steigernde Wartbarkeit.
Aber Wartbarkeit ist ein großer Begriff
Als Entwurf soll das heißen, Verbesserung der Qualität des Entwurfs,
und zwar ein Wurf auf Kohlebene,
ist das vor allen Dingen, wenn wir von Reflektoren sprechen,
sprechen wir immer eigentlich nur für Maßnahmen, auf Code-Ebene.
Und da meinen wir sowas wie klarere Struktur. Ist aber Modularisierung,
was man natürlich irgendwie unter Struktur zusammenfassen kann,
wo du Realisierung Bessere Entkopplung, könnte man auch wieder sagen,
ist der Struktur.
Und solche Sachen wie Duplikate entfernen.
Hier können wir noch hinzuspielen,
Abhängigkeiten reduzieren
Und Duplikate entfernen, wäre noch ein wichtiger Punkt.
Und da wäre ich das zweite Punkt, war das Verbessern der Verständlichkeit.
Auch das war eine Definition genannt. Und das Verständlichkeit ist
ein Teil von Wartbarkeit. Bei Verständlichkeit müssen wir vor allen Dingen,
und das muss man manchmal tatsächlich gestandenen Programmierern nochmal sagen,
es geht nicht darum, dass da Compiler das versteht und dass es funktioniert.
Das kriegen wir ganz leicht hin. Sondern es geht darum,
dass der Kollege das versteht oder wir selber nach fünf Jahren
Deswegen die Konzepte, klar, die Bezeichnungen, klar,
die Strukturen, dem fachlichen Strukturen entsprechend.
Ich schreibe es trotzdem nochmal hin. Obwohl das eigentlich selbstverständlich ist,
der Compiler versteht alles, was syntaktisch korrekt ist.
Und wenn es auch noch zu passt,
dann wird das Brot ein ausführbares Programm geben.
Aber wichtig ist, der Entwickler muss es verstehen
Und das können wir dadurch tun,
dass wir Konzepte klarer abbilden, klarere Abbildung von den Konzepten.
Vor allen Dingen dadurch, dass wir es besser gliedern.
Dann natürlich vereinfachen, zusammenfassen
Und dadurch die Menge der notwendigen Details, die man im Kopf behalten muss.
Sie könnten geneigt sein, dass man so sagt,
ja, ich möchte die Komplexität verringern.
Das geht noch sehr begrenzt. Komplexität, die im Problem
hinter wohnt, die können sie nicht wegmachen.
Dann wäre das Programm
zu einfach
Aber was man machen kann, ist zusätzliche Komplexität,
die dadurch kommt,
dass ich ganz viele verschiedene Tools und Plattformen habe,
dass ich die Steuerflüsse, das ist völlig unstrukturiert oder komplett durcheinander.
Oder ich habe dann noch das geschachtelt, geschachtelt, geschachtelt oder tiefer vererbt.
Solche Komplexität, die können wir tatsächlich entfernen, vereinfachen,
zusammenfassen. Und was wir damit erreichen wollen,
ist, dass man Fehler leichter findet
Und am Ende auch die Effizienz erreicht. Das heißt,
das Aufwand Nutzenverhältnis der Softwareentwicklung, insbesondere der Erwartung. Soweit dazu,
man wird dieses Reflectoring, wir hatten eben schon davon gesprochen,
dass man das immer dann macht,
Und wenn man eine Erweiterung der Funktionalität gibt,
es gibt noch weitere Anlässe,
die möchte ich gern auch noch mit aufschreiben.
Und der Stift. Das zunächst erstmal Erweiterungen.
Das ist das, was wir eben schon hatten
Die sind einfacher möglich, wenn wir ein Refactoring durchgeführt haben.
In gleicher Weise können wir das auch machen im Zusammenhang mit Fehlerbehebungen.
Zum Beispiel, Sie haben ein Sicherheitsproblem gefunden, Sie beheben das,
indem Sie da die Strukturen verändern und dann ist das auch
einfacher möglich.
Ich schreibe es einfach nochmal eben
Manchmal resultieren solche Fehler tatsächlich aus Missverständen Sachen. Und dann,
wenn man sieht, oh, das hat man so und
so falsch verstanden, dann ist es natürlich umso besser,
insbesondere wenn mangelnde Verständlichkeit eine Fehlerursache ist.
So, dann wollen wir noch,
was wir auch noch weitere sind,
wenn wir Fehler suchen,
könnten wir
es auch
vorbeugend machen
Wenn wir Fehler suchen. Und natürlich generell,
wenn wir Überarbeitungen vornehmen, zum Beispiel auch für andere Ziele,
ist nur das Refactoring zur Fehlervorhebung.
Manchmal machen wir auch Performance-Optimierung, Hardwareentkopplung bei weiteren Änderungen
können wir das einfach noch sehen.
Und ich möchte noch annehmen, noch sagen,
zur Erhöhung der Effizienz der Softwareentwicklung
Eine der Metriken für Wortbarkeit in einer Firma,
mit der ich zu tun hatte, bestand mal darin,
dass man gesagt hat, okay, wir haben,
wir sind in diesem Geschäft, wo immer die Änderungen,
zum Beispiel da Steuer- und Sozialgesetze für das nächste Jahr,
von Mitte November bis Mitte Dezember schnell eingebaut werden müssen,
wie schnell schaffen wir das denn das?
Und man hat beobachtet,
dass über die Jahre die Dauer zum Einbauen dieser neuen Features,
die erforderlich waren oder gesetzlichen Änderungen der Änderungen von Geschäftsregeln, immer länger dauerte.
Man hat daraus eine Tendenz abgeleitet und hat gesagt,
okay, das noch weitere, drei Jahre so weitergeht,
schaffen wir es nicht mehr, bis zum 31.12. die Software auszuliefern.
Und dann werden unsere Kunden unzufrieden. Wir müssen also jetzt etwas tun,
man hat analysiert, wo diese Verringerung,
diese Probleme mit der Effizienz der Softwareentwicklung,
also Geschwindigkeit durch Zeit als Ausdruck von Aufwand und Zeitverhältnis,
wo ist dann das am geringsten?
Und man hat diese schlechten Stellen sozusagen vorbeugend behoben während des nächsten Jahres,
damit man im nächsten Jahr tatsächlich dann ein bisschen Bild besser war.
Und das war etwas, was auch die Geschäftsführung tatsächlich verstanden hat.
Man hat das durch Metriken blaue gemacht, ihnen deutlich gemacht,
dass es es geschafft hat, durch diese Investitionen in Re-Engineering,
die Bearbeitungszeit, die durchschnittliche Durchlaufzeit folgen solchen Änderungen im November,
Dezembergeschäft dann deutlich zu verbessern.
Ein weiterer Anlass für solche Refactorings sind Code-Inspektionen, Code-Reviews.
Manchmal macht man diese Code-Reviews natürlich am Bestand,
aber meistens macht man sie an Problemstellen,
wenn wir irgendwas geändert haben, wenn Mängel bezüglich Verständlichkeit entdeckt worden sind.
So, ich möchte durchaus auch noch nicht verschweigen,
dass es Problemfälle gibt. Und zwar,
im Business möchte ich in zwei große Klassen von Problemen nennen
Wenn Datenstrukturen betroffen sind,
dann brauchen wir sowas oder Datenbanken sogar zu verändern sind.
Abhängigkeiten zu anderen Programmen und dass wir die Datenmigration brauchen.
Sie merken schon am Platz,
ich will hier noch
was weiteres unterbringen
Das ist das, was wir im nächsten Kapitel hatten.
Also wenn wir solche Restrukturierung brauchen, dann ist das tatsächlich nochmal,
wir hatten ja hier dieses nette Bildchen vom vorgehenden Abschnitt.
Ja, was also sagt, ja,
wenn wir hier eine Umstrukturierung brauchen,
zum Beispiel zu sowas, das ist,
eigentlich wollen wir nur die Software hier im Programm 2 umstrukturieren,
aber das Erfordern hat dann eine ganze Reihe weiterer Auswirkungen.
Das ist der eine Punkt und der zweite Punkt ist,
dass man es natürlich bewusst sein müssen,
immer wenn wir Interfaces ändern
Immer wenn wir Interfaces ändern, hat das Auswirkungen auf alle Beteiligten.
Man wird deswegen immer Wege gehen,
dass man die Arbeit mit dem alten Interface noch weiter ermöglicht,
dass es Adapter gibt oder wie irgendwie etwas anderes,
dass man das alte Interface erstmal erhalten würde
Lass das hier noch hin. Ja, das passt noch hin,
aber es ist nicht lesbar, das probieren wir nochmal.
Ja, halte und solche Sachen.
Soweit dazu und manchmal ist es eben tatsächlich besser,
etwas neu zu schreiben, wenn die Todqualität zu schlecht ist.
So viel zu dieser Frage und wir müssen nochmal zu
der Frage vorgehen,
uns die Fragen nochmal anschauen
Wir haben jetzt eigentlich noch nicht über diese beiden Fragen fünf und sechs gesprochen.
Welche Rolle Ben Smells spielen und wie das Fehlerrisiko,
durch welche Maßnahmen das tatsächlich verringert werden soll.
Zu Bad Smells gehen wir mal, wir bauen dazu
eine neue Seite. Zu Bad Smells hatten wir eigentlich
vorher schon etwas gesagt im Abschnitt Analyse
auf Kot-Ebene
Wir hatten da gesagt, dass es Bett Merz,
vielleicht schauen Sie da einfach nochmal nach im letzten Abschnitt von vier,
von Kapitel 3,
dass Bett Smells die Intuition viel besser und viel besser sind als Intuition,
weil sie einen Katalog enthalten.
Von typisch Katalog, von typischen Mängeln und diese typischen Menge
können zusammen mit häufig gemeinsam mit Behebungsvorschlägen.
Und das sind dann die Refectorings.
Und das machen wir weiter im fortgesetzten Abschnitt