0
Refactoring
Amir Barylko
(About me & how to find me)
Software Quality
Expert
Agile Coach
Architect
Developer
Cook
amir@barylko.com
@abarylko
http://bit.ly/abarylkop
Disappointment
Management
Your expectations
here...
There’s always lunch!
What is Refactoring?
Refactoring is a disciplined
technique for restructuring
an existing body of code,
altering its internal
structure without...
What happened?
Sharepoint?
Lack of time?
Lack of skill?
Poor management?
Text
Why Refactor?
Any fool can write code that
a computer can understand.
Good programmers write code
that humans can understand
Martin Fowl...
Remove duplication
Remove duplication
Remove duplication
Make code
maintainable
Make code readable
(by humans)
Spaghetti Code
Technical Debt
Improve Design
Reduce BLOC
(beers x LOC)
When to Refactor?
Fixing bugs
Adding features
Code Review
Manager on Vacation?
100% sure the new
code is better
Cost Not to Refactor
greater than
Cost to Refactor
Cost = Doing the change
+ Testing it
+ Documentation
Risk of
Introducing bugs
Only refactor if you
are confident

(it works as before, no side effects)
Unit Tests
One class
One method
No dependencies
(mocks)
Hard to do
with Legacy Code
Core of TDD
Integration Tests
More than
one class
Communication
between
components
Acceptance tests
Black box testing
End to end
Given input
When doing YYY
Expect output
Works with
Legacy Code
Works with
New Code
Works with
-40!!!
Core of BDD
How to Refactor?
Code should be clear
Like telling a story
Refactoring
algorithm
Te
xt

M
et
ho

d?
Second
Write a test for it
Third
Make it better
Fourth
Run the tests
Repeat until
out of coffee
Nesting Conditionals
C#

