SlideShare une entreprise Scribd logo
1  sur  68
Working Effectively with Legacy Code Michael Feathers [email_address]
Background ,[object Object],[object Object],if (m_nCriticalError)‏ return; m_nCriticalError=nErrorCode; switch (nEvent)‏ { case FD_READ: case FD_FORCEREAD: if (GetLayerState()==connecting && !nErrorCode)‏
First Reaction ,[object Object],[object Object],[object Object],[object Object]
Let’s Try It
PageGenerator::generate()‏ std::string PageGenerator::generate()‏ { std::vector<Result> results  = database.queryResults(beginDate, endDate); std::string pageText; pageText += &quot;<html>&quot;; pageText += &quot;<head>&quot;; pageText += &quot;<title>&quot;; pageText += &quot;Quarterly Report&quot;; pageText += &quot;</title>&quot;; pageText += &quot;</head>&quot;; pageText += &quot;<body>&quot;; pageText += &quot;<h1>&quot;; pageText += &quot;Quarterly Report&quot;; pageText += &quot;</h1><table>&quot;; …
Continued.. … if (results.size() != 0) { pageText += &quot;<table border=amp;quot;1amp;quot;>&quot;; for (std::vector<Result>::iterator it = results.begin();  it != results.end(); ++it) { pageText += &quot;<tr border=amp;quot;1amp;quot;>&quot;; pageText += &quot;<td>&quot; + it->department + &quot;</td>&quot;; pageText += &quot;<td>&quot; + it->manager + &quot;</td>&quot;; char buffer [128]; sprintf(buffer, &quot;<td>$%d</td>&quot;, it->netProfit / 100); pageText += std::string(buffer); sprintf(buffer, &quot;<td>$%d</td>&quot;, it->operatingExpense / 100); pageText += std::string(buffer); pageText += &quot;</tr>&quot;; } pageText += &quot;</table>&quot;; } else { …
Continued.. … pageText += &quot;<p>No results for this period</p>&quot;; } pageText += &quot;</body>&quot;; pageText += &quot;</html>&quot;; return pageText; } // Argh!!
Changes ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Chia Pet Pattern ,[object Object]
Why are we so Conservative? ,[object Object],[object Object]
The Refactoring Dilemma ,[object Object]
Most applications are glued together ,[object Object]
Kinds of Glue ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Breaking Dependencies ,[object Object],[object Object],[object Object]
‘ The Undetectable Side-Effect’ ,[object Object]
(told you)‏ public class AccountDetailFrame extends Frame implements ActionListener, WindowListener { private TextField display = new TextField(10); … private AccountDetailFrame(…) { … } public void performAction(ActionEvent event) { String source = (String)event.getActionCommand(); if (source.equals(“project activity”)) { DetailFrame detailDisplay = new DetailFrame(); detailDisplay.setDescription( getDetailText() + “ “ + getProjectText()); detailDisplay.show(); String accountDescription =  detailDisplay.getAccountSymbol(); accountDescription += “: “; … display.setText(accountDescription); … } }
Separate a dependency public class AccountDetailFrame extends Frame implements ActionListener, WindowListener { private TextField display = new TextField(10); … private AccountDetailFrame(…) { … } public void performAction(ActionEvent event) { String source = (String)event.getActionCommand(); if (source.equals(“project activity”)) { DetailFrame detailDisplay = new DetailFrame(); detailDisplay.setDescription( getDetailText() + “ “ + getProjectText()); detailDisplay.show(); String accountDescription =  detailDisplay.getAccountSymbol(); accountDescription += “: “; … display.setText(accountDescription); … } }
After a method extraction.. public class AccountDetailFrame extends Frame implements ActionListener, WindowListener { … public void performAction(ActionEvent event) { performCommand((String)event.getActionCommand()); } void performCommand(String source); if (source.equals(“project activity”)) { DetailFrame detailDisplay = new DetailFrame(); detailDisplay.setDescription( getDetailText() + “ “ + getProjectText()); detailDisplay.show(); String accountDescription =  detailDisplay.getAccountSymbol(); accountDescription += “: “; … display.setText(accountDescription); … } }
More offensive dependencies.. public class AccountDetailFrame extends Frame implements ActionListener, WindowListener { … void performCommand(String source); if (source.equals(“project activity”)) { DetailFrame detailDisplay = new DetailFrame(); detailDisplay.setDescription( getDetailText() + “ “ + getProjectText()); detailDisplay.show(); String accountDescription =  detailDisplay.getAccountSymbol(); accountDescription += “: “; … display.setText(accountDescription); … } }
More refactoring.. public class AccountDetailFrame extends Frame implements ActionListener, WindowListener { private TextField display = new TextField(10); private DetailFrame detailDisplay; … void performCommand(String source); if (source.equals(“project activity”)) { setDescription(getDetailText() + “” +  getProjectText()); … String accountDescripton =  getAccountSymbol(); accountDescription += “: “; … setDisplayText(accountDescription); … } } …
The aftermath.. We can subclass and override  getAccountSymbol ,  setDisplayText ,  and  setDescription  to sense our work
A Test.. public void testPerformCommand() { TestingAccountDetailFrame frame =  new TestingAccountDetailFrame(); frame.accountSymbol = “SYM”; frame.performCommand(“project activity”); assertEquals(“06 080 012”, frame.getDisplayText()); }
Classes are like cells.. ,[object Object]
Making it Better ,[object Object]
Better vs. Best ,[object Object]
Automated Tool Moves ,[object Object],[object Object]
Manual Moves ,[object Object],[object Object],[object Object]
Leaning on the Compiler ,[object Object],[object Object],[object Object],[object Object]
Signature Preservation ,[object Object],[object Object]
Single Goal Editing ,[object Object]
The Legacy Code Change Algorithm ,[object Object],[object Object],[object Object],[object Object],[object Object]
Development Speed ,[object Object],[object Object]
Breaking Dependencies 0 Extract Interface Extract Implementor
Extract Interface ,[object Object],[object Object],[object Object],[object Object]
Extract Interface ,[object Object],[object Object],[object Object]
Extract Interface Steps ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
The Non-Virtual Override Problem ,[object Object],class EventProcessor { public: void handle(Event *event); }; class MultiplexProcessor : public EventProcessor { public: void handle(Event *event); };
The Non-Virtual Override Problem ,[object Object],[object Object],[object Object],[object Object]
The Non-Virtual Override Problem ,[object Object],[object Object],[object Object],[object Object]
Extract Implementor ,[object Object]
Breaking Dependencies 1 Parameterize Method Extract and Override Call
Parameterize Method ,[object Object],[object Object],void TestCase::run() { m_result =  new TestResult; runTest(m_result); } void TestCase::run() { run(new TestResult); } void TestCase::run( TestResult *result) { m_result = result; runTest(m_result); }
Steps – Parameterize Method ,[object Object],[object Object],[object Object]
Extract and Override Call ,[object Object]
Steps – Extract and Override Call ,[object Object],[object Object],[object Object]
Breaking Dependencies 2 Link-Time Polymorphism
Link-Time Polymorphism void account_deposit(int amount)‏ { struct Call *call = (struct Call *)‏ calloc(1, sizeof (struct Call)); call->type = ACC_DEPOSIT; call->arg0 = amount; append(g_calls, call); }
Steps – Link-Time Polymorphism ,[object Object],[object Object],[object Object]
Breaking Dependencies 3 Expose Static Method
Expose Static Method ,[object Object],[object Object],class RSCWorkflow { public void validate(Packet packet) { if (packet.getOriginator() == “MIA”  || !packet.hasValidCheckSum()) { throw new InvalidFlow(); } … } }
Expose Static Method ,[object Object],[object Object],[object Object]
Expose Static Method ,[object Object],[object Object],[object Object],[object Object],[object Object]
Steps – Expose Static Method ,[object Object],[object Object],[object Object],[object Object],[object Object]
Breaking Dependencies 4 Introduce Instance Delegator
Introduce Instance Delegator ,[object Object],[object Object],static void BankingServices::updateAccountBalance( int userID,  Money amount) { … }
Introduce Instance Delegator ,[object Object],public class BankingServices { public static void updateAccountBalance( int userID,  Money amount) { … } public void updateBalance( int userID,  Money amount) { updateAccountBalance(userID, amount); } }
Steps –Introduce Instance Delegator ,[object Object],[object Object],[object Object],[object Object],[object Object]
Dependency Breaking 5 Template Redefinition
Template Redefinition ,[object Object],class AsyncReceptionPort { private: CSocket m_socket;  // bad dependency Packet m_packet; int m_segmentSize; … public: AsyncReceptionPort(); void Run(); … };
Template Redefinition template<typename SOCKET> class AsyncReceptionPortImpl { private: SOCKET m_socket; Packet m_packet; int m_segmentSize; … public: AsyncReceptionPortImpl(); void Run(); }; typedef AsyncReceptionPortImpl<CSocket> AsyncReceptionPort;
Steps – Template Redefinition ,[object Object],[object Object],[object Object],[object Object],[object Object]
Writing Tests
Characterization Testing ,[object Object],[object Object],[object Object]
Characterization Testing ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Characterization Testing Example ,[object Object],class ResidentialAccount void charge(int gallons, date readingDate){   if (billingPlan.isMonthly()) { if (gallons < RESIDENTIAL_MIN)  balance += RESIDENTIAL_BASE; else  balance += 1.2 *  priceForGallons(gallons); billingPlan.postReading(readingDate,  gallons);   } }
Characterization Testing Example ,[object Object],[object Object],if (gallons < RESIDENTIAL_MIN)  balance += RESIDENTIAL_BASE; else  balance += 1.2 *  priceForGallons(gallons); billingPlan.postReading(readingDate,  gallons);
Questions & Concerns ,[object Object],[object Object],[object Object]
WELC Understanding, Isolating,  Testing, and Changing ..Untested Code www.objectmentor.com www.michaelfeathers.com

Contenu connexe

Tendances

Introduction to object oriented programming
Introduction to object oriented programmingIntroduction to object oriented programming
Introduction to object oriented programming
Abzetdin Adamov
 
Software Testing Fundamentals
Software Testing FundamentalsSoftware Testing Fundamentals
Software Testing Fundamentals
Chankey Pathak
 
Software testing methods, levels and types
Software testing methods, levels and typesSoftware testing methods, levels and types
Software testing methods, levels and types
Confiz
 

Tendances (20)

Introduction to Automation Testing
Introduction to Automation TestingIntroduction to Automation Testing
Introduction to Automation Testing
 
Refactoring and code smells
Refactoring and code smellsRefactoring and code smells
Refactoring and code smells
 
An Introduction To REST API
An Introduction To REST APIAn Introduction To REST API
An Introduction To REST API
 
Introduction to object oriented programming
Introduction to object oriented programmingIntroduction to object oriented programming
Introduction to object oriented programming
 
Refactoring Tips by Martin Fowler
Refactoring Tips by Martin FowlerRefactoring Tips by Martin Fowler
Refactoring Tips by Martin Fowler
 
REST API testing with SpecFlow
REST API testing with SpecFlowREST API testing with SpecFlow
REST API testing with SpecFlow
 
Software Testing Fundamentals
Software Testing FundamentalsSoftware Testing Fundamentals
Software Testing Fundamentals
 
An Introduction to Test Driven Development
An Introduction to Test Driven Development An Introduction to Test Driven Development
An Introduction to Test Driven Development
 
Advance oops concepts
Advance oops conceptsAdvance oops concepts
Advance oops concepts
 
Diffing Shotgun Surgery and Divergent Change smells in the two editions of Re...
Diffing Shotgun Surgery and Divergent Change smells in the two editions of Re...Diffing Shotgun Surgery and Divergent Change smells in the two editions of Re...
Diffing Shotgun Surgery and Divergent Change smells in the two editions of Re...
 
interface in c#
interface in c#interface in c#
interface in c#
 
DevCamp - O papel de um testador em uma equipe ágil
DevCamp - O papel de um testador em uma equipe ágilDevCamp - O papel de um testador em uma equipe ágil
DevCamp - O papel de um testador em uma equipe ágil
 
Software testing methods, levels and types
Software testing methods, levels and typesSoftware testing methods, levels and types
Software testing methods, levels and types
 
Clean code
Clean codeClean code
Clean code
 
Unit Testing in Java
Unit Testing in JavaUnit Testing in Java
Unit Testing in Java
 
From Java 17 to 21- A Showcase of JDK Security Enhancements
From Java 17 to 21- A Showcase of JDK Security EnhancementsFrom Java 17 to 21- A Showcase of JDK Security Enhancements
From Java 17 to 21- A Showcase of JDK Security Enhancements
 
Code Review
Code ReviewCode Review
Code Review
 
Clean code
Clean codeClean code
Clean code
 
Automation testing
Automation testingAutomation testing
Automation testing
 
Junit
JunitJunit
Junit
 

En vedette

Club of anonimous developers "Refactoring: Legacy code"
Club of anonimous developers "Refactoring: Legacy code"Club of anonimous developers "Refactoring: Legacy code"
Club of anonimous developers "Refactoring: Legacy code"
Victor_Cr
 

En vedette (16)

XPDays Ukraine: Legacy
XPDays Ukraine: LegacyXPDays Ukraine: Legacy
XPDays Ukraine: Legacy
 
Club of anonimous developers "Refactoring: Legacy code"
Club of anonimous developers "Refactoring: Legacy code"Club of anonimous developers "Refactoring: Legacy code"
Club of anonimous developers "Refactoring: Legacy code"
 
Legacy: как победить в гонке (Joker)
Legacy: как победить в гонке (Joker)Legacy: как победить в гонке (Joker)
Legacy: как победить в гонке (Joker)
 
XP Days Ukraine 2014 - Refactoring legacy code
XP Days Ukraine 2014 - Refactoring legacy codeXP Days Ukraine 2014 - Refactoring legacy code
XP Days Ukraine 2014 - Refactoring legacy code
 
Как пишутся и поддерживаются Enterprise системы
Как пишутся и поддерживаются Enterprise системыКак пишутся и поддерживаются Enterprise системы
Как пишутся и поддерживаются Enterprise системы
 
Towards a Principle-based Classification of Structural Design Smells
Towards a Principle-based Classification of Structural Design SmellsTowards a Principle-based Classification of Structural Design Smells
Towards a Principle-based Classification of Structural Design Smells
 
SOLID Principles and Design Patterns
SOLID Principles and Design PatternsSOLID Principles and Design Patterns
SOLID Principles and Design Patterns
 
Pragmatic Technical Debt Management
Pragmatic Technical Debt ManagementPragmatic Technical Debt Management
Pragmatic Technical Debt Management
 
Infographic - Pragmatic Technical Debt Management
Infographic - Pragmatic Technical Debt ManagementInfographic - Pragmatic Technical Debt Management
Infographic - Pragmatic Technical Debt Management
 
PHAME: Principles of Hierarchy Abstraction Modularization and Encapsulation
PHAME: Principles of Hierarchy Abstraction Modularization and EncapsulationPHAME: Principles of Hierarchy Abstraction Modularization and Encapsulation
PHAME: Principles of Hierarchy Abstraction Modularization and Encapsulation
 
Why care about technical debt?
Why care about technical debt?Why care about technical debt?
Why care about technical debt?
 
A Checklist for Design Reviews
A Checklist for Design ReviewsA Checklist for Design Reviews
A Checklist for Design Reviews
 
Tools for Identifying and Addressing Technical Debt
Tools for Identifying and Addressing Technical DebtTools for Identifying and Addressing Technical Debt
Tools for Identifying and Addressing Technical Debt
 
Refactoring for Software Design Smells: Managing Technical Debt
Refactoring for Software Design Smells: Managing Technical DebtRefactoring for Software Design Smells: Managing Technical Debt
Refactoring for Software Design Smells: Managing Technical Debt
 
Tools for refactoring
Tools for refactoringTools for refactoring
Tools for refactoring
 
Applying Design Principles in Practice
Applying Design Principles in PracticeApplying Design Principles in Practice
Applying Design Principles in Practice
 

Similaire à Working Effectively With Legacy Code

Dot Net Accenture
Dot Net AccentureDot Net Accenture
Dot Net Accenture
Sri K
 

Similaire à Working Effectively With Legacy Code (20)

Stopping the Rot - Putting Legacy C++ Under Test
Stopping the Rot - Putting Legacy C++ Under TestStopping the Rot - Putting Legacy C++ Under Test
Stopping the Rot - Putting Legacy C++ Under Test
 
Clean code
Clean codeClean code
Clean code
 
CLR Exception Handing And Memory Management
CLR Exception Handing And Memory ManagementCLR Exception Handing And Memory Management
CLR Exception Handing And Memory Management
 
Grails unit testing
Grails unit testingGrails unit testing
Grails unit testing
 
Pragmatic Parallels: Java and JavaScript
Pragmatic Parallels: Java and JavaScriptPragmatic Parallels: Java and JavaScript
Pragmatic Parallels: Java and JavaScript
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
Framework Design Guidelines For Brussels Users Group
Framework Design Guidelines For Brussels Users GroupFramework Design Guidelines For Brussels Users Group
Framework Design Guidelines For Brussels Users Group
 
2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability
2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability
2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability
 
Framework engineering JCO 2011
Framework engineering JCO 2011Framework engineering JCO 2011
Framework engineering JCO 2011
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applications
 
Dot Net Accenture
Dot Net AccentureDot Net Accenture
Dot Net Accenture
 
From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)
 
C# interview-questions
C# interview-questionsC# interview-questions
C# interview-questions
 
Testing And Drupal
Testing And DrupalTesting And Drupal
Testing And Drupal
 
Coding Naked 2023
Coding Naked 2023Coding Naked 2023
Coding Naked 2023
 
Can't Dance The Lambda
Can't Dance The LambdaCan't Dance The Lambda
Can't Dance The Lambda
 
Microsoft opened the source code of Xamarin.Forms. We couldn't miss a chance ...
Microsoft opened the source code of Xamarin.Forms. We couldn't miss a chance ...Microsoft opened the source code of Xamarin.Forms. We couldn't miss a chance ...
Microsoft opened the source code of Xamarin.Forms. We couldn't miss a chance ...
 
Professional JavaScript: AntiPatterns
Professional JavaScript: AntiPatternsProfessional JavaScript: AntiPatterns
Professional JavaScript: AntiPatterns
 
SMI - Introduction to Java
SMI - Introduction to JavaSMI - Introduction to Java
SMI - Introduction to Java
 
Need 4 Speed FI
Need 4 Speed FINeed 4 Speed FI
Need 4 Speed FI
 

Plus de Naresh Jain

Organizational Resilience
Organizational ResilienceOrganizational Resilience
Organizational Resilience
Naresh Jain
 
Improving the Quality of Incoming Code
Improving the Quality of Incoming CodeImproving the Quality of Incoming Code
Improving the Quality of Incoming Code
Naresh Jain
 
Agile India 2018 Conference
Agile India 2018 ConferenceAgile India 2018 Conference
Agile India 2018 Conference
Naresh Jain
 

Plus de Naresh Jain (20)

Problem Solving Techniques For Evolutionary Design
Problem Solving Techniques For Evolutionary DesignProblem Solving Techniques For Evolutionary Design
Problem Solving Techniques For Evolutionary Design
 
Agile India 2019 Conference Welcome Note
Agile India 2019 Conference Welcome NoteAgile India 2019 Conference Welcome Note
Agile India 2019 Conference Welcome Note
 
Organizational Resilience
Organizational ResilienceOrganizational Resilience
Organizational Resilience
 
Improving the Quality of Incoming Code
Improving the Quality of Incoming CodeImproving the Quality of Incoming Code
Improving the Quality of Incoming Code
 
Agile India 2018 Conference Summary
Agile India 2018 Conference SummaryAgile India 2018 Conference Summary
Agile India 2018 Conference Summary
 
Agile India 2018 Conference
Agile India 2018 ConferenceAgile India 2018 Conference
Agile India 2018 Conference
 
Agile India 2018 Conference
Agile India 2018 ConferenceAgile India 2018 Conference
Agile India 2018 Conference
 
Agile India 2018 Conference
Agile India 2018 ConferenceAgile India 2018 Conference
Agile India 2018 Conference
 
Pilgrim's Progress to the Promised Land by Robert Virding
Pilgrim's Progress to the Promised Land by Robert VirdingPilgrim's Progress to the Promised Land by Robert Virding
Pilgrim's Progress to the Promised Land by Robert Virding
 
Concurrent languages are Functional by Francesco Cesarini
Concurrent languages are Functional by Francesco CesariniConcurrent languages are Functional by Francesco Cesarini
Concurrent languages are Functional by Francesco Cesarini
 
Erlang from behing the trenches by Francesco Cesarini
Erlang from behing the trenches by Francesco CesariniErlang from behing the trenches by Francesco Cesarini
Erlang from behing the trenches by Francesco Cesarini
 
Anatomy of an eCommerce Search Engine by Mayur Datar
Anatomy of an eCommerce Search Engine by Mayur DatarAnatomy of an eCommerce Search Engine by Mayur Datar
Anatomy of an eCommerce Search Engine by Mayur Datar
 
Setting up Continuous Delivery Culture for a Large Scale Mobile App
Setting up Continuous Delivery Culture for a Large Scale Mobile AppSetting up Continuous Delivery Culture for a Large Scale Mobile App
Setting up Continuous Delivery Culture for a Large Scale Mobile App
 
Towards FutureOps: Stable, Repeatable environments from Dev to Prod
Towards FutureOps: Stable, Repeatable environments from Dev to ProdTowards FutureOps: Stable, Repeatable environments from Dev to Prod
Towards FutureOps: Stable, Repeatable environments from Dev to Prod
 
Value Driven Development by Dave Thomas
Value Driven Development by Dave Thomas Value Driven Development by Dave Thomas
Value Driven Development by Dave Thomas
 
No Silver Bullets in Functional Programming by Brian McKenna
No Silver Bullets in Functional Programming by Brian McKennaNo Silver Bullets in Functional Programming by Brian McKenna
No Silver Bullets in Functional Programming by Brian McKenna
 
Functional Programming Conference 2016
Functional Programming Conference 2016Functional Programming Conference 2016
Functional Programming Conference 2016
 
Agile India 2017 Conference
Agile India 2017 ConferenceAgile India 2017 Conference
Agile India 2017 Conference
 
The Eclipse Way
The Eclipse WayThe Eclipse Way
The Eclipse Way
 
Unleashing the Power of Automated Refactoring with JDT
Unleashing the Power of Automated Refactoring with JDTUnleashing the Power of Automated Refactoring with JDT
Unleashing the Power of Automated Refactoring with JDT
 

Dernier

FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
dollysharma2066
 
Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...
Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...
Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...
Sheetaleventcompany
 
Quick Doctor In Kuwait +2773`7758`557 Kuwait Doha Qatar Dubai Abu Dhabi Sharj...
Quick Doctor In Kuwait +2773`7758`557 Kuwait Doha Qatar Dubai Abu Dhabi Sharj...Quick Doctor In Kuwait +2773`7758`557 Kuwait Doha Qatar Dubai Abu Dhabi Sharj...
Quick Doctor In Kuwait +2773`7758`557 Kuwait Doha Qatar Dubai Abu Dhabi Sharj...
daisycvs
 
Call Now ☎️🔝 9332606886🔝 Call Girls ❤ Service In Bhilwara Female Escorts Serv...
Call Now ☎️🔝 9332606886🔝 Call Girls ❤ Service In Bhilwara Female Escorts Serv...Call Now ☎️🔝 9332606886🔝 Call Girls ❤ Service In Bhilwara Female Escorts Serv...
Call Now ☎️🔝 9332606886🔝 Call Girls ❤ Service In Bhilwara Female Escorts Serv...
Anamikakaur10
 
Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...
Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...
Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...
lizamodels9
 
unwanted pregnancy Kit [+918133066128] Abortion Pills IN Dubai UAE Abudhabi
unwanted pregnancy Kit [+918133066128] Abortion Pills IN Dubai UAE Abudhabiunwanted pregnancy Kit [+918133066128] Abortion Pills IN Dubai UAE Abudhabi
unwanted pregnancy Kit [+918133066128] Abortion Pills IN Dubai UAE Abudhabi
Abortion pills in Kuwait Cytotec pills in Kuwait
 
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
amitlee9823
 

Dernier (20)

The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...
The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...
The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...
 
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
 
Monthly Social Media Update April 2024 pptx.pptx
Monthly Social Media Update April 2024 pptx.pptxMonthly Social Media Update April 2024 pptx.pptx
Monthly Social Media Update April 2024 pptx.pptx
 
(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7
(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7
(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7
 
MONA 98765-12871 CALL GIRLS IN LUDHIANA LUDHIANA CALL GIRL
MONA 98765-12871 CALL GIRLS IN LUDHIANA LUDHIANA CALL GIRLMONA 98765-12871 CALL GIRLS IN LUDHIANA LUDHIANA CALL GIRL
MONA 98765-12871 CALL GIRLS IN LUDHIANA LUDHIANA CALL GIRL
 
Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...
Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...
Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...
 
Quick Doctor In Kuwait +2773`7758`557 Kuwait Doha Qatar Dubai Abu Dhabi Sharj...
Quick Doctor In Kuwait +2773`7758`557 Kuwait Doha Qatar Dubai Abu Dhabi Sharj...Quick Doctor In Kuwait +2773`7758`557 Kuwait Doha Qatar Dubai Abu Dhabi Sharj...
Quick Doctor In Kuwait +2773`7758`557 Kuwait Doha Qatar Dubai Abu Dhabi Sharj...
 
Call Now ☎️🔝 9332606886🔝 Call Girls ❤ Service In Bhilwara Female Escorts Serv...
Call Now ☎️🔝 9332606886🔝 Call Girls ❤ Service In Bhilwara Female Escorts Serv...Call Now ☎️🔝 9332606886🔝 Call Girls ❤ Service In Bhilwara Female Escorts Serv...
Call Now ☎️🔝 9332606886🔝 Call Girls ❤ Service In Bhilwara Female Escorts Serv...
 
BAGALUR CALL GIRL IN 98274*61493 ❤CALL GIRLS IN ESCORT SERVICE❤CALL GIRL
BAGALUR CALL GIRL IN 98274*61493 ❤CALL GIRLS IN ESCORT SERVICE❤CALL GIRLBAGALUR CALL GIRL IN 98274*61493 ❤CALL GIRLS IN ESCORT SERVICE❤CALL GIRL
BAGALUR CALL GIRL IN 98274*61493 ❤CALL GIRLS IN ESCORT SERVICE❤CALL GIRL
 
Organizational Transformation Lead with Culture
Organizational Transformation Lead with CultureOrganizational Transformation Lead with Culture
Organizational Transformation Lead with Culture
 
How to Get Started in Social Media for Art League City
How to Get Started in Social Media for Art League CityHow to Get Started in Social Media for Art League City
How to Get Started in Social Media for Art League City
 
Business Model Canvas (BMC)- A new venture concept
Business Model Canvas (BMC)-  A new venture conceptBusiness Model Canvas (BMC)-  A new venture concept
Business Model Canvas (BMC)- A new venture concept
 
It will be International Nurses' Day on 12 May
It will be International Nurses' Day on 12 MayIt will be International Nurses' Day on 12 May
It will be International Nurses' Day on 12 May
 
Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...
Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...
Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...
 
Dr. Admir Softic_ presentation_Green Club_ENG.pdf
Dr. Admir Softic_ presentation_Green Club_ENG.pdfDr. Admir Softic_ presentation_Green Club_ENG.pdf
Dr. Admir Softic_ presentation_Green Club_ENG.pdf
 
unwanted pregnancy Kit [+918133066128] Abortion Pills IN Dubai UAE Abudhabi
unwanted pregnancy Kit [+918133066128] Abortion Pills IN Dubai UAE Abudhabiunwanted pregnancy Kit [+918133066128] Abortion Pills IN Dubai UAE Abudhabi
unwanted pregnancy Kit [+918133066128] Abortion Pills IN Dubai UAE Abudhabi
 
Falcon's Invoice Discounting: Your Path to Prosperity
Falcon's Invoice Discounting: Your Path to ProsperityFalcon's Invoice Discounting: Your Path to Prosperity
Falcon's Invoice Discounting: Your Path to Prosperity
 
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
 
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
 
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best ServicesMysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
 

Working Effectively With Legacy Code

  • 1. Working Effectively with Legacy Code Michael Feathers [email_address]
  • 2.
  • 3.
  • 5. PageGenerator::generate()‏ std::string PageGenerator::generate()‏ { std::vector<Result> results = database.queryResults(beginDate, endDate); std::string pageText; pageText += &quot;<html>&quot;; pageText += &quot;<head>&quot;; pageText += &quot;<title>&quot;; pageText += &quot;Quarterly Report&quot;; pageText += &quot;</title>&quot;; pageText += &quot;</head>&quot;; pageText += &quot;<body>&quot;; pageText += &quot;<h1>&quot;; pageText += &quot;Quarterly Report&quot;; pageText += &quot;</h1><table>&quot;; …
  • 6. Continued.. … if (results.size() != 0) { pageText += &quot;<table border=amp;quot;1amp;quot;>&quot;; for (std::vector<Result>::iterator it = results.begin(); it != results.end(); ++it) { pageText += &quot;<tr border=amp;quot;1amp;quot;>&quot;; pageText += &quot;<td>&quot; + it->department + &quot;</td>&quot;; pageText += &quot;<td>&quot; + it->manager + &quot;</td>&quot;; char buffer [128]; sprintf(buffer, &quot;<td>$%d</td>&quot;, it->netProfit / 100); pageText += std::string(buffer); sprintf(buffer, &quot;<td>$%d</td>&quot;, it->operatingExpense / 100); pageText += std::string(buffer); pageText += &quot;</tr>&quot;; } pageText += &quot;</table>&quot;; } else { …
  • 7. Continued.. … pageText += &quot;<p>No results for this period</p>&quot;; } pageText += &quot;</body>&quot;; pageText += &quot;</html>&quot;; return pageText; } // Argh!!
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16. (told you)‏ public class AccountDetailFrame extends Frame implements ActionListener, WindowListener { private TextField display = new TextField(10); … private AccountDetailFrame(…) { … } public void performAction(ActionEvent event) { String source = (String)event.getActionCommand(); if (source.equals(“project activity”)) { DetailFrame detailDisplay = new DetailFrame(); detailDisplay.setDescription( getDetailText() + “ “ + getProjectText()); detailDisplay.show(); String accountDescription = detailDisplay.getAccountSymbol(); accountDescription += “: “; … display.setText(accountDescription); … } }
  • 17. Separate a dependency public class AccountDetailFrame extends Frame implements ActionListener, WindowListener { private TextField display = new TextField(10); … private AccountDetailFrame(…) { … } public void performAction(ActionEvent event) { String source = (String)event.getActionCommand(); if (source.equals(“project activity”)) { DetailFrame detailDisplay = new DetailFrame(); detailDisplay.setDescription( getDetailText() + “ “ + getProjectText()); detailDisplay.show(); String accountDescription = detailDisplay.getAccountSymbol(); accountDescription += “: “; … display.setText(accountDescription); … } }
  • 18. After a method extraction.. public class AccountDetailFrame extends Frame implements ActionListener, WindowListener { … public void performAction(ActionEvent event) { performCommand((String)event.getActionCommand()); } void performCommand(String source); if (source.equals(“project activity”)) { DetailFrame detailDisplay = new DetailFrame(); detailDisplay.setDescription( getDetailText() + “ “ + getProjectText()); detailDisplay.show(); String accountDescription = detailDisplay.getAccountSymbol(); accountDescription += “: “; … display.setText(accountDescription); … } }
  • 19. More offensive dependencies.. public class AccountDetailFrame extends Frame implements ActionListener, WindowListener { … void performCommand(String source); if (source.equals(“project activity”)) { DetailFrame detailDisplay = new DetailFrame(); detailDisplay.setDescription( getDetailText() + “ “ + getProjectText()); detailDisplay.show(); String accountDescription = detailDisplay.getAccountSymbol(); accountDescription += “: “; … display.setText(accountDescription); … } }
  • 20. More refactoring.. public class AccountDetailFrame extends Frame implements ActionListener, WindowListener { private TextField display = new TextField(10); private DetailFrame detailDisplay; … void performCommand(String source); if (source.equals(“project activity”)) { setDescription(getDetailText() + “” + getProjectText()); … String accountDescripton = getAccountSymbol(); accountDescription += “: “; … setDisplayText(accountDescription); … } } …
  • 21. The aftermath.. We can subclass and override getAccountSymbol , setDisplayText , and setDescription to sense our work
  • 22. A Test.. public void testPerformCommand() { TestingAccountDetailFrame frame = new TestingAccountDetailFrame(); frame.accountSymbol = “SYM”; frame.performCommand(“project activity”); assertEquals(“06 080 012”, frame.getDisplayText()); }
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33. Breaking Dependencies 0 Extract Interface Extract Implementor
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41. Breaking Dependencies 1 Parameterize Method Extract and Override Call
  • 42.
  • 43.
  • 44.
  • 45.
  • 46. Breaking Dependencies 2 Link-Time Polymorphism
  • 47. Link-Time Polymorphism void account_deposit(int amount)‏ { struct Call *call = (struct Call *)‏ calloc(1, sizeof (struct Call)); call->type = ACC_DEPOSIT; call->arg0 = amount; append(g_calls, call); }
  • 48.
  • 49. Breaking Dependencies 3 Expose Static Method
  • 50.
  • 51.
  • 52.
  • 53.
  • 54. Breaking Dependencies 4 Introduce Instance Delegator
  • 55.
  • 56.
  • 57.
  • 58. Dependency Breaking 5 Template Redefinition
  • 59.
  • 60. Template Redefinition template<typename SOCKET> class AsyncReceptionPortImpl { private: SOCKET m_socket; Packet m_packet; int m_segmentSize; … public: AsyncReceptionPortImpl(); void Run(); }; typedef AsyncReceptionPortImpl<CSocket> AsyncReceptionPort;
  • 61.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68. WELC Understanding, Isolating, Testing, and Changing ..Untested Code www.objectmentor.com www.michaelfeathers.com

Notes de l'éditeur

  1. Notes 2/5/2004 Michael Feathers