Slide 1

Slide 1 text

Railslove We love to build the web. How to work with
 Legacy (Rails) Code Marco Schaden
 @donschado [email protected]
 24.05.2016

Slide 2

Slide 2 text

Legacy (Rails) Code 24.05.2016 The following is a summary of our own practical experiences enriched with opinions and knowledge of various esteemed experts and super heroes such as Kent Beck Martin Fowler Uncle Bob Martin Michael C. Feathers Katrina Owen Sandi Metz Corey Haines Jay Fields and other respected people Disclaimer

Slide 3

Slide 3 text

Legacy (Rails) Code 24.05.2016 Disclaimer The slides are primarily made with Ruby/JS web developers in mind, but apply in most principles to any language.
 We will see almost no code, but discuss a lot of best practices. You'll understand that I'm not able to show any client code. But I don't need to show you crappy code so that we can have fun about it, everybody wrote crappy code… You will have a lot of homework after this talk :)

Slide 4

Slide 4 text

Legacy (Rails) Code 24.05.2016 Disclaimer If you don’t understand something, don’t hesitate to ask. Slides are available online: https://speakerdeck.com/donschado

Slide 5

Slide 5 text

Legacy (Rails) Code 24.05.2016 Why does software become “legacy”?

Slide 6

Slide 6 text

Legacy (Rails) Code 24.05.2016 Is it the customers fault
 by changing the requirements all the time?

Slide 7

Slide 7 text

Legacy Code 21.10.2016 Why couldn't the customer just be happy, with what they first said they need…

Slide 8

Slide 8 text

google: IT+Project+Tree How the customer 
 explained it How the Project Leader 
 understood it How the Analyst designed it 
 How the Programmer 
 wrote it How the Business Consultant described it How the project was 
 documented What Operations
 deployed How the customer was billed How it was supported What the customer really needed

Slide 9

Slide 9 text

Legacy Code 21.10.2016 Random developer: 
 “It was not designed to do this, we need to start from scratch..."

Slide 10

Slide 10 text

Legacy Code 21.10.2016 Surprise: Requirements Change

Slide 11

Slide 11 text

Legacy Code 21.10.2016 Surprise: Requirements Change, all the time!

Slide 12

Slide 12 text

Legacy Code 21.10.2016 Surprise: Requirements Change, all the time! Software that cannot tolerate this, is simply poor designed.

Slide 13

Slide 13 text

Hi, I’m Marco @donschado [email protected] Software Developer
 Master of Computer Science

Slide 14

Slide 14 text

T We’re an agile team 
 and develop products for the web. Web applications are more than our daily business. We support our customers in close cooperation from the initial idea through to the launch - and beyond.

Slide 15

Slide 15 text

Legacy (Rails) Code 24.05.2016

Slide 16

Slide 16 text

Legacy (Rails) Code 24.05.2016 https://www.railslove.com/jobs

Slide 17

Slide 17 text

Legacy (Rails) Code 24.05.2016 Rails…?

Slide 18

Slide 18 text

Legacy (Rails) Code 24.05.2016 I know this is old, but when you remember web development in 2005, the demo is still awesome.

Slide 19

Slide 19 text

Legacy (Rails) Code 24.05.2016 Ruby A PROGRAMMER’S BEST FRIEND TL;DR Ruby Yukihiro Matsumoto (Matz) https://www.ruby-lang.org Ruby is designed to be human-oriented. It reduces the burden of programming and tries to push jobs back to machines. You can accomplish more tasks with less work, in smaller yet readable code. First appeared 1995 21 years ago Multi-paradigm: 
 Object-oriented imperative functional reflective dynamically typed

Slide 20

Slide 20 text

Legacy (Rails) Code 24.05.2016 David Heinemeier Hansson (DHH) Rails is an attempt to mold the beauty and productiveness of Ruby into a framework for web applications. • convention over configuration • don't repeat yourself (DRY) • model - view - controller architecture (MVC) TL;DR Rails https://www.rubyonrails.org

Slide 21

Slide 21 text

Legacy Code 21.10.2016

Slide 22

