SlideShare ist ein Scribd-Unternehmen logo
Quelle: Ron Jeffries http://xprogramming.com/articles/refactoring-not-on-the-backlog
Entwicklung
Weiter-
entwicklung
Weiter-
entwicklung
Weiter-
entwicklung
Stabilisierung
Optimierung
Sanierung
Stabilisierung
Stabilisierung
Optimierung
t in Jahren
Quelle: Software Evolution, Tom Mens, Serge Demeyer
Initial
Development Phase Out Close DownEvolution
changes patches
Servicing
Big Bang
„Partialy New“
Maintenance
• Das Softwaresystem wird (nahezu)
komplett neu entwickelt.
• Das Altsystem muss während
dessen noch betreut werden.
• Es werden Teile neu entwickelt
oder hinzugefügt.
• Fokussierung auf Bugfixes und
Stabilisierung.
1. It is hard to change because every change affects too many other parts
of the system. (Rigidity - Starr)
2. When you make a change, unexpected parts of the system break.
(Fragility - Zerbrechlich)
3. It is hard to reuse in another application because it cannot be
disentangled from the current application. (Immobility - Unbeweglich)
Quelle: http://www.objectmentor.com/resources/articles/dip.pdf
Quelle: Martin Fowler http://martinfowler.com/bliki/TechnicalDebtQuadrant.html
Ward Cunningham
rücksichtslos umsichtig
überlegt
versehentlich
„Wir haben keine
Zeit für ein
Design.“
„Wir müssen jetzt
liefern und uns später
um die Konsequenzen
kümmern.“
„Jetzt wissen wir wie
wir es hätten machen
müssen.“
„Layer? Was ist
das?“
Quelle: http://martinfowler.com/bliki/BeckDesignRules.html
Legacy Software
System
Improved
restructured
model
New Software
System
High-level
architectural
model
analyse
Improve,
restructure,
extend
understand,
extract,
abstract
generate,
refine
ReverseEngineering
ForwardEngineering
Restructuring
Refactoring bezeichnet in der Software-Entwicklung die manuelle oder
automatisierte Strukturverbesserung von Quelltexten unter Beibehaltung des
beobachtbaren Programmverhaltens.
Dabei sollen die Lesbarkeit, Verständlichkeit, Wartbarkeit und Erweiterbarkeit
verbessert werden, mit dem Ziel, den jeweiligen Aufwand für Fehleranalyse und
funktionale Erweiterungen deutlich zu senken.
Quelle: https://de.wikipedia.org/wiki/Refactoring
Schreibe nur Code, der verlangt wird.
Entwickle schrittweise Deinen Code.
Wähle möglichst kleine Schritte.
Jeder Schritt muss den Code verbessern.
Test
Implementierung
Refaktorisierung
1. Änderungsbereiche aufdecken.
2. Testpunkte aufdecken.
3. Abhängigkeiten aufbrechen.
4. Tests schreiben.
5. Änderungen vornehmen & refaktorisieren.
1. Quellcode einchecken.
2. Einen Überblick darüber verschaffen was geändert werden soll.
3. Mindestens einen Test schreiben der das bestehende Verhalten
charakterisiert.
4. Refaktorisieren
5. Prüfen ob das Verhalten sich verändert hat.
Code without tests is bad code. It doesn't matter how
well written it is; it doesn't matter how pretty or object-
oriented or well-encapsulated it is.
With tests, we can change the behavior of our code
quickly and verifiably. Without them, we really don't
know if our code is getting better or worse.
Benutzersicht
Speichern
Datenvalidierung
Fehlerbehandlung
Validierungsregeln
Speichervorgang
Zurücksetzen bei
Fehler
Fehlerausschrift
Validator
Event Handling
DB
Datenbank-
anbindung
DS
ExternEntwicklersicht
Benutzersicht Entwicklersicht
Speichern
Datenvalidierung
Fehlerbehandlung
Validierungsregeln
Speichervorgang
Zurücksetzen bei
Fehler
Fehlerausschrift
Validator
Unit-Tests
System-Tests
Event Handling
DB
Datenbank-
anbindung
DS
Extern
Integration Tests
Benutzersicht Entwicklersicht
Speichern
Datenvalidierung
Fehlerbehandlung
Validierungsregeln
Speichervorgang
Zurücksetzen bei
Fehler
Fehlerausschrift
Validator
Micro Test
Component Tests
Event Handling
DB
Datenbank-
anbindung
DS
Extern
Benutzersicht Entwicklersicht
Speichern
Datenvalidierung
Fehlerbehandlung
Validierungsregeln
Speichervorgang
Zurücksetzen bei
Fehler
Fehlerausschrift
Validator
Micro Test
Event Handling
DB
Datenbank-
anbindung
DS
Extern
Benutzersicht Entwicklersicht
Speichern
Datenvalidierung
Fehlerbehandlung
Validierungsregeln
Speichervorgang
Zurücksetzen bei
Fehler
Fehlerausschrift
Validator
Component Tests
Event Handling
DB
Datenbank-
anbindung
DS
Extern
Benutzersicht
Speichern
System-Tests
Zeug DB
DS
Extern
Integration Tests
Quelle: Daniel Marbach, Legacy Code und Jetzt?
Add Parameter Introduce Class Annotation Replace Conditional with Polymorphism
Change Bidirectional Association to Unidirectional Introduce Expression Builder Replace Constructor with Factory Method
Change Reference to Value Introduce Foreign Method Replace Data Value with Object
Change Unidirectional Association to Bidirectional Introduce Gateway Replace Delegation With Hierarchy
Change Value to Reference Introduce Local Extension Replace Delegation with Inheritance
Collapse Hierarchy Introduce Named Parameter Replace Dynamic Receptor with Dynamic Method Definition
Consolidate Conditional Expression Introduce Null Object Replace Error Code with Exception
Consolidate Duplicate Conditional Fragments Introduce Parameter Object Replace Exception with Test
Decompose Conditional Isolate Dynamic Receptor Replace Hash with Object
Duplicate Observed Data Lazily Initialized Attribute Replace Inheritance with Delegation
Dynamic Method Definition Move Eval from Runtime to Parse Time Replace Loop with Collection Closure Method
Eagerly Initialized Attribute Move Field Replace Magic Number with Symbolic Constant
Encapsulate Collection Move Method Replace Method with Method Object
Encapsulate Downcast Parameterize Method Replace Nested Conditional with Guard Clauses
Encapsulate Field Preserve Whole Object Replace Parameter with Explicit Methods
Extract Class Pull Up Constructor Body Replace Parameter with Method
Extract Interface Pull Up Field Replace Record with Data Class
Extract Method Pull Up Method Replace Subclass with Fields
Extract Module Push Down Field Replace Temp with Chain
Extract Subclass Push Down Method Replace Temp with Query
Extract Superclass Recompose Conditional Replace Type Code with Class
Extract Surrounding Method Remove Assignments to Parameters Replace Type Code with Module Extension
Extract Variable Remove Control Flag Replace Type Code With Polymorphism
Form Template Method Remove Middle Man Replace Type Code with State/Strategy
Hide Delegate Remove Named Parameter Replace Type Code with Subclasses
Hide Method Remove Parameter Self Encapsulate Field
Inline Class Remove Setting Method Separate Query from Modifier
Inline Method Remove Unused Default Parameter Split Temporary Variable
Inline Module Rename Method Substitute Algorithm
Inline Temp Replace Abstract Superclass with Module
Introduce Assertion Replace Array with Object
refactoring.com
Seam
A seam is a Place where you can alter behavior
in your program without editing in that Place.
Enabling Point
Every seam has an enabling point, a Place
where you can make the decision to use one
behavior or another.
Code <-> Methode
Methode <-> Methoden
Methode(n) <-> Klasse
Klasse <-> Klassen
Klasse(n) <-> Interface
Interface <-> Interfaces
Klasse(n) <-> Namspace(s)
Namspace(s) <-> Assembly/ies
Inline extract
User Interface
Business Layer
Data Access Layer
Cross
Cutting
Concerns
DEMO
public class PersonSelectionViewModel
{
List<Person> Persons { get; set; }
public void Initialize()
{
var query = "SELECT * FROM PEOPLE";
var connection = new DataBaseConnection();
var command = connection.CreateCommand(query);
var reader = command.Excute();
this.Persons = new List<Person>();
while(reader.Next())
{
var person = new Person();
person.Id = reader["ID"];
person.Name = reader["NAME"];
this.Persons.Add(person);
}
return;
}
. . .
[TestMethod]
public void ViewModelMustShowAllPersons ()
{
this.SetupDataBase();
var person = this.AddPersonToDataBase();
var sut = new PersonSelectionViewModel();
sut.Initialize();
this.AssertThatDataBaseContains(person);
}
public class PersonSelectionViewModel
{
List<Person> Persons { get; set; }
public void Initialize()
{
var repository = new PersonRepository();
this.Persons = repository.GetAllPersons();
return;
}
public void Save(Person person)
{
var repository = new PersonRepository();
repository.Save(person);
return;
}
. . .
}
[TestMethod]
public void ViewModelMustShowAllPersons()
{
using(ShimsContext.Create())
{
var person = new Person() { Name = "Meyer" };
ShimPersonRepository.AllInstances.GetPersons =
() => return new List<Person> {person};
var sut = new PersonSelectionViewModel();
sut.Initialize();
Assert.IsTrue(sut.Persons.Contains(person));
}
}
[TestMethod]
public void ViewModelMustShowAllPersons ()
{
var person = new Person() { Name = "Meyer" };
var rep = Mock.Create<PersonRepository>();
Mock.Arrange(() => rep.Persons).IgnoreInstance()
.Returns(new List<Person> { person });
var sut = new PersonSelectionViewModel();
// Initializes the view model
sut.Initialize();
Assert.IsTrue(sut.Persons.Contains(person));
}
public class PersonSelectionViewModel
{
List<Person> Persons { get; set; }
private IPersonRepository repository;
private IPersonRepository Repository
{
get
{
return this.repository ?? (this.repository = new PersonRepository());
}
}
public void Initialize()
{
this.Persons = this.repository.GetAllPersons();
return;
}
. . .
}
[TestMethod]
public void ViewModelMustShowAllPersons()
{
var person = new Person() { Name = "Meyer" };
var repository = A.Fake<IPersonRepository>();
A.CallTo(repository.GetPersons()).Returns(new List<Person> {person});
var sut = new PersonSelectionViewModel();
var accessor = new PrivateObject(sut);
accessor.SetFieldOrProperty("repository", repository);
sut.Initialize();
Assert.IsTrue(sut.Persons.Contains(person));
}
•
•
•
•
•
SLOC
(in Mio.)
Windows NT 3.1 (1993) 4–5
Windows NT 3.5 (1994) 7–8
Windows NT 4.0 (1996) 11–12
Windows 2000 (2000) > 29
Windows XP (2001) 40
Windows Server 2003 (2003) 50
= 187 LoC
π •👍
Klasse < 500 LoC
Methode < 50 LoC ?
1 2 3
π •👍
Methode <= 9
π •👍
Hierachieebene <= 6
public class ActionBarViewModel : ReactiveObject, IActionBarViewModel
Komplexität == 2
Komplexität == 3
public SourceSelectionViewModel(IEventAggregator eventAggregator)
{
this.eventAggregator = eventAggregator;
this.readDataCommand = new ReactiveCommand();
this.readDataCommand.Subscribe( _ => this.ReadData());
}
π •👍
1 bis 10 = normal
11 bis 20 = moderat
21 bis 50 = riskant
> 50 = instabil
Komplexität == 3
Quelle: http://www.artima.com/weblogs/viewpost.jsp?thread=210575
C.R.A.P.(m) = CC(m)^2 * (1 – Coverage(m)/100)^3 + CC(m)
Quelle: https://www.artima.com/weblogs/viewpost.jsp?thread=215899
C.R.A.P.(m) = CC(m)^2 * (1 – Coverage(m)/100)^3 + CC(m)
π •👍
30
Systemtest
Integrationstest
Unit Tests
Integration
Based
Component
Based
Baby StepUI Based
Quelle: Ron Jeffries http://xprogramming.com/articles/refactoring-not-on-the-backlog
Quelle: Dr. Elmar Jürgens, CQSE
4
3
2
1
Keine Defizite
Keine Defizite in geändertem Code
Keine neuen Defizite
Egal
Pragmatismus Overengineering
Refaktorisiere niemals nur des Refaktorisierens wegen!
Legacy Code refaktorisieren

Weitere ähnliche Inhalte

Ähnlich wie Legacy Code refaktorisieren

96% macoun 2013
96% macoun 201396% macoun 2013
96% macoun 2013
Maxim Zaks
 
Lightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPALightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPA
mh0708
 
dotnet Cologne 2013 - Windows Azure Mobile Services
dotnet Cologne 2013 - Windows Azure Mobile Servicesdotnet Cologne 2013 - Windows Azure Mobile Services
dotnet Cologne 2013 - Windows Azure Mobile Services
Sascha Dittmann
 

Ähnlich wie Legacy Code refaktorisieren (20)

Codesmells
CodesmellsCodesmells
Codesmells
 
Große Applikationen mit AngularJS
Große Applikationen mit AngularJSGroße Applikationen mit AngularJS
Große Applikationen mit AngularJS
 
A/B Testing mit Node.js
A/B Testing mit Node.jsA/B Testing mit Node.js
A/B Testing mit Node.js
 
96% macoun 2013
96% macoun 201396% macoun 2013
96% macoun 2013
 
Lightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPALightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPA
 
Mögen die Tests mit dir sein
Mögen die Tests mit dir seinMögen die Tests mit dir sein
Mögen die Tests mit dir sein
 
QUANTO Solutions Q-SEC
QUANTO Solutions Q-SECQUANTO Solutions Q-SEC
QUANTO Solutions Q-SEC
 
QUANTO Solutions Q-GO
QUANTO Solutions Q-GOQUANTO Solutions Q-GO
QUANTO Solutions Q-GO
 
Best Practices für TDD in JavaScript
Best Practices für TDD in JavaScriptBest Practices für TDD in JavaScript
Best Practices für TDD in JavaScript
 
Feature Flags mit Togglz
Feature Flags mit TogglzFeature Flags mit Togglz
Feature Flags mit Togglz
 
Real Application Testing - DOAG SIG Database 2010 - Simon Dickmeiß
Real Application Testing - DOAG SIG Database 2010 - Simon DickmeißReal Application Testing - DOAG SIG Database 2010 - Simon Dickmeiß
Real Application Testing - DOAG SIG Database 2010 - Simon Dickmeiß
 
MVVM mit WPF
MVVM mit WPFMVVM mit WPF
MVVM mit WPF
 
Wicket Kurzübersicht
Wicket KurzübersichtWicket Kurzübersicht
Wicket Kurzübersicht
 
dotnet Cologne 2013 - Windows Azure Mobile Services
dotnet Cologne 2013 - Windows Azure Mobile Servicesdotnet Cologne 2013 - Windows Azure Mobile Services
dotnet Cologne 2013 - Windows Azure Mobile Services
 
Was ist eigentlich eine Unit?
Was ist eigentlich eine Unit?Was ist eigentlich eine Unit?
Was ist eigentlich eine Unit?
 
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
 
Cloud Deployment und (Auto)Scaling am Beispiel von Angrybird
Cloud Deployment und (Auto)Scaling am Beispiel von AngrybirdCloud Deployment und (Auto)Scaling am Beispiel von Angrybird
Cloud Deployment und (Auto)Scaling am Beispiel von Angrybird
 
WPF Dos n Don'ts - der WPF Rundumschlag
WPF Dos n Don'ts - der WPF RundumschlagWPF Dos n Don'ts - der WPF Rundumschlag
WPF Dos n Don'ts - der WPF Rundumschlag
 
MicroProfile 2.x: Der alternative Standard
MicroProfile 2.x: Der alternative StandardMicroProfile 2.x: Der alternative Standard
MicroProfile 2.x: Der alternative Standard
 
Agiles Testen - Überblick
Agiles Testen - ÜberblickAgiles Testen - Überblick
Agiles Testen - Überblick
 

Mehr von Hendrik Lösch

„Wie reden Sie denn mit mir?!?“ – Stakeholder überzeugen als Softwarearchitekt
„Wie reden Sie denn mit mir?!?“ – Stakeholder überzeugen als Softwarearchitekt„Wie reden Sie denn mit mir?!?“ – Stakeholder überzeugen als Softwarearchitekt
„Wie reden Sie denn mit mir?!?“ – Stakeholder überzeugen als Softwarearchitekt
Hendrik Lösch
 

Mehr von Hendrik Lösch (20)

Why (most) softwareprojects fail silently
Why (most) softwareprojects fail silentlyWhy (most) softwareprojects fail silently
Why (most) softwareprojects fail silently
 
We (don't) need a software architect!?!
We (don't) need a software architect!?!We (don't) need a software architect!?!
We (don't) need a software architect!?!
 
Restrukturierung einer industriellen Großapplikation
Restrukturierung einer industriellen GroßapplikationRestrukturierung einer industriellen Großapplikation
Restrukturierung einer industriellen Großapplikation
 
Vom Monolith zum Modulith
Vom Monolith zum ModulithVom Monolith zum Modulith
Vom Monolith zum Modulith
 
Der Software auf den Zahn gefühlt - Einstieg in die Architekturbewertung
Der Software auf den Zahn gefühlt - Einstieg in die ArchitekturbewertungDer Software auf den Zahn gefühlt - Einstieg in die Architekturbewertung
Der Software auf den Zahn gefühlt - Einstieg in die Architekturbewertung
 
„Wie reden Sie denn mit mir?!?“ – Stakeholder überzeugen als Softwarearchitekt
„Wie reden Sie denn mit mir?!?“ – Stakeholder überzeugen als Softwarearchitekt„Wie reden Sie denn mit mir?!?“ – Stakeholder überzeugen als Softwarearchitekt
„Wie reden Sie denn mit mir?!?“ – Stakeholder überzeugen als Softwarearchitekt
 
Software ist was du draus machst!
Software ist was du draus machst!Software ist was du draus machst!
Software ist was du draus machst!
 
Modular mit .NET
Modular mit .NETModular mit .NET
Modular mit .NET
 
.NET zu .NET Core
.NET zu .NET Core.NET zu .NET Core
.NET zu .NET Core
 
Workshop Vue js
Workshop Vue jsWorkshop Vue js
Workshop Vue js
 
Migrationsstrategien
MigrationsstrategienMigrationsstrategien
Migrationsstrategien
 
Einstieg in das Vueniverse
Einstieg in das VueniverseEinstieg in das Vueniverse
Einstieg in das Vueniverse
 
Survivalkit für Codehausmeister
Survivalkit für CodehausmeisterSurvivalkit für Codehausmeister
Survivalkit für Codehausmeister
 
Confessions of a Codehausmeister
Confessions of a CodehausmeisterConfessions of a Codehausmeister
Confessions of a Codehausmeister
 
Hey, wie geht es dir?
Hey, wie geht es dir?Hey, wie geht es dir?
Hey, wie geht es dir?
 
Clean mit visual studio
Clean mit visual studioClean mit visual studio
Clean mit visual studio
 
Der Healthcheck für Softwareprojekte
Der Healthcheck für SoftwareprojekteDer Healthcheck für Softwareprojekte
Der Healthcheck für Softwareprojekte
 
Ionic 3
Ionic 3Ionic 3
Ionic 3
 
Ionic 2 - Hybridapps auf Steroiden
Ionic 2 - Hybridapps auf SteroidenIonic 2 - Hybridapps auf Steroiden
Ionic 2 - Hybridapps auf Steroiden
 
Werkzeugkasten
WerkzeugkastenWerkzeugkasten
Werkzeugkasten
 

Legacy Code refaktorisieren

Hinweis der Redaktion

  1. Rigidity – Starrheit Fragility – Zerbrechlichkeit Immobility - UNbeweglichkeit
  2. Fachlicher Druck, wenn der Auftraggeber auf die Projektbeteiligten Druck ausübt, neue Fachlichkeiten schnell und bevor technische Aufräumarbeiten abgeschlossen sind, geliefert zu bekommen. Ungenügende qualitätssichernde Prozesse, wenn es in einem Projekt keine qualitätssichernden Prozesse gibt (oder diese nicht gelebt werden), welche die Technische Schuld laufend messen und Verbesserungsmaßnahmen einleiten. Ungenügendes technisches Wissen, um technische Entscheidungen treffen zu können, welche die Technische Schuld nicht erhöhen und im Optimalfall reduzieren. Ungenügende Kommunikation der gewählten technischen Lösungen und ihrer Hintergründe. Die Kommunikation kann auf vielerlei Arten erfolgen, beispielsweise durch selbsterklärenden Code, Dokumentation, Diagramme, Videos etc. Parallele Entwicklung in eigenen Branches (beispielsweise Featurebranches) führt zu erhöhten Zusammenführungsaufwänden und somit Technischer Schuld. Hintangestelltes Refactoring, wenn in Codeteilen, welche verbesserungswürdig sind, weiter Fachlichkeiten umgesetzt werden, ohne davor die Verbesserungen umzusetzen. Je mehr diese notwendigen Refactorings verzögert werden, desto aufwändiger werden sie bzw. die Umsetzung von Fachlichkeiten.
  3. Rigidity – Starrheit Fragility – Zerbrechlichkeit Immobility - UNbeweglichkeit
  4. Lines of IL Code Referenzgröße die erlaubt Dinge in ein Verhältnis zueinander zu setzen
  5. - Die 9 wird von FX Cop als Maximal angesehen
  6. Jede Ableitung (außer Interfaces) erhöht den Wert um 1 Klassen starten mit 1 Interfaces gelten nicht als Klassen und haben deshalb 0 Wenn man von Frameworkelementen erbt, hat man automatisch eine höhere Vererbungstiefe. Die Zusammenfassung für die DLL/den Namensraum zeigt immer den höchsten Wert
  7. 1. The deeper a class in the hierarchy, the greater the number of methods it will probably inherit which makes it harder to predict its behavior. 2. Deeper trees involve greater design complexity since more classes and methods are involved. 3. Deeper classes in the tree have a greater potential for reusing inherited methods.   Assumptions 1 and 2 tell us that having a higher number for depth is bad. If that is where it ended we would be in good shape; however assumption 3 indicates that a higher number for depth is good for potential code reuse.
  8. Spiegelt die Anzahl der Entscheidungen im Code wieder Wie oft muss der Code durchlaufen werden um alle Codepfade abzudecken Die Komplexität für Klassen und Namensräume wird kumuliert
  9. Unit Tests sollten immer eine CC von 1 haben!
  10. - Bei 25 gibt es eine Warnung von FX Cop
  11. Wert zwischen 0 und 100
  12. - Code Map hilft dabei sich einen Überblick über die Abhängigkeiten im Code zu verschaffen