Top Banner
Refactoring
101

Refactoring

Oct 30, 2014

Download

Technology

Amir Barylko

Presentation about refactoring code and testing
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Refactoring

Refactoring

Page 2: Refactoring

What is Refactoring?

Page 3: Refactoring

Refactoring is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior.

Martin FowlerRefactoring, improving design of existing code

Page 4: Refactoring
Page 5: Refactoring
Page 6: Refactoring

What happened?

Page 7: Refactoring

Sharepoint?

Page 8: Refactoring

Lack of time?

Page 9: Refactoring

Lack of skill?

Page 10: Refactoring

Poor management?

Page 11: Refactoring

Text

Page 12: Refactoring

Why Refactor?

Page 13: Refactoring

Any fool can write code that a computer can understand. Good programmers write code that humans can understand

Martin Fowler

Page 14: Refactoring

Remove duplicationRemove duplicationRemove duplication

Page 15: Refactoring

Make code maintainable

Page 16: Refactoring

Make code readable (by humans)

Page 17: Refactoring

Spaghetti Code

Page 18: Refactoring

Technical Debt

Page 19: Refactoring

Improve Design

Page 20: Refactoring

Reduce BLOC(beers x LOC)

Page 21: Refactoring

When to Refactor?

Page 22: Refactoring

Fixing bugs

Page 23: Refactoring

Adding features

Page 24: Refactoring

Code Review

Page 25: Refactoring

Manager on Vacation?

Page 26: Refactoring

100% sure the new code is better

Page 27: Refactoring

Cost Not to Refactorgreater thanCost to Refactor

Page 28: Refactoring

Cost = Doing the change+ Testing it+ Documentation

Page 29: Refactoring

Risk ofIntroducing bugs

Page 30: Refactoring
Page 31: Refactoring
Page 32: Refactoring

Only refactor if youare confident

(it works as before, no side effects)

Page 33: Refactoring

Unit Tests

Page 34: Refactoring

One classOne method

Page 35: Refactoring

No dependencies(mocks)

Page 36: Refactoring

Hard to dowith Legacy Code

Page 37: Refactoring

Core of TDD

Page 38: Refactoring

Integration Tests

Page 39: Refactoring

More thanone class

Page 40: Refactoring

Communicationbetween

components

Page 41: Refactoring

Acceptance tests

Page 42: Refactoring

Black box testing

Page 43: Refactoring

End to end

Page 44: Refactoring

Given inputWhen doing YYYExpect output

Page 45: Refactoring

Works withLegacy Code

Page 46: Refactoring

Works withNew Code

Page 47: Refactoring

Works with-40!!!

Page 48: Refactoring

Core of BDD

Page 49: Refactoring

How to Refactor?

Page 50: Refactoring
Page 51: Refactoring
Page 52: Refactoring

Code should be clear

Page 53: Refactoring

Like telling a story

Page 54: Refactoring

Refactoringalgorithm

Page 55: Refactoring

Text

Method?

Page 56: Refactoring

SecondWrite a test for it

Page 57: Refactoring

Third Make it better

Page 58: Refactoring

FourthRun the tests

Page 59: Refactoring

Repeat untilout of coffee

Page 60: Refactoring

Nesting Conditionals

Page 61: Refactoring

public double SomeMethod(){ var result = 0d;

if (_firstGuard) { result = FirstCalculation(); if (_secondGuard) { result = SecondCalculation(); } } return result;}

C#

Page 62: Refactoring

public double BetterMethod(){ if (!_firstGuard) { return 0; }

if (!_secondGuard) { return FirstCalculation(); }

return SecondCalculation();}

REFACTORED

C#

Page 63: Refactoring

class NestedCalculation def awesome_method first_calculation || second_calculation || default_calculation end

def first_calculation @first_guard && some_calc_here end def second_calculation # etc... endend

RubyREFACTORED

Page 64: Refactoring

public double SomeMethod(){ var result = 0d;

if (_guard1) { if (_guard2) { if (_guard3) { result = Calc1() + Calc2(); } } } return result;}

C#

Page 65: Refactoring

public double BetterMethod(){ if (_guard1 && _guard2 && _guard3) { return Calc1() + Calc2(); }

return 0;}

REFACTORED

C#

Page 66: Refactoring

public bool SomeMethod(){ var result = false;

if (_firstGuard) { if (_secondGuard) result = true; } else result = true;

return result;}

C#

Page 67: Refactoring

public bool BetterMethod(){ return !_firstGuard || _secondGuard;}

REFACTORED

C#

Page 68: Refactoring

Functional Inspiration

Page 69: Refactoring

DRY

Page 70: Refactoring

Stop writing custom loops

Page 71: Refactoring

Meaning rulez

Page 72: Refactoring

public Iterable<String> deploy( Iterable<String> collection) {

Collection<String> result = new ArrayList<>...;

Iterator<String> cursor = collection.iterator(); while(cursor.hasNext()) { result.add("Deployed to " + cursor.next()); } return result;}

Java

Page 73: Refactoring

Java

public Iterable<String> betterDeploy( Iterable<String> environments) { return with(environments) .convert(new DeployConverter());}

class DeployConverter implements Converter<String, String> {

public String convert(String env) { return "Deployed to " + env; }}

REFACTORED

Page 74: Refactoring

Scala

def betterDeploy(environments: Iterable[String]) : Iterable[String] {

environment.map env => s"Deploy to $env"}

REFACTORED

Page 75: Refactoring

Java

public class Movie {

private String title; private int review; public Movie(String title, int review) { this.title = title; this.review = review; } public String getTitle() {...}

public int getReview() {...} }

Page 76: Refactoring

Java