public double SomeMethod()
{
var result = 0d;
if (_firstGuard)
{
result = FirstCalculation();
if (_secondGuard)
{
resu...
C#

RE
public double BetterMethod()
{
if (!_firstGuard)
{
return 0;
}
if (!_secondGuard)
{
return FirstCalculation();
}
re...
Ruby

class NestedCalculation
def awesome_method
first_calculation
||
second_calculation ||
default_calculation
end
def fi...
C#

public double SomeMethod()
{
var result = 0d;
if (_guard1)
{
if (_guard2)
{
if (_guard3)
{
result = Calc1() + Calc2();...
C#

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

RE

FAC
T...
C#

public bool SomeMethod()
{
var result = false;
if (_firstGuard)
{
if (_secondGuard)
result = true;
}
else
result = tru...
C#

RE

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

FAC
T

OR

ED
Functional
Inspiration
DRY
Stop writing
custom loops
Meaning rulez
Java

public Iterable<String> deploy(
Iterable<String> collection) {
Collection<String> result = new ArrayList<>...;
Itera...
Java

public Iterable<String> betterDeploy(
Iterable<String> environments) {

RE

FAC
T

return with(environments)
.conver...
Java

public class Movie {
private String title;
private int review;
public Movie(String title, int review) {
this.title =...
Java

@Test
public void whereAreMyPostIt() {
// arrange
Iterable<Movie> movies = asList(
new Movie("Blazing Saddles", 5), ...
Java

@Test
public void wheresMyGanttChart() {
// arrange
Iterable<Movie> movies = asList(new Movie("Blazing Saddles"),
ne...
C#

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

[1..1000].reduce (t, s) -> t + s
What about
MONADS?
Just kidding :)
Don’t forget OOP
Abstraction is
KEY
Coffee

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

RE
class BudgetViewModel
constructor: ->
@budgets = [
new BudgetModel(2013, 5000),
new BudgetModel(2012, 2000),
ne...
Coffee
KO

class BudgetViewModel

RE

FAC
T

OR

constructor: ->
@budgets = ko.observableArray [
new BudgetModel(2013, 500...
Language is your friend
(or it should be)
The right tool
for the job
Coffee

class window.NewsViewModel
constructor: (@limit = -1) ->
@news = ko.observableArray()
@title = ko.observable()
$.g...
JS
(function() {
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
window.NewsViewMo...
JVM supports
multiple languages
same for
.net framework
Testing is a great
place to start
Thank you!
amir@barylko.com
@abarylko
http://bit.ly/abarylkop
Books
Books
Photo Credit
•

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

•
•

Bill Ward, Derek Schin's Trucks 1, http://flic.kr/...
Photo Credit 2
•
•

How to write good code, http://xkcd.com/844/
Understanding flow charts, http://lifehacker.com/5909501/...
Resources
•
•

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

•
•
•

Refactoring Catalog: http://www.refactoring....
Refactoring
Refactoring
Refactoring
Refactoring
Refactoring
Refactoring
Refactoring
Refactoring
Refactoring
Refactoring
Upcoming SlideShare
Loading in...5
×

Refactoring

382

Published on

Presentation about what it means to refactor software, when is a good idea to do it and how to start

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
382
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
12
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Transcript of "Refactoring"

  1. 1. Refactoring
  2. 2. Amir Barylko (About me & how to find me)
  3. 3. Software Quality Expert
  4. 4. Agile Coach
  5. 5. Architect
  6. 6. Developer
  7. 7. Cook
  8. 8. amir@barylko.com @abarylko http://bit.ly/abarylkop
  9. 9. Disappointment Management
  10. 10. Your expectations here...
  11. 11. There’s always lunch!
  12. 12. What is Refactoring?
  13. 13. Refactoring is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior. Martin Fowler Refactoring, improving design of existing code
  14. 14. What happened?
  15. 15. Sharepoint?
  16. 16. Lack of time?
  17. 17. Lack of skill?
  18. 18. Poor management?
  19. 19. Text
  20. 20. Why Refactor?
  21. 21. Any fool can write code that a computer can understand. Good programmers write code that humans can understand Martin Fowler
  22. 22. Remove duplication Remove duplication Remove duplication
  23. 23. Make code maintainable
  24. 24. Make code readable (by humans)
  25. 25. Spaghetti Code
  26. 26. Technical Debt
  27. 27. Improve Design
  28. 28. Reduce BLOC (beers x LOC)
  29. 29. When to Refactor?
  30. 30. Fixing bugs
  31. 31. Adding features
  32. 32. Code Review
  33. 33. Manager on Vacation?
  34. 34. 100% sure the new code is better
  35. 35. Cost Not to Refactor greater than Cost to Refactor
  36. 36. Cost = Doing the change + Testing it + Documentation
  37. 37. Risk of Introducing bugs
  38. 38. Only refactor if you are confident (it works as before, no side effects)
  39. 39. Unit Tests
  40. 40. One class One method
  41. 41. No dependencies (mocks)
  42. 42. Hard to do with Legacy Code
  43. 43. Core of TDD
  44. 44. Integration Tests
  45. 45. More than one class
  46. 46. Communication between components
  47. 47. Acceptance tests
  48. 48. Black box testing
  49. 49. End to end
  50. 50. Given input When doing YYY Expect output
  51. 51. Works with Legacy Code
  52. 52. Works with New Code
  53. 53. Works with -40!!!
  54. 54. Core of BDD
  55. 55. How to Refactor?
  56. 56. Code should be clear
  57. 57. Like telling a story
  58. 58. Refactoring algorithm
  59. 59. Te xt M et ho d?
  60. 60. Second Write a test for it
  61. 61. Third Make it better
  62. 62. Fourth Run the tests
  63. 63. Repeat until out of coffee
  64. 64. Nesting Conditionals
  65. 65. C# public double SomeMethod() { var result = 0d; if (_firstGuard) { result = FirstCalculation(); if (_secondGuard) { result = SecondCalculation(); } } return result; }
  66. 66. C# RE public double BetterMethod() { if (!_firstGuard) { return 0; } if (!_secondGuard) { return FirstCalculation(); } return SecondCalculation(); } FAC T OR ED
  67. 67. Ruby 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... end end RE FAC T OR ED
  68. 68. C# public double SomeMethod() { var result = 0d; if (_guard1) { if (_guard2) { if (_guard3) { result = Calc1() + Calc2(); } } } return result; }
  69. 69. C# public double BetterMethod() { if (_guard1 && _guard2 && _guard3) { return Calc1() + Calc2(); } return 0; } RE FAC T OR ED
  70. 70. C# public bool SomeMethod() { var result = false; if (_firstGuard) { if (_secondGuard) result = true; } else result = true; return result; }
  71. 71. C# RE public bool BetterMethod() { return !_firstGuard || _secondGuard; } FAC T OR ED
  72. 72. Functional Inspiration
  73. 73. DRY
  74. 74. Stop writing custom loops
  75. 75. Meaning rulez
  76. 76. Java 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; }
  77. 77. Java public Iterable<String> betterDeploy( Iterable<String> environments) { RE FAC T return with(environments) .convert(new DeployConverter()); } class DeployConverter implements Converter<String, String> { public String convert(String env) { return "Deployed to " + env; } } OR ED
  78. 78. 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() {...} }
  79. 79. Java @Test public 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")); }
  80. 80. Java @Test public 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")); }
  81. 81. C# public int Mysterious(IEnumerable<int> collection) { return collection.Aggregate((a, b) => a + b); }
  82. 82. Coffee [1..1000].reduce (t, s) -> t + s
  83. 83. What about MONADS?
  84. 84. Just kidding :)
  85. 85. Don’t forget OOP
  86. 86. Abstraction is KEY
  87. 87. Coffee class BudgetViewModel constructor: (json) -> @budgets = [2013, 2012, 2011] @budgetIndex = 0 salary: -> return 5000 if @budgetIndex == 0 return 2000 if @budgetIndex == 1 1000
  88. 88. Coffee RE class BudgetViewModel constructor: -> @budgets = [ new BudgetModel(2013, 5000), new BudgetModel(2012, 2000), new BudgetModel(2011, 1000) ] @budget = @budgets[0] salary: => @budget.salary FAC T OR ED
  89. 89. Coffee KO class BudgetViewModel RE FAC T OR constructor: -> @budgets = ko.observableArray [ new BudgetModel(2013, 5000), new BudgetModel(2012, 2000), new BudgetModel(2011, 1000) ] @budget = ko.observable() @salary = ko.computed => @budget().salary ED
  90. 90. Language is your friend (or it should be)
  91. 91. The right tool for the job
  92. 92. 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
  93. 93. 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);
  94. 94. JVM supports multiple languages
  95. 95. same for .net framework
  96. 96. Testing is a great place to start
  97. 97. Thank you!
  98. 98. amir@barylko.com @abarylko http://bit.ly/abarylkop
  99. 99. Books
  100. 100. Books
  101. 101. Photo Credit • Under http://creativecommons.org/licenses/by/2.5/ • • 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 • • Joe Cheng, DSC_7820-01, http://flic.kr/p/2Zt2u 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
  102. 102. Photo Credit 2 • • How to write good code, http://xkcd.com/844/ Understanding flow charts, http://lifehacker.com/5909501/how-tochoose-the-best-chart-for-your-data
  103. 103. Resources • • http://www.infoq.com/news/2010/06/decision-to-refactor • • • Refactoring Catalog: http://www.refactoring.com/catalog/ http://stackoverflow.com/questions/38635/what-static-analysis-toolsare-available-for-c LambdaJ: https://code.google.com/p/lambda Coffeescript: http://coffeescript.org/
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×