SlideShare a Scribd company logo
1 of 64
Download to read offline
Mein Freund,
der Legacy-Code
    Mathias Meyer
    Peritor GmbH
self
• Chief Cloud Officer bei Peritor GmbH
• Rubyist
• Asynchronist
• Post-Relationalist
• @roidrage
• http://github.com/mattmatt
Peritor

          Ruby on Rails
Deployment
               Performance-Tuning/-Reviews
Amazon Web Services
                       Scaling
     http://dailyawswtf.com
Peritor
Es war einmal


• Eine elegante Programmiersprache
• Ein wunderbar einfaches Web-Framework
Es war einmal



  +        =
Es war einmal


• Beide erreichten den Mainstream
• Beide wurden von vielen Entwicklern gefunden
• Beide sind keine Garantie für guten Code
Es war einmal


    Ruby und Rails im Mainstream = Millionen LOLC*




*LOLC: Lines of Legacy Code
Es war einmal


• Millionen LOLC =

• Legacy-Code ist ein Markt
Legacy-Code?



• Code ohne Tests
Legacy-Code?


• Stuff that other people wrote.
  http://www.c2.com/cgi/wiki?LegacyCode
Legacy-Code?


• Technical Debt
  Niedrige Kosten/Aufwand am Anfang, im Laufe
  der Zeit steigend
Legacy-Code?


• Code der in Production ist.
  (Mathias Meyer, 2009)
Legacy-Code?


• Ergo:
  Code den ihr tagtäglich produziert.
Legacy-Code?

• Code den keiner gern anfässt.
• Code der schwer zu ändern ist.
• Code der fehleranfällig ist.
• Code der stetig verschlimmbessert wird.
Legacy-Code?

• Änderungen werden mit der Zeit exponentiell
  teurer
• Änderungen führen zu mehr Bugs
• Änderungen brechen existierenden Code
Legacy-Code?

• Negativ vorbelastet
• Riesige Codewürste, unstrukturiert, ungetestet
• Sch***code
• Code-Smells ist noch gelinde ausgedrückt
• Broken-Windows passt schon eher
Legacy-Code?
                                          Legacy-Code in Ruby*
                         5000000
                                       LOLC          LOTC
                         4500000


                         4000000


                         3500000


                         3000000


                         2500000


                         2000000


                         1500000


                         1000000


                          500000


                               0
                                1995          2000          2005   2010




* Zahlen frei erfunden
Warum?

• Mangelnde Erfahrung
• Entwickler bringen Java, C, PHP, Perl, etc. in
  ihren Ruby-Code ein
• Mangelndes Interesse
• “Keine Zeit”
• “Feature-Druck”
Warum?

   • Weil Leute immer noch
     keine Tests schreiben
   • Tests: Oftmals schon der
     halbe Weg zum Glück
   • Refactoring ohne Tests:
     Die Welt des Schmerzes
Eine Geschichte

• Ein Controller
• Er möchte unerkannt bleiben
• Er war die Ausgeburt aller Ängste vor Legacy-
  Code
Eine Geschichte

• ~1300 Zeilen
• Für mehrere Wochen auf Abspeckkur
  geschickt
• Auf 200 Zeilen, 3 neue Controller, und den
  meisten Code ins Model abgeschoben
Das will ich auch!

• Legacy-Code muss nichts schlechtes sein
• Auch wenn er so aussieht
• Legacy-Code kann schlimm aussehen, aber es
  liegt an euch wie ihr ihn hinterlasst
• TODOs im Code vermeiden, lieber fixen
Wie?
• Offensichtliches
 • Test all the fucking time, as much and as
   widely as you can
 • Refactor like a pr0n star
 • Pair a lot of the time
 • Agile, XP, Scrum, oh my!
 • Man kann es nicht oft genug sagen
Wie?


• Given enough eyeballs, all bugs are shallow.
• And all code will be awesome.
• Nicht immer!
Redmine


• app/controllers/issues_controller.rb:
  500 Zeilen, 23.5kb, “Nur” ~1000 Zeilen Tests
Wie?

• Wie gehe ich mit solchem Code um?
• Wie gehe ich ein Refactoring an?
• Wie ziehe ich eine Test-Suite auf?
• Wie rechtfertige ich große Änderungen?
Wie?




© http://thisiswhyyourefat.com/
Halbwahrheiten

• Der große Wurf wird nicht auf einmal gelingen
• Ein großes Refactoring einplanen ist der Weg
  ins Verderben
