22
Legacy Coderetreat

Legacy Coderetreat @Budapest 2013 02 16

Embed Size (px)

Citation preview

Page 1: Legacy Coderetreat @Budapest 2013 02 16

Legacy Coderetreat

Page 2: Legacy Coderetreat @Budapest 2013 02 16

About

Coderetreat started in 2009, created by:

• Gary Bernhardt

• Patrick Welsh

• Nayan Hajratwala

• Corey Haines

Legacy code retreat created in 2012 by JB Rainsberger

Page 3: Legacy Coderetreat @Budapest 2013 02 16

Me

Adrian Bolboaca

Technical and Organizational Trainer and Coach at Mozaic Works

Page 4: Legacy Coderetreat @Budapest 2013 02 16

Why

Practice

Experiment

Learn legacy code techniques

Extend your comfort zone

Learn through pair-programing

Have fun

Page 5: Legacy Coderetreat @Budapest 2013 02 16

How

1 Day of coding

Have an existing codebase

6 pairing partners

On average 135 minutes of coding

6 different legacy code techniques

A lot of fun!

Page 6: Legacy Coderetreat @Budapest 2013 02 16

Day structure

Introduction

3 sessions in the morning

Lunch 1h

3 sessions in the afternoon

Day retrospective 30 minutes

Page 7: Legacy Coderetreat @Budapest 2013 02 16

Principles

Language agnostic

Follow the constraints of the session

Delete the code changes after each session

Focus on practice

Experiment each session

Have fun!

Page 8: Legacy Coderetreat @Budapest 2013 02 16

Prerequisites

Computer

Coding environment

Testing environment

Local source control (git, etc)

Page 9: Legacy Coderetreat @Budapest 2013 02 16

The four elements of simple design

1. Passes its tests

2. Minimizes duplication

3. Maximizes clarity

4. Has fewer elements

Page 10: Legacy Coderetreat @Budapest 2013 02 16

Basic rules of refactoring

Steps

1. Duplicate implementation

2. Cover duplicated implementation with tests

(these are learning tests)

3. Reroute original code to new code

(make sure you have some initial tests)

4. Remove old implementation

5. Check tests pass

Page 11: Legacy Coderetreat @Budapest 2013 02 16

Git

cd /myroot/myfolder

git clone https://github.com/jbrains/trivia.git

git status -> check pending changes

git commit -am "non-empty message"

git reset --hard HEAD --> reset to last commit

git clean -f -d -x -> delete all untracked files

Page 12: Legacy Coderetreat @Budapest 2013 02 16

Codebase

You can find it at https://github.com/jbrains/trivia

Use git to clone the repository

Page 13: Legacy Coderetreat @Budapest 2013 02 16

Session 1: Code reading

Take 30 minutes to read the code

Try to understand it

Work in pairs

Page 14: Legacy Coderetreat @Budapest 2013 02 16

Session 2: From nothing to system tests

1.Find an entry point into your system, a method at the highest level possible, closest to external calls or the user interface

2. Define a limit of your system that blocks you from verifying resulting behavior

3. Find a way to fake this limit so that you can catch the results

4. Write a system test that verifies one of your assumptions about one specific behavior of that method

5. Refactor

Page 15: Legacy Coderetreat @Budapest 2013 02 16

Session 3: Encapsulate external dependencies

1. Look for a method that uses an external dependency (IO, framework, hardware, etc)

2. Isolate the real call to the external dependency from the rest of the method logic, so that this only uses the result/value of the external call

3. Extract the real call to the external dependency into a separate method

4. Extract the method to a new class

5. Create an abstraction for the class

6. Dependency inject the abstraction by:

a. Constructor

b. Property

c. Parameter

7. Rewrite your tests so that the external dependency is:

a. stubbed

b. mocked

Page 16: Legacy Coderetreat @Budapest 2013 02 16

Lunch

1 hour

Page 17: Legacy Coderetreat @Budapest 2013 02 16

Session 4: Reveal intent

Concepts

1. Find magic number/string within the code

2. Replace the number/string with a symbolic constant which encapsulated the value and describes the meaning of the number/string

1. Find a variable/method/class with a non-descriptive name, like Foo

2. Change Foo variable/method/class to a meaningful explicit name which might be too long to be useful but reveals intent

3. Iteratively improve* the variable/method/class name.

Improving means:

● Shortening towards a more comfortable length

● Keeping the explicit nature of the name intact

● Staying coherent with the domain

● Avoiding duplication of concepts, i.e. synonyms for the same concept

Page 18: Legacy Coderetreat @Budapest 2013 02 16

Session 5: Refactoring conditionals (slide 1/2)

Concepts

● Guard Clauses [1]

Is a chunk of code at the top of a function that serves

a similar purpose to a Precondition. It typically does

one (or any or all) of the following:

a. Returns an error when invalid input parameters.

b. Bails out when function call is inappropriate.

c. Handle trivial cases quickly.

● Explaining Variable [2]

Transform an expression into a temporary variable

that explains the purpose of the logical expression

Page 19: Legacy Coderetreat @Budapest 2013 02 16

Session 5: Refactoring conditionals (slide 2/2)

Concepts

● Decompose Conditional [4]

1. Find a method that contains a conditional expression and a chunk of functionality within this conditional

2. Use extract method to move the real functionality into a separate method

● Consolidate Conditional Expression [5]

1. Find a method that contains multiple conditional expressions or a composite conditional

2. Use extract method to move all of the conditional logic into a separate method so that it combines all the conditional logic

3. Give the new method a descriptive name that you can use in the original method (like an explaining variable)

Page 20: Legacy Coderetreat @Budapest 2013 02 16

Session 6: Extract pure functions

A pure function always evaluates the same result value given the same argument value(s). Its result cannot depend on any hidden information or state that may change as program execution proceeds or between different executions of the program. *

Steps

1. Find an atomic piece of code that can be moved into a separate public function by using Extract method

2. Replace all external dependencies within this function with independent or primitive parameters

a. Constants

b. Class variables

c. Global variables

d. Method variables outside of the extracted code

3. Returns an object instantiated inside the function

4. Add tests for the method

a. At least one test for each parameter

b. One test for each value range of each parameter

5. Refactor

Page 21: Legacy Coderetreat @Budapest 2013 02 16

Closing circle

1)How did you feel2)What did you learn3)What would you apply Monday?

Page 22: Legacy Coderetreat @Budapest 2013 02 16

Contact me

Remote pair-programming

Unit testing workshop

Test driven development workshop

Refactoring workshop

Working FAST and safe with existing code workshop

Code retreat workshop

http://mozaicworks.com

[email protected]

@adibolb

blog.adrianbolboaca.ro