Working with Legacy Code: Lessons in Practice
Transcript of Working with Legacy Code: Lessons in Practice
![Page 1: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/1.jpg)
Working Effec-vely with Legacy Code
Lessons in Prac-ce
![Page 2: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/2.jpg)
The Book
by Michael C. Feathers
published 2004
foreword by “Uncle Bob” Mar-n
influenced by Mar-n Fowler’s Refactoring
![Page 3: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/3.jpg)
What is Legacy Code?
• “difficult to change code that I don’t understand” • “code wriNen a long -me ago” • “code that somebody else wrote”
![Page 4: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/4.jpg)
Refactor Add Feature Fix Bug Op4mize Structure Changes Changes Changes New Behavior Changes Exis-ng Behavior Changes Resource Usage Changes
because SoTware is Never Done
Why do I need to understand the code?
![Page 5: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/5.jpg)
What is Legacy Code?
“Code Without Tests”
![Page 6: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/6.jpg)
Two Methods of SoTware Development
“Edit and Pray” vs.
“Cover and Modify” which brings us to…
![Page 7: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/7.jpg)
The Legacy Code Dilemma
“When we change code, we should have tests in place.”
“To put tests in place,
we oTen have to change code.” (But why?)
![Page 8: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/8.jpg)
Legacy Code Change Algorithm
1. Iden-fy Change Point
2. Find Test Point
3. Break Dependency
4. Write Tests
5. Change and Refactor
![Page 9: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/9.jpg)
Seams
Exchangeable Behavior + an Enabling Point. Seams let you subs7tute one behavior for another by edi-ng only at the enabling point. Seams let you introduce test collaborators.
![Page 10: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/10.jpg)
Object Seams
Most useful type of seam for OOP. Another way of talking about polymorphism.
Code without seam Code with seam
![Page 11: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/11.jpg)
In the Wild
instead of
No Tests == No Up-‐to-‐Date Documenta-on
![Page 12: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/12.jpg)
In the Wild
Duplicate Code
![Page 13: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/13.jpg)
In the Wild
Long, Procedural Methods
def generate_pdf
end
![Page 14: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/14.jpg)
In the Wild
Stateful Programming • Keeping Track of Flags • HTTP Session Abuse
![Page 15: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/15.jpg)
In the Wild
Curse of MVC • Fat Models, Fat Controllers • Overloaded Responsibili-es
![Page 16: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/16.jpg)
So Many Problems
Chapter 6: “I Don’t Have Much Time and I Have to Change It”
Chapter 8: “It Takes Forever to Make a Change”
Chapter 10: “I Can’t Run This Method in a Test”
Chapter 16: “I Don’t Understand the Code Well Enough To Change It”
Chapter 17: “My Applica-on Has No Structure”
Chapter 19: “My Project Is Not Object Oriented. How Do I Make Safe Changes?
Chapter 20: “This Class Is Too Big and I Don’t Want It to Get Any Bigger”
![Page 17: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/17.jpg)
This Class is Too Big
Methods defined on Job:
![Page 18: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/18.jpg)
Single Responsibility Principle
“Every class should have a single responsibility: It should have a single purpose in the system, and there should be only one reason to change it.”
![Page 19: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/19.jpg)
Seeing Responsibili-es
Group Methods
![Page 20: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/20.jpg)
Seeing Responsibili-es
Effect Sketch: Show Internal Rela-onships
![Page 21: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/21.jpg)
Seeing Responsibili-es
Primary Responsibility “Job presents damper inspec-on data in report form.” “Job generates files of reports.” “Job deletes report files.” “Job produces graphs of damper inspec-on data.” “Job persists and retrieves representa-ons of jobs in a database.”
![Page 22: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/22.jpg)
Iden-fy Change Point
We want to refactor Job to extract Reporter.
1. Iden-fy Change Point
2. Find Test Point
3. Break Dependency
4. Write Tests
5. Change and Refactor
![Page 23: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/23.jpg)
Find Test Point Intercep-on Points Higher Level Tes-ng
– don’t have to break dependencies – verifies that your feature actually works – slow, inconvenient – hard to automate – not tes-ng in isola-on
Progressive Strategy
1. Iden-fy Change Point
2. Find Test Point
3. Break Dependency
4. Write Tests
5. Change and Refactor
![Page 24: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/24.jpg)
Break Dependencies
Required for unit tes-ng. Less necessary for higher-‐level tes-ng. We’re gonna skip it (but just this -me).
1. Iden-fy Change Point
2. Find Test Point
3. Break Dependency
4. Write Tests
5. Change and Refactor
![Page 25: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/25.jpg)
Write Tests
“Tes-ng” in the Interac-ve Console:
1. Iden-fy Change Point
2. Find Test Point
3. Break Dependency
4. Write Tests
5. Change and Refactor
![Page 26: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/26.jpg)
Change and Refactor
This was harder than it looks.
1. Iden-fy Change Point
2. Find Test Point
3. Break Dependency
4. Write Tests
5. Change and Refactor
![Page 27: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/27.jpg)
Refactored Code
Five different extracted classes
(plus two more)
![Page 28: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/28.jpg)
Extract Class…Again
![Page 29: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/29.jpg)
BeNer With Seam? We can add a seam by injec-ng the dependency on the reporter.
This way, we can test in isola-on by passing in a FakeReporter.
Unfortunately, this makes our produc-on code ugly:
![Page 30: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/30.jpg)
Seams Everywhere
![Page 31: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/31.jpg)
Legacy Code Ain’t So Bad
• No writer’s block. • Learn as you go. • Easy scapegoat! • Unavoidable, so learn to love it.
![Page 32: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/32.jpg)
Thanks J
Working Effec7vely with Legacy Code
Michael Feathers Amar Shah @amar47shah
![Page 33: Working with Legacy Code: Lessons in Practice](https://reader030.fdocuments.us/reader030/viewer/2022032514/55d765c0bb61eb977d8b4628/html5/thumbnails/33.jpg)
because SoTware is Never Done
Refactor to Remove Demeter Viola-on