• Stetige Verbesserung ist der Weg der Weisen
Wie?
• Know your enemy, because knowing is half the battle
Tools?
Tools?


• Refactoring-Tools in Ruby? Nada
• Gesunder Menschenverstand
• Know when to stop
Wie?


• Code-Metriken
• Code Lesen
• Exploratives Testen
Code-Metriken

• Mit Statistiken stark riechende Stellen finden
• Hohe Signal-Noise-Ratio
• Zu einfach den Fokus zu verlieren
• Einzig nützlich: Test-Coverage als Peildaumen
Code Lesen

• Use the source, Luke
• Notwendiges Übel
• Knowing!
• Con:Verlieren in Details immer zu einfach
Exploratives Testen

• Spezifische Teile des Codes mit Tests abdecken
• Zeile für Zeile, Feature für Feature
• Pro: Test-Suite wächst und ist bereit zum
  Refactoring
• Sehr hoher Lerneffekt, viele Wtf-Momente
  garantiert
Subkategorie: Mocks/Stubs

 • Pro: Nützlich gegen unliebsame Abhängigkeiten
 • Con: Kann zur Sucht, zum Dauerzustand
   werden
 • Zuviele Mocks verstecken das Wesentliche
 • Fantasy Testing
Too. Many. Mocks.
before(:each)
do


@fanout
=
mock("fanout")


@binding
=
mock("binding",
:subscribe
=>
true)


@queue
=
mock("queue",
:bind
=>
@binding,
:publish
=>
true)


@amq
=
mock("AMPQueue",
:queue
=>
@queue,
:fanout
=>
@fanout)


@serializer
=
mock("Serializer",
:dump
=>
"dumped_value")