Slide 22 text

This stuff is so 2005, you better use… ELIXIR PHOENIX GO EMBER ANGULAR GRUNT GULP ELM DOCKER REACT WEBPACK BROWSERIFY REDUX FLUX RUST BACKBONE MARIONETTE NODE ES2016 SASS LESS COFFEESCRIPT POLYMER KNOCKOUT METEOR HANDLEBARS EXPRESS BOWER TRAILBLAZER CLOJURE MICROSERVICES TYPESCRIPT

Slide 23

Slide 23 text

Legacy Code 21.10.2016 the hype is a lie

Slide 24

Slide 24 text

Legacy Code 21.10.2016 http://www.gartner.com/technology/research/methodologies/hype-cycle.jsp

Slide 25

Slide 25 text

Legacy Code 21.10.2016 New technology doesn’t save you from legacy

Slide 26

Slide 26 text

Legacy (Rails) Code 24.05.2016 If you have lot of free time and are curios about new technology, it’s an amazing time to be a developer. The hype is a lie If you have a real job and maintaining a product, 
 then this doesn’t benefit you unless you rewrite your project every three months, 
 in the hottest tech available. Worse, even if you manage to resist the temptation to do that, 
 people will keep raving about their new toys and making you feel retarded.

Slide 27

Slide 27 text

Legacy (Rails) Code 24.05.2016 Mountain West Ruby 2016 - Surviving the Framework Hype Cycle by Brandon Hays https://www.youtube.com/watch?v=9zc4DSTRGeM

Slide 28

Slide 28 text

Legacy (Rails) Code 24.05.2016 def legacy_code legacy code VS technical debt class You < LegacyCode::Base Change Dependencies Testing Refactoring Bugs Rewrite vs Refactoring Tools

Slide 29

Slide 29 text

Legacy Code 21.10.2016 Legacy is not exclusively a bad thing

Slide 30

Slide 30 text

Legacy Code 21.10.2016 Most of us see legacy as…

Slide 31

Slide 31 text

Legacy (Rails) Code 24.05.2016 Some may see it differently: #vintage #oldtimer #classic

Slide 32

Slide 32 text

Legacy Code 21.10.2016 many “legacy” systems have reliably served 
 the needs of their businesses generating value (usually it’s the main system and the source of income…) people and processes depend on it just because code is old 
 doesn’t mean it has to be thrown away Some people in our industry call it legacy while the codebase is less than 2 years old?! #vintage #oldtimer #classic

Slide 33

Slide 33 text

Legacy (Rails) Code 24.05.2016 def legacy_code

Slide 34

Slide 34 text

Legacy Code 21.10.2016 slang for complex, difficult to change code code with many dependencies mostly somebody else's code “old” code with deprecated syntax/features or style highly coupled code / “spaghetti" / ball of mud code you’re afraid to touch code without tests def legacy_code

Slide 35

Slide 35 text

Legacy (Rails) Code 24.05.2016 The Michael C. Feathers definition: “code without tests” no matter how well written it is, 
 without tests you don't know 
 if a change makes it better or worse def legacy_code

Slide 36

Slide 36 text

Why does software become “legacy”?

Slide 37

Slide 37 text

Legacy (Rails) Code 24.05.2016 legacy code vs technical debt

Slide 38

Slide 38 text

Legacy (Rails) Code 24.05.2016 legacy code vs technical debt *sometimes required to move projects forward

Slide 39

Slide 39 text

Legacy (Rails) Code 24.05.2016 legacy code vs technical debt *sometimes required to move projects forward referring to the eventual consequences of any system design

Slide 40

Slide 40 text

Legacy (Rails) Code 24.05.2016 legacy code vs technical debt accumulating interest *sometimes required to move projects forward referring to the eventual consequences of any system design

Slide 41

Slide 41 text

Legacy (Rails) Code 24.05.2016 legacy code vs technical debt accumulating interest *sometimes required to move projects forward referring to the eventual consequences of any system design the result of unpaid debt

Slide 42

Slide 42 text

