Slide 1

Slide 1 text

Effective approaches when working with huge legacy codebase By Paul Taykalo, Stanfy Paul Taykalo, UMT 2016 1

Slide 2

Slide 2 text

Legacy code Paul Taykalo, UMT 2016 2

Slide 3

Slide 3 text

Plan 4 What is Legacy Code 4 Problems with Legacy Code 4 Dealing with Legacy Code 4 Features vs Refactoring balance 4 Measure our Success :) Paul Taykalo, UMT 2016 3

Slide 4

Slide 4 text

What is Legacy Code? Paul Taykalo, UMT 2016 4

Slide 5

Slide 5 text

an amount of money or property left to someone in a will :) Definition Legacy Code /lɛɡəsi/ Paul Taykalo, UMT 2016 5

Slide 6

Slide 6 text

So here we'll tell what legacy code is not :) Legacy code is not... Paul Taykalo, UMT 2016 6

Slide 7

Slide 7 text

Even the code is bad it doesn't make it a Legacy. Bad code can be covered with tests, and works fine. And sometimes more then enough. Don't mark it as a Legacy if you think that it's just look bad Bad Code is not always a Legacy Code Paul Taykalo, UMT 2016 7

Slide 8

Slide 8 text

It's always good to blame other people for making a legacy code. If you know people who are writing the code, and you can reach them - they writing kind'a ok code. In case if they left their job, for some reasons people automatically tend to think that code of people who left is legacy. by default. Other people's code is not a Legacy code Paul Taykalo, UMT 2016 8

Slide 9

Slide 9 text

From the other hand... Paul Taykalo, UMT 2016 9

Slide 10

Slide 10 text

This works backwards too Nice looking code can be a Legacy code Paul Taykalo, UMT 2016 10

Slide 11

Slide 11 text

Code without tests is bad code. It doesn't matter how well written it is 1 Michael C. Feathers Working with Legacy Code Paul Taykalo, UMT 2016 11

Slide 12

Slide 12 text

Why do we so care about it? May be Legacy Code is just another buzzword we complains about? Why do we care about Legacy Code? Paul Taykalo, UMT 2016 12

Slide 13

Slide 13 text

Legacy code is... Paul Taykalo, UMT 2016 13

Slide 14

Slide 14 text

Legacy code is... Complex Paul Taykalo, UMT 2016 14

Slide 15

Slide 15 text

It strikes you when you aren't expecting it. At Friday's evening, for example https://www.youtube.com/watch?v=DT2X5b0tyDI Legacy code is... Unpredictable Paul Taykalo, UMT 2016 15

Slide 16

Slide 16 text

Legacy code is... Unmaintainable Paul Taykalo, UMT 2016 16

Slide 17

Slide 17 text

Because all of above, it's really hard to support this kind of code in reasonable timte Legacy code is... Time consuming Paul Taykalo, UMT 2016 17

Slide 18

Slide 18 text

And beacuse of that Legacy code actually becomes a proble. It just stops feature delivery Legacy code ... Stops features delivery Paul Taykalo, UMT 2016 18

Slide 19

Slide 19 text

Ask yourself, do you have Legacy in the Project? Why do we write it? Paul Taykalo, UMT 2016 19

Slide 20

Slide 20 text

here are some generators which produce Unmaintainable code Unmaintainable code generators Paul Taykalo, UMT 2016 20

Slide 21

Slide 21 text

Sometimes it's really "Tecnical Debt", when customer comes in and asks to make feature really fast. But some lazy developers tend to use Unmaintainable code generators 4 So called "Technical Debt" Paul Taykalo, UMT 2016 21

Slide 22

Slide 22 text

No comment here Unmaintainable code generators 4 So called "Technical Debt" 4 Code without Tests Paul Taykalo, UMT 2016 22

Slide 23

Slide 23 text

