Working Effectively with Legacy Code (draft)

2,362 views

Published on

Something I read on that book.

Published in: Technology, Education
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,362
On SlideShare
0
From Embeds
0
Number of Embeds
27
Actions
Shares
0
Downloads
0
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide
  • M
  • 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>

    ×