Legacy (Rails) Code 24.05.2016 legacy code vs technical debt accumulating interest *sometimes required to move projects forward referring to the eventual consequences of any system design code smells • metaprogramming madness • long parameter list • shotgun surgery • duplicated code • feature envy • large class • long method • case statements • complex conditionals the result of unpaid debt

Slide 43

Slide 43 text

Legacy (Rails) Code 24.05.2016 legacy code vs technical debt accumulating interest code smells refactoring • metaprogramming madness • long parameter list • shotgun surgery • duplicated code • feature envy • large class • long method • case statements • complex conditionals *sometimes required to move projects forward referring to the eventual consequences of any system design the result of unpaid debt

Slide 44

Slide 44 text

Legacy (Rails) Code 24.05.2016 So you've inherited some “legacy”… What do you look at first?

Slide 45

Slide 45 text

Legacy (Rails) Code 24.05.2016 Who wrote that crap?
 git blame all the files

Slide 46

Slide 46 text

Legacy (Rails) Code 24.05.2016 What does crappy code say about the developer who wrote it?

Slide 47

Slide 47 text

Legacy (Rails) Code 24.05.2016 What does crappy code say about the developer who wrote it? not skilled enough bad person drunk

Slide 48

Slide 48 text

Legacy (Rails) Code 24.05.2016 What does crappy code say about the developer who wrote it? not skilled enough bad person drunk changing requirements tough deadline had a bad day

Slide 49

Slide 49 text

Legacy (Rails) Code 24.05.2016 What does crappy code say about the developer who wrote it? not skilled enough bad person drunk changing requirements tough deadline had a bad day it's easy and funny to criticise but you might miss the context, at the time the code was written

Slide 50

Slide 50 text

Only blame the developers?

Slide 51

Slide 51 text

Legacy Code 21.10.2016 missing (product) strategy (no design thinking) unnecessary / tough deadlines unfinished requirements conceptually poor features needless complexity high fluctuation and poor on-boarding not enough training / further education doing agile wrong (yeah, we’re doing scrum/kanban we’re so agile!) The influence of management* on legacy: Even a development process that encourages code reviews and pairing
 can yield bad technical decisions which effect the whole architecture:

Slide 52

Slide 52 text

Legacy Code 21.10.2016 You might miss the context, at the time the code was written

Slide 53

Slide 53 text

Legacy (Rails) Code 24.05.2016 Uncle Bob: “every 5 years, double new programmers, with less than 5 years experience” http://blog.cleancoder.com/uncle-bob/2014/06/20/MyLawn.html

Slide 54

Slide 54 text

Legacy (Rails) Code 24.05.2016 Doesn't matter, now YOU need to

Slide 55

Slide 55 text

Legacy (Rails) Code 24.05.2016 Doesn't matter, now YOU need to

Slide 56

Slide 56 text

Legacy (Rails) Code 24.05.2016 Doesn't matter, now YOU need to <fix all the bugs>

Slide 57

Slide 57 text

Legacy (Rails) Code 24.05.2016 Doesn't matter, now YOU need to

Slide 58

Slide 58 text

Legacy Code 21.10.2016 change

Slide 59

Slide 59 text

Legacy (Rails) Code 24.05.2016 changing legacy code is a big deal

Slide 60

Slide 60 text

Legacy (Rails) Code 24.05.2016 In legacy code, it is particularly hard to come up with estimates that are meaningful. even the simplest code changes take a long time to implement it seems like no amount of time will be enough to understand everything you need to do to make a change Expensive

Slide 61

Slide 61 text

Legacy (Rails) Code 24.05.2016 How much change can you afford if changes are risky? What changes do we have to make? How will we know that we've done them correctly and haven't broken anything? Risk Often we don't know how much of the existing behaviour is at risk 
 when we make our changes.

Slide 62

Slide 62 text

Legacy (Rails) Code 24.05.2016

Slide 63

Slide 63 text

Legacy (Rails) Code 24.05.2016 1. Identify change points 2. Find test points 3. Break dependencies 4. Write tests 5. Make your changes and refactor Algorithm: Michael C. Feathers