YAA makes project way more complex, an way more harder to support Unmaintainable code generators 4 So called "Technical Debt" 4 Code without Tests 4 Yet Another Architecture Paul Taykalo, UMT 2016 23

Slide 24

Slide 24 text

It's the same for another cute awesome library. In ost cases it's better to avoid additional library. You just can't allow to add to your code even more complexity Unmaintainable code generators 4 So called "Technical Debt" 4 Code without Tests 4 Yet Another Architecture 4 Super Awesome Library X Paul Taykalo, UMT 2016 24

Slide 25

Slide 25 text

Funny one. Other people generates Legacy Code by default. It is known Unmaintainable code generators 4 So called "Technical Debt" 4 Code without Tests 4 Yet Another Architecture 4 Super Awesome Library X 4 Other people* Paul Taykalo, UMT 2016 25

Slide 26

Slide 26 text

How to avoid writing Legacy Code? Paul Taykalo, UMT 2016 26

Slide 27

Slide 27 text

So here ae some tecnics that will prevent us from writing legacy code. Dealing with Legacy Code Preventive measures Paul Taykalo, UMT 2016 27

Slide 28

Slide 28 text

Easy one Stop writing code! Paul Taykalo, UMT 2016 28

Slide 29

Slide 29 text

If you don't write any code - you won't be able to add more legacy to it. Also, it's obviously that reading few lines of code is way simpler than reading 200 Stop writing code! 4 More code - more legacy code 4 Less code - less errors 4 Less code is easier to read Paul Taykalo, UMT 2016 29

Slide 30

Slide 30 text

E=mc2 Errors = ( more code )2 Paul Taykalo, UMT 2016 30

Slide 31

Slide 31 text

This is actually contrexample, when you need to write more code to make it more readable. The Idea here is to make code readable and understandable. Check two exampes above Less code exceptions mViewModels.value.map { $0.map { $0.map { $0.price }}} mViewModels.value.map { sections in sections.map { items in items.map { item in item.price } } } Paul Taykalo, UMT 2016 31

Slide 32

Slide 32 text

Start adding tests Paul Taykalo, UMT 2016 32

Slide 33

Slide 33 text

Hey, I'm captain obsious here, but you need to add them, seriously Start adding tests Paul Taykalo, UMT 2016 33

Slide 34

Slide 34 text

You should start writing tests from tomorrow. Start adding tests If you don't write tests you will never learn how to write them, its better to write bad tests then not to write any — https://t.co/KgfdqTbOSr Paul Taykalo, UMT 2016 34

Slide 35

Slide 35 text

Start adding tests Whenever you are tempted to type something into a print statement or a debugger expression, write it as a test instead. — Martin Fowler Paul Taykalo, UMT 2016 35

Slide 36

Slide 36 text

I have an opinion about this part. Depending on the project size So here, depending on the side of the project, if project is small, you would probably wont' receive any time saves, just beacuase o fproject size. So technically test setup and runs will take you way more precious time to do. Paul Taykalo, UMT 2016 36

Slide 37

Slide 37 text

Generated code. Really helpful to prevent mistakes. If it works - it works for every generated class. if it wont - it won't Do code generation Paul Taykalo, UMT 2016 37

Slide 38

Slide 38 text

Do code generation! 4 Stops you from manual work 4 Unifies project architecture 4 Prevents you from human-like mistakes Paul Taykalo, UMT 2016 38

Slide 39

Slide 39 text

If you're about to stick to the same architecture, it means, that you can predefine some parts to be in templates. This will decreas amount of time to rewrite things, and also Make templates for classes or big code parts Paul Taykalo, UMT 2016 39

Slide 40

Slide 40 text

Pull Requests. At least more than one person will know about what happening in the code base Let other people read your code Paul Taykalo, UMT 2016 40

Slide 41

Slide 41 text

Am I doing better today? Is it better then previous year? Dealing with Legacy Code Know your status Paul Taykalo, UMT 2016 41

Slide 42

Slide 42 text