@Testpublic void whereAreMyPostIt() { // arrange Iterable<Movie> movies = asList( new Movie("Blazing Saddles", 5), new Movie("Terminator"), new Movie("Canadian Bacon", 8) ); // act Iterable<Movie> reviewed = filter(having(on(Movie.class).getReview(), greaterThan(-1)) , movies); // assert assertThat(joinFrom(reviewed).getTitle(), equalTo("Blazing Saddles, Canadian Bacon"));}

REFACTORED

Page 77: Refactoring

Java

@Testpublic void wheresMyGanttChart() {

// arrange Iterable<Movie> movies = asList(new Movie("Blazing Saddles"), new Movie("Terminator"), new Movie("Curator")); // act Matcher<Movie> endsWithAtor = new Predicate<Movie>() { public boolean apply(Movie item) { return item.getTitle().endsWith("ator"); } };

Iterable<Movie> actual = filter(endsWithAtor, movies); // assert assertThat(joinFrom(actual).getTitle(), equalTo("Terminator, Curator"));}

REFACTORED

Page 78: Refactoring

public int Mysterious(IEnumerable<int> collection){ return collection.Aggregate((a, b) => a + b);}

C#

Page 79: Refactoring

Coffee

[1..1000].reduce (t, s) -> t + s

Page 80: Refactoring

What aboutMONADS?

Page 81: Refactoring

Just kidding :)

Page 82: Refactoring

Don’t forget OOP

Page 83: Refactoring

Abstraction isKEY

Page 84: Refactoring
Page 85: Refactoring

class BudgetViewModel constructor: (json) -> @budgets = [2013, 2012, 2011] @budgetIndex = 0

salary: -> return 5000 if @budgetIndex == 0 return 2000 if @budgetIndex == 1 1000

Coffee

Page 86: Refactoring

CoffeeREFACTORED

class BudgetViewModel constructor: -> @budgets = [ new BudgetModel(2013, 5000), new BudgetModel(2012, 2000), new BudgetModel(2011, 1000) ] @budget = @budgets[0] salary: => @budget.salary

Page 87: Refactoring

Coffee

class BudgetViewModel

constructor: -> @budgets = ko.observableArray [ new BudgetModel(2013, 5000), new BudgetModel(2012, 2000), new BudgetModel(2011, 1000) ]

@budget = ko.observable()

@salary = ko.computed => @budget().salary

KO REFACTORED

Page 88: Refactoring

Language is your friend(or it should be)

Page 89: Refactoring

The right toolfor the job

Page 90: Refactoring

Coffee

class window.NewsViewModel

constructor: (@limit = -1) -> @news = ko.observableArray() @title = ko.observable() $.getJSON '../api/news', @loadNews

loadNews: (data) => max = (if @limit == -1 then -1 else @limit - 1) @news(@createNewsItem(e) for e in data[0..max]) @title @news()[0]?.Title

createNewsItem: (e) => newsItem = Title: e.Title Date: @parseDate(e.Date) Body: e.Body

Page 91: Refactoring

JS

(function() { var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

window.NewsViewModel = (function() {

function NewsViewModel(limit) { this.limit = limit != null ? limit : -1; this.createNewsItem = __bind(this.createNewsItem, this);

this.loadNews = __bind(this.loadNews, this);

this.news = ko.observableArray(); this.title = ko.observable(); $.getJSON('../api/news', this.loadNews); }

NewsViewModel.prototype.loadNews = function(data) { var e, max, _ref; max = (this.limit === -1 ? -1 : this.limit - 1); this.news((function() { var _i, _len, _ref, _results; _ref = data.slice(0, max + 1 || 9e9); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { e = _ref[_i]; _results.push(this.createNewsItem(e)); } return _results; }).call(this)); return this.title((_ref = this.news()[0]) != null ? _ref.Title : void 0); };

NewsViewModel.prototype.createNewsItem = function(e) { var newsItem; return newsItem = { Title: e.Title, Date: this.parseDate(e.Date), Body: e.Body }; };

return NewsViewModel;

})();

}).call(this);

Page 92: Refactoring

JVM supportsmultiple languages

Page 93: Refactoring

same for.net framework

Page 94: Refactoring

Tests are a greatplace to start

Page 95: Refactoring

Thank you!

Page 96: Refactoring

[email protected]

@abarylko

http://bit.ly/abarylkop

Page 97: Refactoring

Books

Page 98: Refactoring

Books

Page 99: Refactoring

Photo Credit

• Under http://creativecommons.org/licenses/by/2.5/

• Joe Cheng, DSC_7820-01, http://flic.kr/p/2Zt2u

• Bill Ward, Derek Schin's Trucks 1, http://flic.kr/p/m5L5S

• Jeremy Keith, Roast beef, http://flic.kr/p/TKUz

• Rob Campbell, Field of daisies, http://flic.kr/p/6QJjU4

• Karin Dalziel, The Thinker, http://flic.kr/p/4UYArc

• Under http://creativecommons.org/licenses/by-sa/3.0/us/

• Derick Bailey, SOLID Motivational Posters, http://bit.ly/17aVaHg

Page 100: Refactoring

Photo Credit 2• How to write good code, http://xkcd.com/844/

• Understanding flow charts, http://lifehacker.com/5909501/how-to-choose-the-best-chart-for-your-data

Page 101: Refactoring

Resources• http://www.infoq.com/news/2010/06/decision-to-refactor

• http://stackoverflow.com/questions/38635/what-static-analysis-tools-are-available-for-c

• Refactoring Catalog: http://www.refactoring.com/catalog/

• LambdaJ: https://code.google.com/p/lambda

• Coffeescript: http://coffeescript.org/