Slide 64

Slide 64 text

Legacy (Rails) Code 24.05.2016 1. Identify change points 2. Find test points 3. Break dependencies 4. Write tests 5. Make your changes and refactor Algorithm: debugger, inspect, puts, tap, raise, console.log, … most obvious impediment to testing this can be hard for side effects
 sometime requires creative and ugly technics Always leave the campground cleaner than you found it Michael C. Feathers

Slide 65

Slide 65 text

Legacy (Rails) Code 24.05.2016 1. Identify change points 2. Find test points 3. Break dependencies 4. Write tests 5. Make your changes and refactor Algorithm: debugger, inspect, puts, tap, raise… most obvious impediment to testing this can be hard for side effects
 sometime requires creative and ugly technics Always leave the campground cleaner than you found it Michael C. Feathers

Slide 66

Slide 66 text

Legacy (Rails) Code 24.05.2016 Dependencies They will try to kill you

Slide 67

Slide 67 text

Legacy (Rails) Code 24.05.2016 http://blog.npmjs.org/post/141577284765/kik-left-pad-and-npm

Slide 68

Slide 68 text

Legacy (Rails) Code 24.05.2016 Whenever we bring up on our screens a nasty batch of tangled legacy code, we are experiencing the results of poor dependency management. Poor dependency management leads to code that is hard to change, fragile, and non-reusable.
 
 When classes depend directly on things that are hard to use in a test, they are hard to modify and hard to work with. Uncle Bob:

Slide 69

Slide 69 text