Know your status Paul Taykalo, UMT 2016 42

Slide 43

Slide 43 text

More than that. Make your code easy to delete Dealing with Legacy Code Delete code Paul Taykalo, UMT 2016 43

Slide 44

Slide 44 text

EACH big project will have unused classes/methods etc It's superb to / Libraries Remove old unused code Paul Taykalo, UMT 2016 44

Slide 45

Slide 45 text

Just remove it. Easily. It's simple Remove old unused code func removeItem(item: MenuItem) { var sectionsToRemove: [CartOrderSection] = [] // mSections.value.forEach { section in // section.removeItem(item) // let containsNonPinnedItems = section.items.value.contains { $0.menuItem.pinned != true } // if !containsNonPinnedItems { // sectionsToRemove += [section] // } // } for section in sectionsToRemove { removeSection(section) } mSections.value = mSections.value } Paul Taykalo, UMT 2016 45

Slide 46

Slide 46 text

Not all IDEs will tell you about that. Be careful if you do dynamic classes Remove old unused code Paul Taykalo, UMT 2016 46

Slide 47

Slide 47 text

Feel free to mark classes/methods as deprecated, this will prevent these classes/methos usage across the prohect. You don't want really bad code to spread around more than it does now Deprecate unwanted code Paul Taykalo, UMT 2016 47

Slide 48

Slide 48 text

If you spent some time reading legacy code - and you cannot fix it now, but you unrestood what next possible steps should be Leave a comment. This will prevent you or other people for re- reading and rethinking the complex part of the code. Leave comments Leave warnings Paul Taykalo, UMT 2016 48

Slide 49

Slide 49 text

In general case dependencies always grows. We should recheck our deps from time to time Recheck and cleanup dependencies Paul Taykalo, UMT 2016 49

Slide 50

Slide 50 text

Instead of blindly rewriting old code in new "way", make sure that "new way" written code won't become Legacy in short We're forcing to have tests for the new functionality as well as when we're changing old parts of code those without tests Add tests on changes you make Don't use "Change and Pray" approach Paul Taykalo, UMT 2016 50

Slide 51

Slide 51 text

It's really hard to stop fixing everything, when there are a lot of things wrong, but you should be careful about big breaking changes One refactor at the time Paul Taykalo, UMT 2016 51

Slide 52

Slide 52 text

There are some good tools for refactoring. Don't rely on the Xcode only. Some IDE's know how to do it correctly. Use tools for refactoring Paul Taykalo, UMT 2016 52

Slide 53

Slide 53 text

In case of big and long running project, there's a big desire to try some new better approaches to do something in new way. Try to avoid this as much as possible. i.e KVO vs manual observing vs Notifications. Stick to the same architecture within the project* Paul Taykalo, UMT 2016 53

Slide 54

Slide 54 text

This one is a bit cardinal solution, but there's always an option to put some parts of the project into the library. This will prevent logic leaking through All the layers of the project, and also decrease main project size. This could take a while, but it worth it. In worst case, we could try to make another application insteead of doing everthing in one app. Decrease project size Paul Taykalo, UMT 2016 54

Slide 55

Slide 55 text

Dealing with Legacy Code Understanding what went wrong Paul Taykalo, UMT 2016 55

Slide 56

Slide 56 text

Understanding what went wrong 4 Crashes 4 Bugs 4 Deadlocks 4 Data loss 4 Unexpected behaviours Paul Taykalo, UMT 2016 56

Slide 57

Slide 57 text

Captain obvious :)) Everyone doing it, right? Understanding what went wrong Crash logging Paul Taykalo, UMT 2016 57

Slide 58

Slide 58 text

Here are some tools for crash Understanding what went wrong Crash logging Tools 4 Crashlytics 4 HockeyApp 4 TestFlight 4 BugSee Paul Taykalo, UMT 2016 58

Slide 59

Slide 59 text