@target
=
mock("Target
of
Request")


@reaper
=
mock("Reaper")


Nanite::Reaper.stub!(:new).and_return(@reaper)


@request_without_target
=
mock("Request",
:target
=>
nil,
:token
=>
"Token",



:reply_to
=>
"Reply
To",
:from
=>
"From",
:persistent
=>
true,
:identity
=>
"Identity")


@request_with_target
=
mock("Request",
:target
=>
"Target",
:token
=>
"Token",



:reply_to
=>
"Reply
To",
:from
=>
"From",
:persistent
=>
true)


@mapper_with_target
=
mock("Mapper",
:identity
=>
"id")


@mapper_without_target
=
mock("Mapper",
:request
=>
false,
:identity
=>
@request_without_target.identity)


@cluster_with_target
=
Nanite::Cluster.new(@amq,
32,
"the_identity",
@serializer,
@mapper_with_target)


@cluster_without_target
=
Nanite::Cluster.new(@amq,
32,
"the_identity",
@serializer,
@mapper_without_target)


Nanite::Cluster.stub!(:mapper).and_return(@mapper)
end

it
"should
forward
requests
with
targets"
do


@mapper_with_target.should_receive(:send_request).with(@request_with_target,
anything())


@cluster_with_target.__send__(:handle_request,
@request_with_target)
end
Parallele Welten
• Notfallwaffe
• Code auseinandernehmen und parallel neu
  aufbauen (aus existierendem)
• Ja, zuerst auch ohne Tests, wenn’s sein muss
• Test-Suite aufbauen mit den verschobenen
  Code-Teilen
• Eltern haften für ihre Kinder
Test-Suite Aufbauen

• Jetzt? Ja!
• Für die ganze Code-Basis? Nein!
• Klein anfangen,Vorher Hände waschen!
• Tests schreiben für Funktionalität die durch
  neue Features zerbrechen kann
• Skaliert nicht bei großen Geschwüren
Technik

• Sollbruchstellen finden
• Dependencies idenfizieren, wenn möglich
  aufbrechen
• Sollbruchstellen mit Tests abdecken
• Refactor!
• Rinse and repeat
Technik in Rails
• RESTful als Guideline, nicht als Mantra
• Controller aufbrechen
• Zuviele Actions bedeuten zuviele potentielle
  Ressourcen
• Code raus aus den Controllern, sie müssen
  dumm sein
• resource_controller, make_resourceful, etc.
Technik in Rails
• Tests von oben nach unten
 • Controller-Tests decken das wichtigste ab
 • Views nicht vergessen
 • Unit-Tests sollten daraus entstehen
• Models != ActiveRecord
• Neue Models braucht das Land
Technik in Rails


• Dependencies von Controllern nicht vergessen
 • Views
 • Helper
The Enterprise Way

• Versteck den Legacy-Code hinter noch mehr
 Legacy-Code
• ESB
• SOA
• EAI
SOAESBEAIOMGWTF!


• SOA: Legacy-Code as a Service
• Wenn schon, dann eine einfache REST-API
• Legacy-Code wird z.B. zum Web-Service
SOAESBEAIOMGWTF!

• EAI: Enterprise Application Integration
• Versteckt Code hinter Messaging-Backends
• Dröger Name, großer Effekt
• Entkoppelt alten von neuem Code
• Erspart nicht das Refactoring, macht es aber
  potentiell einfacher
SOAESBEAIOMGWTF!
• ESB: Enterprise Service Bus
• ESB = EAI + SOA + XML + OMG + Magic
• Unentdecktes Land unter Rubyists
Worauf fokussieren?
Refactoringchen

• Refactor as you go
• Code der angefasst wird, bekommt Tests
  verpasst und wird aufgeräumt
• Sollte selbstverständlich sein
Gezieltes Aufräumen
• Ein dunkle Stelle anpeilen
 • Analysieren
 • Testen
 • Refaktorieren,
 • Nochmals testen
• Sinnvoll bei vielen größeren Code Smells
The Big Refactoring

• Sowas wie ein Big Refactoring existiert nicht
• Refactoring ist ein Prozess
• In jeder Iteration Zeit einplanen zum
  Aufräumen alten Codes, mit spezifischem Ziel
• Aber: Es ist eine Alternative
The Big Rewrite
• Beliebt bei Entwicklern
• Unbeliebt beim Management, zu Recht
• Funktioniert so gut wie nie
• Oftmals voller Stop der Entwicklung
• Kulmuliert neuen Legacy-Code
• Ergebnis bleibt meist weit hinter Erwartungen
  zurück
Wie verkaufen?




Management     Entwickler
Wie verkaufen?

       • Management: Wir
         brauchen mehr
         Features
       • Entwickler: Wir
         brauchen mehr Zeit
         zum aufräumen
Wie verkaufen?
• Das klassische Vorurteil
• Es gibt auch einen Mittelweg
Wie verkaufen?

• Gar nicht, einfach machen
 • Skaliert nicht für große Umbauten
 • Hohes Business-Risiko
 • Sollte wohl durchdacht sein
Wie verkaufen?
• Argumente sammeln
 • Code-Änderungen werden teurer
 • Neue Features fließen langsamer
 • Leidenschaftlich, aber nicht trotzig, Konsens
   ist trotzdem wichtig
 • Wenn gar nichts mehr geht, Notbremse
   ziehen
Danach


Den Beweis antreten
Danach


• Bugs sind kein Weltuntergang, sie kommen vor
• Wenn man sie schneller fixen kann: Win!
Und dann?
Fin


mathias.meyer@peritor.com

More Related Content

Viewers also liked (6)

guía de lectura
guía de lecturaguía de lectura
guía de lectura
 
Bonificaciones
BonificacionesBonificaciones
Bonificaciones
 
Blogs Y Wiki
Blogs Y WikiBlogs Y Wiki
Blogs Y Wiki
 
Auf die Sturköpfe
Auf die SturköpfeAuf die Sturköpfe
Auf die Sturköpfe
 
dpsg Webmaster Convention 2010 - GMaps API
dpsg Webmaster Convention 2010 - GMaps APIdpsg Webmaster Convention 2010 - GMaps API
dpsg Webmaster Convention 2010 - GMaps API
 
Akhirnya saya berhasil berhenti merokok
Akhirnya saya berhasil berhenti merokokAkhirnya saya berhasil berhenti merokok
Akhirnya saya berhasil berhenti merokok
 

Similar to Mein Freund Der Legacy Code

Designpatterns in Ruby
Designpatterns in RubyDesignpatterns in Ruby
Designpatterns in Ruby
pfleidi
 
HTML5 und node.js Grundlagen
HTML5 und node.js GrundlagenHTML5 und node.js Grundlagen
HTML5 und node.js Grundlagen
Mayflower GmbH
 

Similar to Mein Freund Der Legacy Code (20)

Ruby on Rails SS09 04
Ruby on Rails SS09 04Ruby on Rails SS09 04
Ruby on Rails SS09 04
 
PHP Sucks?!
PHP Sucks?!PHP Sucks?!
PHP Sucks?!
 
JFS 2011 - Top 10 der Tools & Methoden - Baumgartner, Oehmichen
JFS 2011 - Top 10 der Tools & Methoden - Baumgartner, OehmichenJFS 2011 - Top 10 der Tools & Methoden - Baumgartner, Oehmichen
JFS 2011 - Top 10 der Tools & Methoden - Baumgartner, Oehmichen
 
JFS 2011 - Top 10 Tools & Methoden - Baumgartner, Oehmichen
JFS 2011 - Top 10 Tools & Methoden - Baumgartner, OehmichenJFS 2011 - Top 10 Tools & Methoden - Baumgartner, Oehmichen
JFS 2011 - Top 10 Tools & Methoden - Baumgartner, Oehmichen
 
Continuous Integration für PHP
Continuous Integration für PHPContinuous Integration für PHP
Continuous Integration für PHP
 
2008 02 01 Zeller
2008 02 01 Zeller2008 02 01 Zeller
2008 02 01 Zeller
 
BED-Con - Tools für den täglichen Kampf als Entwickler
BED-Con - Tools für den täglichen Kampf als EntwicklerBED-Con - Tools für den täglichen Kampf als Entwickler
BED-Con - Tools für den täglichen Kampf als Entwickler
 
Offline Arbeiten
Offline ArbeitenOffline Arbeiten
Offline Arbeiten
 
Webspam (German Version)
Webspam (German Version)Webspam (German Version)
Webspam (German Version)
 
Designpatterns in Ruby
Designpatterns in RubyDesignpatterns in Ruby
Designpatterns in Ruby
 
Dirty Little Snippets - SEO Campixx 2014 - Slides zum Vortrag
Dirty Little Snippets - SEO Campixx 2014 - Slides zum VortragDirty Little Snippets - SEO Campixx 2014 - Slides zum Vortrag
Dirty Little Snippets - SEO Campixx 2014 - Slides zum Vortrag
 
Qooxdoo 0.8 - Das Neue Gui Toolkit
Qooxdoo 0.8 - Das Neue Gui ToolkitQooxdoo 0.8 - Das Neue Gui Toolkit
Qooxdoo 0.8 - Das Neue Gui Toolkit
 
Mein Haus, mein Auto, mein Backend
Mein Haus, mein Auto, mein BackendMein Haus, mein Auto, mein Backend
Mein Haus, mein Auto, mein Backend
 
HTML5 und node.js Grundlagen
HTML5 und node.js GrundlagenHTML5 und node.js Grundlagen
HTML5 und node.js Grundlagen
 
JavaScript Days 2015: Security
JavaScript Days 2015: SecurityJavaScript Days 2015: Security
JavaScript Days 2015: Security
 
Clean code in ABAP
Clean code in ABAPClean code in ABAP
Clean code in ABAP
 
NetBeans für PHP-Entwickler
NetBeans für PHP-EntwicklerNetBeans für PHP-Entwickler
NetBeans für PHP-Entwickler
 
BarCamp Karlsruhe 18.06.2011
BarCamp Karlsruhe 18.06.2011BarCamp Karlsruhe 18.06.2011
BarCamp Karlsruhe 18.06.2011
 
Roslyn DDC Kompakt 2014
Roslyn DDC Kompakt 2014Roslyn DDC Kompakt 2014
Roslyn DDC Kompakt 2014
 
Testgetriebene Entwicklung mit JavaScript - webtech 2010
Testgetriebene Entwicklung mit JavaScript - webtech 2010Testgetriebene Entwicklung mit JavaScript - webtech 2010
Testgetriebene Entwicklung mit JavaScript - webtech 2010
 

More from mattmatt (6)

Cloud Conf - Datenbanken in der Cloud
Cloud Conf - Datenbanken in der CloudCloud Conf - Datenbanken in der Cloud
Cloud Conf - Datenbanken in der Cloud
 
Redis - N✮SQL Berlin
Redis - N✮SQL BerlinRedis - N✮SQL Berlin
Redis - N✮SQL Berlin
 
RabbitMQ And Nanite
RabbitMQ And NaniteRabbitMQ And Nanite
RabbitMQ And Nanite
 
The Current State of Asynchronous Processing With Ruby
The Current State of Asynchronous Processing With RubyThe Current State of Asynchronous Processing With Ruby
The Current State of Asynchronous Processing With Ruby
 
Upstream Goes To Maine
Upstream Goes To MaineUpstream Goes To Maine
Upstream Goes To Maine
 
Smalltalk on Git
Smalltalk on GitSmalltalk on Git
Smalltalk on Git
 

Mein Freund Der Legacy Code