Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Working Effectively with Legacy Code (draft)

2,506 views

Published on

Something I read on that book.

Published in: Technology, Education

Working Effectively with Legacy Code (draft)

  1. 1. Working Effectively with Legacy Code written by Michael Feathers Something I understand about the book
  2. 2. Contents <ul><li>The Book </li></ul><ul><li>Definition of Legacy Code </li></ul><ul><li>Problems of the Conservative Approach </li></ul><ul><li>The Automatic Test Approach </li></ul><ul><li>Example of Characterization Test </li></ul><ul><li>Breaking Dependencies (not yet ready) </li></ul><ul><li>Seams (not yet ready) </li></ul><ul><li>Conclusion: the complaints/solutions matrix </li></ul>
  3. 3. The Book <ul><li>Robert C. Martin Series </li></ul><ul><li>Michael C. Feathers </li></ul>http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052 Paperback:  456 pages Publisher:  Prentice Hall PTR; 1 edition (October 2, 2004)
  4. 4. What is legacy code? (for me/us?) <ul><li>Code that: </li></ul><ul><ul><li>is difficult to understand </li></ul></ul><ul><ul><li>is fragile </li></ul></ul><ul><ul><li>is difficult to modify </li></ul></ul><ul><ul><li>is not (or not well) documented </li></ul></ul><ul><ul><li>has been inherited from others </li></ul></ul><ul><li>But that : </li></ul><ul><ul><li>is still useful! </li></ul></ul>
  5. 5. What is legacy code? (M.Feathers) <ul><li>M.Feathers says: </li></ul><ul><li>Legacy Code ≡ Code without automatic tests </li></ul><ul><li>Why? </li></ul>
  6. 6. The conservative approach <ul><li>No automatic tests </li></ul><ul><li>leads to </li></ul><ul><li>Manual testing </li></ul><ul><li>that leads to </li></ul><ul><li>High risk of introduce bugs </li></ul><ul><li>that leads to </li></ul><ul><li>Fear of change </li></ul><ul><li>so </li></ul><ul><li>You prefer add more mess instead cleaning up the existing code </li></ul><ul><li>and </li></ul><ul><li>the code get worse, </li></ul><ul><li>the cost/time of adding features increases </li></ul>If it ain't broke don't fix it
  7. 7. Preserving Behaviour with Characterization Tests <ul><li>Write tests for an existings program </li></ul><ul><li>Write a test that “Describe” the actual behaviour </li></ul><ul><li>Use these test as regression tests during the refactoring/feature addition. </li></ul>Please note that: “actual” is not always the same as “correct”.
  8. 8. Characterization Tests Example (1/5) <ul><li>public static int[] slaDjcl(double djm) </li></ul><ul><li>{ </li></ul><ul><li>long ld, jd, n4, nd10; </li></ul><ul><li>if ((djm <= -2395520.0) || (djm >= 1e9)) </li></ul><ul><li>{ </li></ul><ul><li>throw new IllegalArgumentException(&quot;MJD out of valid range&quot;); </li></ul><ul><li>} </li></ul><ul><li>ld = (long) djm; </li></ul><ul><li>jd = ld + 2400001L; </li></ul><ul><li>n4 = 4L * (jd + ((6L * ((4L * jd - 17918L) / 146097L)) / 4L + 1L) / 2L - 37L); </li></ul><ul><li>nd10 = 10L * (((n4 - 237L) % 1461L) / 4L) + 5L; </li></ul><ul><li>int[] ret = new int[3]; </li></ul><ul><li>ret[0] = (int) (n4 / 1461L - 4712L); </li></ul><ul><li>ret[1] = (int) (((nd10 / 306L + 2L) % 12L) + 1L); </li></ul><ul><li>ret[2] = (int) ((nd10 % 306L) / 10L + 1L); </li></ul><ul><li>return ret; </li></ul><ul><li>} </li></ul>
  9. 9. Characterization Tests Example (2/5) <ul><li>@Test </li></ul><ul><li>public void testSlaDjcl() { </li></ul><ul><li>assertArrayEquals(new int[]{},slaDjcl(0.0)); </li></ul><ul><li>} </li></ul>Testcase: testSlaDjcl(prova.ProvaTest): FAILED array lengths differed, expected.length=0 actual.length=3 junit.framework.AssertionFailedError: array lengths differed, expected.length=0 actual.length=3 at prova.ProvaTest.testSlaDjcl(ProvaTest.java:19)
  10. 10. Characterization Tests Example (3/5) <ul><li>@Test </li></ul><ul><li>public void testSlaDjcl() { </li></ul><ul><li>assertArrayEquals(new int[]{0,0,0},slaDjcl(0.0)); </li></ul><ul><li>} </li></ul>Testcase: testSlaDjcl(prova.ProvaTest): Caused an ERROR arrays first differed at element [0]; expected:<0> but was:<1858> arrays first differed at element [0]; expected:<0> but was:<1858> at prova.ProvaTest.testSlaDjcl(ProvaTest.java:19)
  11. 11. Characterization Tests Example (4/5) <ul><li>@Test </li></ul><ul><li>public void testSlaDjcl() { </li></ul><ul><li>assertArrayEquals(new int[]{1858,11,17},slaDjcl(0.0)); </li></ul><ul><li>} </li></ul>BUILD SUCCESSFUL (total time: 0 seconds)
  12. 12. Characterization Tests Example (5/5) <ul><li>@Test </li></ul><ul><li>public void testSlaDjcl() { </li></ul><ul><li>assertArrayEquals(new int[]{1858,11,17},slaDjcl(0.0)); </li></ul><ul><li>assertArrayEquals(new int[]{-3617, 1, 24},slaDjcl(-2000000.0)); </li></ul><ul><li>assertArrayEquals(new int[]{10346, 5, 23},slaDjcl(3100000.0)); </li></ul><ul><li>assertArrayEquals(new int[]{24309, 9, 19},slaDjcl(8200000.0)); </li></ul><ul><li>assertArrayEquals(new int[]{38273, 1, 15},slaDjcl(1.33E7)); </li></ul><ul><li>assertArrayEquals(new int[]{52236, 5, 14},slaDjcl(1.84E7)); </li></ul><ul><li>assertArrayEquals(new int[]{66199, 9, 10},slaDjcl(2.35E7)); </li></ul><ul><li>assertArrayEquals(new int[]{80163, 1, 7},slaDjcl(2.86E7)); </li></ul><ul><li>assertArrayEquals(new int[]{94126, 5, 6},slaDjcl(3.37E7)); </li></ul><ul><li>assertArrayEquals(new int[]{108089, 9, 1},slaDjcl(3.88E7)); </li></ul><ul><li>assertArrayEquals(new int[]{122052, 12, 29},slaDjcl(4.39E7)); </li></ul><ul><li>assertArrayEquals(new int[]{136016, 4, 27},slaDjcl(4.9E7)); </li></ul><ul><li>assertArrayEquals(new int[]{149979, 8, 25},slaDjcl(5.41E7)); </li></ul><ul><li>assertArrayEquals(new int[]{163942, 12, 22},slaDjcl(5.92E7)); </li></ul><ul><li>assertArrayEquals(new int[]{177906, 4, 20},slaDjcl(6.43E7)); </li></ul><ul><li>assertArrayEquals(new int[]{191869, 8, 16},slaDjcl(6.94E7)); </li></ul><ul><li>assertArrayEquals(new int[]{205832, 12, 13},slaDjcl(7.45E7)); </li></ul><ul><li>assertArrayEquals(new int[]{219796, 4, 10},slaDjcl(7.96E7)); </li></ul><ul><li>assertArrayEquals(new int[]{233759, 8, 8},slaDjcl(8.47E7)); </li></ul><ul><li>assertArrayEquals(new int[]{247722, 12, 5},slaDjcl(8.98E7)); </li></ul><ul><li>assertArrayEquals(new int[]{261686, 4, 2},slaDjcl(9.49E7)); </li></ul><ul><li>} </li></ul>
  13. 13. The TDD algorithm <ul><li>0. Get the class you want to change under test. </li></ul><ul><li>1. Write a failing test case. </li></ul><ul><li>2. Get it to compile. </li></ul><ul><li>3. Make it pass. (Try not to change existing code as you do this.) </li></ul><ul><li>4. Remove duplication. </li></ul><ul><li>5. Repeat. </li></ul>
  14. 14. Conclusions: Complaints / Solutions matrix So then you ... But legacy code… add them (as characterization tests) lacks of test redesign it (with refactoring) is ugly
  15. 15. Conclusions: I can’t put code under tests because So you I can’t because code <ul><li>Break Depedencies </li></ul><ul><li>Use the seams </li></ul>depends of everything <ul><li>Introduce sensing variabiles </li></ul><ul><li>Use exract method (safe version) </li></ul>lacks of modularity
  16. 16. Thanks <ul><li>Andrea Francia </li></ul><ul><ul><li>http://andrefrancia.it/ </li></ul></ul><ul><ul><li>http://blog.andreafrancia.it </li></ul></ul><ul><ul><li>[email_address] </li></ul></ul><ul><li>These slide will be available at my blog. </li></ul>

×