This can be done while trying to replicate things Understanding went wrong Debugging Paul Taykalo, UMT 2016 59

Slide 60

Slide 60 text

Xcode, LLDB, Chisel Understanding went wrong Debugging tools 4 Xcode 4 LLDB 4 Chisel 4 View Debugging / Description Paul Taykalo, UMT 2016 60

Slide 61

Slide 61 text

This can be done while trying to replicate things Understanding went wrong Remote Logging Paul Taykalo, UMT 2016 61

Slide 62

Slide 62 text

Here are some tools for remote logs Understanding went wrong Remote logging tools 4 Crashlytics 4 LogEntries Paul Taykalo, UMT 2016 62

Slide 63

Slide 63 text

Reminder Paul Taykalo, UMT 2016 63

Slide 64

Slide 64 text

Reminder Fighting Legacy Code is not our goal Paul Taykalo, UMT 2016 64

Slide 65

Slide 65 text

If you give enough time to the developers, they will rewrite code again and again and again until it will be "perfect" At least for some time Features delivery We aren't paid for fighting with Technical Debt Paul Taykalo, UMT 2016 65

Slide 66

Slide 66 text

But each feature 4 Adds more code 4 Adds complexity 4 Increases project size 4 Increases testing time Paul Taykalo, UMT 2016 66

Slide 67

Slide 67 text

This one is hard. Depending on how big your project is, you can either work with with new features and Features vs Tech Debt Paul Taykalo, UMT 2016 67

Slide 68

Slide 68 text

Different features types Paul Taykalo, UMT 2016 68

Slide 69

Slide 69 text

Different features types 4 Affects nothing (independent) 4 Affects one localized previous feature 4 Affects multiple previous features 4 Affects all application Paul Taykalo, UMT 2016 69

Slide 70

Slide 70 text

Always have time to clean up a project. Plan accordingly. From the other hand, focus on feature while doing it And don't spend any time on rewriting old functionality - Put TODOS, comments etc. 90/10 Principle* Paul Taykalo, UMT 2016 70

Slide 71

Slide 71 text

Measure Paul Taykalo, UMT 2016 71

Slide 72

Slide 72 text

Some techical stuff, easy to read, easy to check shoud be check automatically //TODO : Graph Image Measure 4 Tests count 4 Test coverage 4 Code Lines Count 4 Tests Lines Count Paul Taykalo, UMT 2016 72

Slide 73

Slide 73 text

Measure Paul Taykalo, UMT 2016 73

Slide 74

Slide 74 text

Not everything can be tracked automatically, but can be measured. Results need to be checked at retru // TODO: Other reports Measure 4 Crash-free users/sessions 4 Number of days since last incident 4 Amount of bugs create in the last X days 4 Regressions count Paul Taykalo, UMT 2016 74

Slide 75

Slide 75 text

Measure development speed Paul Taykalo, UMT 2016 75

Slide 76

Slide 76 text

Measure development speed 4 Features count per time 4 Time per feature to be delivered Paul Taykalo, UMT 2016 76

Slide 77

Slide 77 text

Recap Paul Taykalo, UMT 2016 77

Slide 78

Slide 78 text

Recap 4 Get the project status 4 Set up goals 4 Tack changes 4 Stop writing Legacy Code Paul Taykalo, UMT 2016 78

Slide 79

Slide 79 text

Stop writing Legacy Code Thank you Paul Taykalo, UMT 2016 79

Slide 80

Slide 80 text

Links 4 https://vimeo.com/138774243 4 https://tech.blacklane.com/2015/12/13/test- automation-for-ios/ 4 http://inessential.com/2016/06/03/ thecleanscreen_habit 4 https://engineering.instagram.com/instagram- android-four-years- Paul Taykalo, UMT 2016 80

Slide 81

Slide 81 text

Effective approaches when working with huge legacy codebase By Paul Taykalo, Stanfy Paul Taykalo, UMT 2016 81