Legacy (Rails) Code 24.05.2016 Dependency Inversion Principle depend on abstraction instead of implementation don't call 3rd Party APIs directly in Ruby you can do this implicit as a 'protocoll' 
 (we don't care for the type of the dependency)

Slide 70

Slide 70 text

Legacy (Rails) Code 24.05.2016 Dependency Inversion Principle depend on abstraction instead of implementation don't call 3rd Party APIs directly in Ruby you can do this implicit as a 'protocoll' 
 (we don't care for the type of the dependency) A B before In UML the arrow points to a dependency

Slide 71

Slide 71 text

Legacy (Rails) Code 24.05.2016 Dependency Inversion Principle depend on abstraction instead of implementation don't call 3rd Party APIs directly in Ruby you can do this implicit as a 'protocoll' 
 (we don't care for the type of the dependency) A B before A B after I Interface! Ohai Java! In UML the arrow points to a dependency

Slide 72

Slide 72 text

Legacy (Rails) Code 24.05.2016 Dependency Inversion Principle Summary: DIP is primarily about reversing the conventional direction of dependencies from higher level components to lower level components such that lower level components are dependent upon the “interfaces” owned by the higher level components.

Slide 73

Slide 73 text

Legacy (Rails) Code 24.05.2016 Dependency Inversion Principle Summary: DIP is primarily about reversing the conventional direction of dependencies from higher level components to lower level components such that lower level components are dependent upon the “interfaces” owned by the higher level components.

Slide 74

Slide 74 text

Legacy (Rails) Code 24.05.2016 Dependency Inversion Principle Summary: DIP is primarily about reversing the conventional direction of dependencies from higher level components to lower level components such that lower level components are dependent upon the “interfaces” owned by the higher level components.

Slide 75

Slide 75 text

Legacy (Rails) Code 24.05.2016 Dependency Injection class Car def start Engine.new.start end end before

Slide 76

Slide 76 text

Legacy (Rails) Code 24.05.2016 Dependency Injection class Car def start Engine.new.start end end class Car attr_reader :engine def initialize(engine = Engine.new) @engine = engine end def start engine.start end end before after (constructor injection) Car.new(V8Engine.new).start

Slide 77

Slide 77 text

Legacy (Rails) Code 24.05.2016 Dependency Injection class Car def start Engine.new.start end end before after (setter injection) class Car attr_writer :engine def initialize end def start engine.start end def engine @engine ||= Engine.new end end

Slide 78

Slide 78 text

Legacy (Rails) Code 24.05.2016 RubyConf 2009 - SOLID Ruby by: Jim Weirich https://www.youtube.com/watch?v=dKRbsE061u4 GORUCO 2009 - SOLID Object-Oriented Design by Sandi Metz https://www.youtube.com/watch?v=v-2yFMzxqwU

Slide 79

Slide 79 text

Legacy (Rails) Code 24.05.2016 https://cleancoders.com/videos

Slide 80

Slide 80 text

Legacy (Rails) Code 24.05.2016 Testing To survive Legacy Code you need to maximise safety

Slide 81

Slide 81 text

Legacy (Rails) Code 24.05.2016 2 unit tests. 0 integration tests.

Slide 82

Slide 82 text

Legacy (Rails) Code 24.05.2016 unit test <-----> integration test

Slide 83

Slide 83 text

Legacy (Rails) Code 24.05.2016 unit test <-----> integration test aka acceptance, end to end , …

Slide 84

Slide 84 text

Legacy (Rails) Code 24.05.2016 unit test <-----> integration test hard to localize the bug when they fail very useful in bigger refactorings many people
 prefer these

Slide 85

Slide 85 text

Legacy (Rails) Code 24.05.2016 unit test <-----> integration test hard to localize the bug when they fail fast feedback very useful in bigger refactorings hard to work with
 when lots of little tests fail all the time many people
 prefer these many people
 do these wrong

Slide 86

Slide 86 text

Legacy (Rails) Code 24.05.2016 unit test <-----> integration test hard to localize the bug when they fail fast feedback very useful in bigger refactorings hard to work with
 when lots of little tests fail all the time many people
 prefer these many people
 do these wrong Use high level tests only to make sure the overall system works 
 and drive the behaviour down to the unit level.

Slide 87

Slide 87 text

Legacy (Rails) Code 24.05.2016 How to unit test In theory, writing a test 
 for a piece of functionality shouldn’t be too bad. We instantiate a class, 
 call its methods and check the results. What could go wrong? GOALS • comprehensive • stable • fast • few

Slide 88

Slide 88 text

Legacy (Rails) Code 24.05.2016 The method might not be accessible to the test. 
 It could be private or have some other accessibility problem. It might be hard to call the method because it is hard to construct the parameters we need to call it. We might need to sense through some other object that the method uses. The method might have (bad) side effects modifying a database send notification launching a cruise missile … How to unit test GOALS • comprehensive • stable • fast • few

Slide 89

Slide 89 text

Legacy (Rails) Code 24.05.2016 Rails Conf 2013 The Magic Tricks of Testing by Sandi Metz https://www.youtube.com/watch?v=URSWYvyc42M

Slide 90

Slide 90 text

Legacy (Rails) Code 24.05.2016 Legacy Code is special Testing legacy code requires creative and (sometimes) ugly technics Break all rules if it saves $$$ during development

Slide 91

Slide 91 text

Legacy (Rails) Code 24.05.2016 Rule of thumb for nearly every legacy system: What the system does is more important than what it is supposed to do.

Slide 92

Slide 92 text

Legacy (Rails) Code 24.05.2016 The tests that we need when we want to preserve behaviour are called characterization tests.

Slide 93

Slide 93 text

Legacy (Rails) Code 24.05.2016 Golden Master Testing wow, such fancy, very noble

Slide 94

Slide 94 text

Legacy (Rails) Code 24.05.2016 def: Golden Master Testing refers to capturing the result of “a process”,
 and then comparing future runs against the saved golden master version to discover unexpected changes. So you expect, that what it does now, is correct.

Slide 95

Slide 95 text

Legacy (Rails) Code 24.05.2016 Golden Master Testing wow such dirt, very temporary

Slide 96

Slide 96 text

Legacy (Rails) Code 24.05.2016 1. Use a piece of untested 
 undocumented code 2. Write an assertion 
 that you know will fail 3. Let the failure tell you 
 what the behaviour is 4. Change the test so that it 
 expects the behaviour that the code produces 5. Reason about the code 
 and exercise every branch Golden Master Testing: 6. Repeat until 
 the code is covered

Slide 97

Slide 97 text

Legacy (Rails) Code 24.05.2016 <<< The idea is: you get some output and save the result (snapshot) and every time you run the test again you compare:
 
 * the same: great the test pass, because everything works as before * different: the test fails and the human has to check the output again >>>

Slide 98

Slide 98 text

Legacy (Rails) Code 24.05.2016 This seems to be fundamentally wrong Are our tests really testing anything at all? What if you just characterized a bug?

Slide 99

Slide 99 text

Legacy (Rails) Code 24.05.2016 We are trying to put in a mechanism to find bugs later. Protection for changing things => confidence to refactor

Slide 100

Slide 100 text

Legacy (Rails) Code 24.05.2016 We are trying to put in a mechanism to find bugs later. Protection for changing things => confidence to refactor A characterization test is not a test you want to keep around. • You use the test to get coverage, • you refactor, • cleanup / write new specs • and then you throw it away!

Slide 101

Slide 101 text

Legacy (Rails) Code 24.05.2016 Highly coupled tests will cost you more money than they save you Add a comment to the tests if you keep them # delete me if I fail They will fail when you need them most to pass while fixing a critical bug making an unrelated change you need to go in production NOW manually checking the output has high error potential Anti Pattern, if you keep them

Slide 102

Slide 102 text

Legacy (Rails) Code 24.05.2016 But what about the DOM? Legacy JavaScript code usually couples UI and business logic

Slide 103

Slide 103 text

Legacy (Rails) Code 24.05.2016 Get out of managing the DOM, as fast as you can. • test user interaction with an automated browser engine • the DOM represents the state of your application • using #ids or .classes to manipulate the DOM is dead • be careful testing markup, because it will change • use data, rel or role attributes in your tests and to describe behaviour • refactor heavy jQuery code to JavaScript objects • clear separation between UI and business logic

Slide 104

Slide 104 text

Legacy (Rails) Code 24.05.2016 RailsConf 2014 - Bring Fun Back to JS: Step-by-Step Refactoring Toward Ember by Brandon Hays
 https://www.youtube.com/watch?v=VMmaKj8hCR4

Slide 105

Slide 105 text

Legacy (Rails) Code 24.05.2016 Tools

Slide 106

Slide 106 text

Legacy Code 21.10.2016 Test coverage analysis Lines of Code (no code is better than no code) Cyclomatic Complexity ABC Score for Code Smells Churn Afferent / Efferent Coupling Mutation Coverage Metrics: Usually language agnostic and a helpful tool, but metrics should never be a goal:

Slide 107

Slide 107 text

Legacy (Rails) Code 24.05.2016 SimpleCov https://github.com/colszowka/simplecov

Slide 108

Slide 108 text

Legacy (Rails) Code 24.05.2016 https://github.com/kytrinyx/approvals Golden Master Testing

Slide 109

Slide 109 text

Legacy (Rails) Code 24.05.2016 https://github.com/bblimke/webmock WebMock

Slide 110

Slide 110 text

Legacy (Rails) Code 24.05.2016 https://github.com/vcr/vcr VCR

Slide 111

Slide 111 text

Legacy (Rails) Code 24.05.2016 https://github.com/jnicklas/capybara Capybara

Slide 112

Slide 112 text

Legacy (Rails) Code 24.05.2016 https://github.com/mattheworiordan/capybara-screenshot capybara-screenshot • powerful in combination with a debugger like • https://github.com/pry/pry

Slide 113

Slide 113 text

Legacy (Rails) Code 24.05.2016 https://github.com/teampoltergeist/poltergeist Poltergeist • trigger(“click”) is your friend • unit testing jQuery spaghetti is really hard • jasmine-rails gem

Slide 114

Slide 114 text

Legacy (Rails) Code 24.05.2016 https://github.com/douglascrockford/JSLint JSLint • IDE/Editor integrations

Slide 115

Slide 115 text

Legacy (Rails) Code 24.05.2016 https://github.com/es-analysis/plato plato

Slide 116

Slide 116 text

Legacy (Rails) Code 24.05.2016 https://github.com/es-analysis/plato plato

Slide 117

Slide 117 text

Legacy (Rails) Code 24.05.2016 https://github.com/jasmine/jasmine Jasmine

Slide 118

Slide 118 text

Legacy (Rails) Code 24.05.2016 https://github.com/troessner/reek reek

Slide 119

Slide 119 text

Legacy (Rails) Code 24.05.2016 https://github.com/seattlerb/flog flog

Slide 120

Slide 120 text

Legacy (Rails) Code 24.05.2016 https://github.com/mbj/mutant mutant https://speakerdeck.com/donschado/mutation-testing-with-the-mutant-gem

Slide 121

Slide 121 text

Legacy (Rails) Code 24.05.2016 https://github.com/CoralineAda/society Afferent/Efferent Coupling • identify risky hotspots

Slide 122

Slide 122 text

Legacy (Rails) Code 24.05.2016 https://relishapp.com/rspec/rspec-mocks/v/3-4/docs/basics/ Mock / Stub / Fake Object

Slide 123

Slide 123 text

Legacy (Rails) Code 24.05.2016 Ruby & Black Magic Everything is allowed to get to first coverage instance_variable_get(:@foo) send private / protected methods reopen class and monkey patch attr_accessor capture algorithm in a lambda and use it as assertion for new refactored code import complete staging database dump into your test env

Slide 124

Slide 124 text

Legacy (Rails) Code 24.05.2016 Everything allowed? don’t forget to fix it! we can use reflection and special permissions to access private variables at runtime It is very helpful when we want to break dependencies But unless we deal with the root causes, that make these cheats necessary, we are just delaying the bill

Slide 125

Slide 125 text

Legacy (Rails) Code 24.05.2016

Slide 126

Slide 126 text

Legacy (Rails) Code 24.05.2016 Bugs

Slide 127

Slide 127 text

Legacy (Rails) Code 24.05.2016 When you work on legacy code, you will find bugs throughout the entire process. All code has bugs, usually in direct proportion to how little it is understood. Examine the possibility that someone is depending on that behaviour. Often it takes a bit of analysis to figure out how to fix a bug without causing ripple effects. fixing bugs could be dangerous... What should you do when you find a bug?

Slide 128

Slide 128 text

Legacy (Rails) Code 24.05.2016 Refactoring

Slide 129

Slide 129 text

Legacy (Rails) Code 24.05.2016

Slide 130

Slide 130 text

Legacy (Rails) Code 24.05.2016 the list of refactoring technics is just the beginning composing methods (extract method, replace method with object) moving features (move method, extract class) organizing data (replace hash with object, replace type code with polymorphism) simplifying conditional (decompose, recompose, null objects) making method calls simpler (separate query from modifier, replace constructor with factory) dealing with generalization (template method, extract module, inheritance) learn when to start, when to stop when you have “refactoring tickets” you're doing it wrong (it’s part of your work!) not having the time for refactoring (because of deadlines?) is usually a sign that you need to do some refactoring Refactoring: pay your bills!

Slide 131

Slide 131 text

Legacy (Rails) Code 24.05.2016 You are likely to see new possibilities, REFACTOR ALL THE CODE to pursue truth and beauty...

Slide 132

Slide 132 text

Legacy (Rails) Code 24.05.2016 DON’T.

Slide 133

Slide 133 text

Legacy (Rails) Code 24.05.2016 A big refactoring is a recipe for disaster. As ugly as the mess looks now, focus on the real problems. When you need to add a new feature: add some specs to get confidence clean up add new code refactoring hat, feature hat Don't mix an unfinished refactoring with other new tasks. Your goal is to leave the code computing exactly the same, like you found it. Always leave the campground cleaner than you found it. Discipline

Slide 134

Slide 134 text

Legacy (Rails) Code 24.05.2016 Rewrite vs Refactoring

Slide 135

Slide 135 text

Legacy (Rails) Code 24.05.2016 When is it easier to start from scratch, instead of refactoring a big mess?

Slide 136

Slide 136 text

Legacy (Rails) Code 24.05.2016 if it doesn't work at all (code has to work mostly correctly, before you refactor) if it is full of bugs and you cannot stabilize it there are big changing requirements, the current app can't support When is it easier to start from scratch, instead of refactoring a big mess? # depends… + + +

Slide 137

Slide 137 text

Legacy Code 21.10.2016 Compromise! Refactor one large piece into components.
 Favour piece by piece rewrite over big bang rewrite and rebuild incrementally.

Slide 138

Slide 138 text

Legacy Code 21.10.2016 Compromise! Refactor one large piece into components.
 Favour piece by piece rewrite over big bang rewrite and rebuild incrementally. • focus on the important parts • recover knowledge which got lost in complex code • preserve investment which went into the code already (time, bugfixes, requirements…)

Slide 139

Slide 139 text

Legacy Code 21.10.2016 Compromise! Refactor one large piece into components.
 Favour piece by piece rewrite over big bang rewrite and rebuild incrementally. What's the cost of debt? Which parts are less critical? Think of extra costs for maintenance and extension caused by overly complex code. • focus on the important parts • recover knowledge which got lost in complex code • preserve investment which went into the code already (time, bugfixes, requirements…)

Slide 140

Slide 140 text

Legacy Code 21.10.2016 TL;DR technical debt is the main reason for legacy code
 treat your legacy and former developers with respect
 the business always wins* (changing requirements)
 keep your code well tested
 break dependencies and decouple business logic
 maintenance == refactoring (pay your debt!)
 


Slide 141

Slide 141 text

Legacy (Rails) Code 24.05.2016 Refactoring - Ruby Edition http://www.amazon.com/Refactoring-Ruby-Addison-Wesley-Professional/dp/0321984137 TL;DR: http://ghendry.net/refactor.html Patterns of Enterprise Application Architecture http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420/ Working Effectively with Legacy Code http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052
 Golden Master Testing: Refactor Complicated Views Katrina Owen: July 09, 2014 http://www.sitepoint.com/golden-master-testing-refactor-complicated-views/ Rails Conf 2013 The Magic Tricks of Testing by Sandi Metz https://www.youtube.com/watch?v=URSWYvyc42M GORUCO 2009 - SOLID Object-Oriented Design by Sandi Metz https://www.youtube.com/watch?v=v-2yFMzxqwU Rocky Mountain Ruby 2012 - Go Ahead, Make a Mess by Sandi Metz https://www.youtube.com/watch?v=f5I1iyso29U 
 RailsConf 2014 - Step-by-Step Refactoring Toward Ember by Brandon Hays
 https://www.youtube.com/watch?v=VMmaKj8hCR4 Katrina Owen - 467 tests, 0 failures, 0 confidence - Railsberry 2013 https://vimeo.com/68730418 BathRuby 2015 - Here Be Dragons, Katrina Owen https://www.youtube.com/watch?v=QAUHYzC9kFM Cascadia Ruby Conf 2012 Therapeutic Refactoring by Katrina Owen https://www.youtube.com/watch?v=J4dlF0kcThQ RailsConf 2015 - Getting a Handle on Legacy Code https://www.youtube.com/watch?v=lsFFjFp7mEE MountainWest RubyConf 2015 - Data-Driven Refactoring https://www.youtube.com/watch?v=AcdliNixNhs Baruco 2013: Design Patterns And The Proper Cultivation Thereof, Corey Haines https://www.youtube.com/watch?v=vqN3TQgsXzI Rocky Mountain Ruby 2013 SOLID and TDD, Sitting in a by Mike Nicholaides https://www.youtube.com/watch?v=FidRcixHQos RubyConf 2009 - SOLID Ruby by: Jim Weirich https://www.youtube.com/watch?v=dKRbsE061u4 content[:source]

Slide 142

Slide 142 text

Legacy (Rails) Code 24.05.2016 Have some #legacy #vintage 
 #oldtimer 
 #classic
 App we can help you with?

Slide 143

Slide 143 text

Railslove We love to build the web. KTHXBYE Questions? Marco Schaden
 @donschado [email protected]
 24.05.2016