SlideShare a Scribd company logo
Working Effectively with Legacy Code – Part I -ShriKantVashishtha Aug 19, 2009
Four Reasons to Change Software Adding a feature Fixing a bug Improving the design Optimizing resource usage
A Legacy Code Scenario What changes do we have to make? How will we know that we have done them correctly How will we know that we haven’t broken anything Avoiding change is a bad thing, but what is our alternative? Try harder. Hire more people
Way of doing changes - Edit and Pray
Way of doing changes - Cover and Modify
Why Unit Tests Are Important? Error localization Execution time Coverage
A Typical Legacy Code Sample
Legacy Code Dilemma When we change code, we should have tests in place. To put tests in place, we often have to change code. Use Primitivize Parameter and Extract Interface to remove these issues
Fake Objects
Fake Objects
Fake objects Support Real Tests public class FakeDisplay implements Display {     private String lastLine = "";     public void showLine(String line) { lastLine = line;     }     public String getLastLine() {         return lastLine;     } } import junit.framework.*; public class SaleTest extends TestCase {     public void testDisplayAnItem() { FakeDisplay display = new FakeDisplay();         Sale sale = new Sale(display); sale.scan("1"); assertEquals("Milk $3.99", display.getLastLine());     } }
Seams boolCAsyncSslRec::Init() {     …     if (!m_bFailureSent) { m_bFailureSent=TRUE; PostReceiveError(SOCKETCALLBACK, SSL_FAILURE);     } CreateLibrary(m_hSslDll1,"syncesel1.dll"); CreateLibrary(m_hSslDll2,"syncesel2.dll");     ….     return true; }
Object Seam class CAsyncSslRec {     ...     virtual void PostReceiveError(UINT type, UINT errorcode);     ... }; class TestingAsyncSslRec : public CAsyncSslRec {     virtual void PostReceiveError(UINT type, UINT errorcode)     {     } };
Seam Types Preprocessing Seams Link Seams : static linking in C/C++/Flex and dynamic linking in Java Object Seams
I Don't Have Much Time and I Have to Change It Sprout Method Sprout Class Wrap Method Wrap Class
Sprout Method public class TransactionGate {     public void postEntries(List entries) {         for (Iterator it = entries.iterator(); it.hasNext(); ) {             Entry entry = (Entry)it.next(); entry.postDate();         } transactionBundle.getListManager().add(entries);     }     ... }
Sprout Method public class TransactionGate {     public void postEntries(List entries) {         List entriesToAdd = new LinkedList();         for (Iterator it = entries.iterator(); it.hasNext(); ) {             Entry entry = (Entry)it.next();    if (!transactionBundle.getListManager().hasEntry(entry) { entry.postDate(); entriesToAdd.add(entry);             }         } transactionBundle.getListManager().add(entriesToAdd);     }     ... }
Sprout Method public class TransactionGate {     ...     List uniqueEntries(List entries) {         List result = new ArrayList();         for (Iterator it = entries.iterator(); it.hasNext(); ) {             Entry entry = (Entry)it.next();             if (!transactionBundle.getListManager().hasEntry(entry) { result.add(entry);             }         }         return result;     }     ... } public class TransactionGate {     ...     public void postEntries(List entries) {         List entriesToAdd = uniqueEntries(entries);         for (Iterator it = entriesToAdd.iterator(); it.hasNext(); ) {             Entry entry = (Entry)it.next(); entry.postDate();         } transactionBundle.getListManager().add(entriesToAdd);     }     ... }
Sprout Class std::string QuarterlyReportGenerator::generate() {     std::vector<Result> results = database.queryResults( beginDate, endDate);     std::string pageText; pageText += "<html><head><title>"             "Quarterly Report"             "</title></head><body><table>";     if (results.size() != 0) {         for (std::vector<Result>::iterator it = results.begin();                 it != results.end();                 ++it) { pageText += "<tr>"; pageText += "<td>" + it->department + "</td>"; pageText += "<td>" + it->manager + "</td>";             char buffer [128]; sprintf(buffer, "<td>$%d</td>", it->netProfit / 100); pageText += std::string(buffer); sprintf(buffer, "<td>$%d</td>", it->operatingExpense / 100); pageText += std::string(buffer); pageText += "</tr>";         }     } else { pageText += "No results for this period";     } pageText += "</table>"; pageText += "</body>"; pageText += "</html>";     return pageText; }
Wrap Method public class Employee {     ...     public void pay() {         Money amount = new Money();         for (Iterator it = timecards.iterator(); it.hasNext(); ) {             Timecard card = (Timecard)it.next();             if (payPeriod.contains(date)) { amount.add(card.getHours() * payRate);             }         } payDispatcher.pay(this, date, amount);     } }
Wrap Method public class Employee {     private void dispatchPayment() {         Money amount = new Money();         for (Iterator it = timecards.iterator(); it.hasNext(); ) {             Timecard card = (Timecard)it.next();             if (payPeriod.contains(date)) { amount.add(card.getHours() * payRate);             }         } payDispatcher.pay(this, date, amount);     }     public void pay() { logPayment(); dispatchPayment();     }     private void logPayment() {     ...     } }
Wrap Method Advantages A good way of getting new, tested functionality into an application when we can't easily write tests for the calling code It explicitly makes the new functionality independent of existing functionality Disadvantages Can lead to poor names
Wrap Class class Employee {     public void pay() {         Money amount = new Money();         for (Iterator it = timecards.iterator(); it.hasNext(); ) {             Timecard card = (Timecard)it.next();             if (payPeriod.contains(date)) { amount.add(card.getHours() * payRate);             }         } payDispatcher.pay(this, date, amount);     }     ... }
Wrap Class class LoggingEmployee extends Employee {     public LoggingEmployee(Employee e) {         employee = e;     }     public void pay() { logPayment(); employee.pay();     }     private void logPayment() {         ...     }     ... }
Wrap Class class LoggingPayDispatcher {     private Employee e;     public LoggingPayDispatcher(Employee e) { this.e  = e;     }     public void pay() { employee.pay(); logPayment();     }     private void logPayment() {         ...     }     ... }
Wrap Class Able to add new behavior into a system without adding it to an existing class When there are many calls to the code you want to wrap, it often pays to move toward a decorator-ish wrapper If new behavior has to happen at couple of places, simple class wrapper is very useful
I Don't Have Much Time and I Have to Change It: Summary Use Sprout Method when the code you have in the existing method communicates a clear algorithm to the reader.  Use Wrap Method when you think that the new feature you’re adding is as important as the work that was there before Use Wrap Class when the behavior that I want to add is completely independent

More Related Content

What's hot

High performance web programming with C++14
High performance web programming with C++14High performance web programming with C++14
High performance web programming with C++14
Matthieu Garrigues
 
Is your C# optimized
Is your C# optimizedIs your C# optimized
Is your C# optimizedWoody Pewitt
 
Operator overloading2
Operator overloading2Operator overloading2
Operator overloading2
zindadili
 
Automatically Describing Program Structure and Behavior (PhD Defense)
Automatically Describing Program Structure and Behavior (PhD Defense)Automatically Describing Program Structure and Behavior (PhD Defense)
Automatically Describing Program Structure and Behavior (PhD Defense)Ray Buse
 
81818088 isc-class-xii-computer-science-project-java-programs
81818088 isc-class-xii-computer-science-project-java-programs81818088 isc-class-xii-computer-science-project-java-programs
81818088 isc-class-xii-computer-science-project-java-programsAbhishek Jena
 
Антихрупкий TypeScript | Odessa Frontend Meetup #17
Антихрупкий TypeScript | Odessa Frontend Meetup #17Антихрупкий TypeScript | Odessa Frontend Meetup #17
Антихрупкий TypeScript | Odessa Frontend Meetup #17
OdessaFrontend
 
FP 201 - Unit 3 Part 2
FP 201 - Unit 3 Part 2FP 201 - Unit 3 Part 2
FP 201 - Unit 3 Part 2rohassanie
 
Java Simple Programs
Java Simple ProgramsJava Simple Programs
Java Simple Programs
Upender Upr
 
The secret unit testing tools no one ever told you about
The secret unit testing tools no one ever told you aboutThe secret unit testing tools no one ever told you about
The secret unit testing tools no one ever told you about
Dror Helper
 
Computer science project work
Computer science project workComputer science project work
Computer science project work
rahulchamp2345
 
DSU C&C++ Practical File Diploma
DSU C&C++ Practical File DiplomaDSU C&C++ Practical File Diploma
DSU C&C++ Practical File Diploma
mustkeem khan
 
FP 201 - Unit 6
FP 201 - Unit 6FP 201 - Unit 6
FP 201 - Unit 6rohassanie
 
Automatically Documenting Program Changes
Automatically Documenting Program ChangesAutomatically Documenting Program Changes
Automatically Documenting Program Changes
Ray Buse
 
Lambda Expressions in C++
Lambda Expressions in C++Lambda Expressions in C++
Lambda Expressions in C++
Patrick Viafore
 
C# console programms
C# console programmsC# console programms
C# console programms
Yasir Khan
 
C programs
C programsC programs
C programs
Vikram Nandini
 

What's hot (20)

High performance web programming with C++14
High performance web programming with C++14High performance web programming with C++14
High performance web programming with C++14
 
Is your C# optimized
Is your C# optimizedIs your C# optimized
Is your C# optimized
 
Operator overloading2
Operator overloading2Operator overloading2
Operator overloading2
 
Automatically Describing Program Structure and Behavior (PhD Defense)
Automatically Describing Program Structure and Behavior (PhD Defense)Automatically Describing Program Structure and Behavior (PhD Defense)
Automatically Describing Program Structure and Behavior (PhD Defense)
 
81818088 isc-class-xii-computer-science-project-java-programs
81818088 isc-class-xii-computer-science-project-java-programs81818088 isc-class-xii-computer-science-project-java-programs
81818088 isc-class-xii-computer-science-project-java-programs
 
Антихрупкий TypeScript | Odessa Frontend Meetup #17
Антихрупкий TypeScript | Odessa Frontend Meetup #17Антихрупкий TypeScript | Odessa Frontend Meetup #17
Антихрупкий TypeScript | Odessa Frontend Meetup #17
 
FP 201 - Unit 3 Part 2
FP 201 - Unit 3 Part 2FP 201 - Unit 3 Part 2
FP 201 - Unit 3 Part 2
 
Java Simple Programs
Java Simple ProgramsJava Simple Programs
Java Simple Programs
 
The secret unit testing tools no one ever told you about
The secret unit testing tools no one ever told you aboutThe secret unit testing tools no one ever told you about
The secret unit testing tools no one ever told you about
 
Computer science project work
Computer science project workComputer science project work
Computer science project work
 
Simple Java Programs
Simple Java ProgramsSimple Java Programs
Simple Java Programs
 
DSU C&C++ Practical File Diploma
DSU C&C++ Practical File DiplomaDSU C&C++ Practical File Diploma
DSU C&C++ Practical File Diploma
 
FP 201 - Unit 6
FP 201 - Unit 6FP 201 - Unit 6
FP 201 - Unit 6
 
Automatically Documenting Program Changes
Automatically Documenting Program ChangesAutomatically Documenting Program Changes
Automatically Documenting Program Changes
 
Lambda Expressions in C++
Lambda Expressions in C++Lambda Expressions in C++
Lambda Expressions in C++
 
C# console programms
C# console programmsC# console programms
C# console programms
 
Fp201 unit5 1
Fp201 unit5 1Fp201 unit5 1
Fp201 unit5 1
 
C program
C programC program
C program
 
Bijender (1)
Bijender (1)Bijender (1)
Bijender (1)
 
C programs
C programsC programs
C programs
 

Similar to Working effectively with legacy code

SystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummarySystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features Summary
Amal Khailtash
 
Category theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) DataCategory theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) Data
greenwop
 
Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#
Juan Pablo
 
Practices For Becoming A Better Programmer
Practices For Becoming A Better ProgrammerPractices For Becoming A Better Programmer
Practices For Becoming A Better Programmer
Srikanth Shreenivas
 
20.1 Java working with abstraction
20.1 Java working with abstraction20.1 Java working with abstraction
20.1 Java working with abstraction
Intro C# Book
 
Clean Code: Chapter 3 Function
Clean Code: Chapter 3 FunctionClean Code: Chapter 3 Function
Clean Code: Chapter 3 Function
Kent Huang
 
Chapter 2
Chapter 2Chapter 2
Ruslan Platonov - Transactions
Ruslan Platonov - TransactionsRuslan Platonov - Transactions
Ruslan Platonov - TransactionsDmitry Buzdin
 
Clean code _v2003
 Clean code _v2003 Clean code _v2003
Clean code _v2003
R696
 
Embedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for JavaEmbedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for JavaJevgeni Kabanov
 
Liferay Training Struts Portlet
Liferay Training Struts PortletLiferay Training Struts Portlet
Liferay Training Struts PortletSaikrishna Basetti
 
JDD 2016 - Sebastian Malaca - You Dont Need Unit Tests
JDD 2016 - Sebastian Malaca - You Dont Need Unit TestsJDD 2016 - Sebastian Malaca - You Dont Need Unit Tests
JDD 2016 - Sebastian Malaca - You Dont Need Unit Tests
PROIDEA
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every day
Vadym Khondar
 
Rx workshop
Rx workshopRx workshop
Rx workshop
Ryan Riley
 
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Skills Matter
 
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#Mark Needham
 
Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8
RichardWarburton
 

Similar to Working effectively with legacy code (20)

SystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummarySystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features Summary
 
Category theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) DataCategory theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) Data
 
Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#
 
Java Generics
Java GenericsJava Generics
Java Generics
 
Practices For Becoming A Better Programmer
Practices For Becoming A Better ProgrammerPractices For Becoming A Better Programmer
Practices For Becoming A Better Programmer
 
20.1 Java working with abstraction
20.1 Java working with abstraction20.1 Java working with abstraction
20.1 Java working with abstraction
 
Anti patterns
Anti patternsAnti patterns
Anti patterns
 
Clean Code: Chapter 3 Function
Clean Code: Chapter 3 FunctionClean Code: Chapter 3 Function
Clean Code: Chapter 3 Function
 
Chapter 2
Chapter 2Chapter 2
Chapter 2
 
Ruslan Platonov - Transactions
Ruslan Platonov - TransactionsRuslan Platonov - Transactions
Ruslan Platonov - Transactions
 
Clean code _v2003
 Clean code _v2003 Clean code _v2003
Clean code _v2003
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
Embedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for JavaEmbedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for Java
 
Liferay Training Struts Portlet
Liferay Training Struts PortletLiferay Training Struts Portlet
Liferay Training Struts Portlet
 
JDD 2016 - Sebastian Malaca - You Dont Need Unit Tests
JDD 2016 - Sebastian Malaca - You Dont Need Unit TestsJDD 2016 - Sebastian Malaca - You Dont Need Unit Tests
JDD 2016 - Sebastian Malaca - You Dont Need Unit Tests
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every day
 
Rx workshop
Rx workshopRx workshop
Rx workshop
 
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
 
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
 
Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8
 

More from ShriKant Vashishtha

Evolution of Agile world with Lean Startup Concepts
 Evolution of Agile world with Lean Startup Concepts Evolution of Agile world with Lean Startup Concepts
Evolution of Agile world with Lean Startup Concepts
ShriKant Vashishtha
 
Distributed Agile Patterns
Distributed Agile PatternsDistributed Agile Patterns
Distributed Agile Patterns
ShriKant Vashishtha
 
What is Agile Testing
What is Agile TestingWhat is Agile Testing
What is Agile Testing
ShriKant Vashishtha
 
How to Break the Requirements into User Stories
How to Break the Requirements into User StoriesHow to Break the Requirements into User Stories
How to Break the Requirements into User StoriesShriKant Vashishtha
 
Agile Maintenance by ShriKant Vashishtha
Agile Maintenance by ShriKant VashishthaAgile Maintenance by ShriKant Vashishtha
Agile Maintenance by ShriKant VashishthaShriKant Vashishtha
 
Working With Augmented Distributed Agile Team In Legacy Application
Working With Augmented Distributed Agile Team In Legacy ApplicationWorking With Augmented Distributed Agile Team In Legacy Application
Working With Augmented Distributed Agile Team In Legacy ApplicationShriKant Vashishtha
 
Agile FAQs by ShriKant Vashishtha
Agile FAQs by ShriKant VashishthaAgile FAQs by ShriKant Vashishtha
Agile FAQs by ShriKant VashishthaShriKant Vashishtha
 
TheOtherPages Pagination Framework by Shrikant Vashishtha
TheOtherPages Pagination Framework by Shrikant VashishthaTheOtherPages Pagination Framework by Shrikant Vashishtha
TheOtherPages Pagination Framework by Shrikant VashishthaShriKant Vashishtha
 
Caching fundamentals by Shrikant Vashishtha
Caching fundamentals by Shrikant VashishthaCaching fundamentals by Shrikant Vashishtha
Caching fundamentals by Shrikant VashishthaShriKant Vashishtha
 
Pair Programming Explained By Shrikant Vashishtha
Pair Programming Explained  By Shrikant VashishthaPair Programming Explained  By Shrikant Vashishtha
Pair Programming Explained By Shrikant VashishthaShriKant Vashishtha
 
Management and Self Learning Lessons from Indian Mythology
Management and Self Learning Lessons from Indian MythologyManagement and Self Learning Lessons from Indian Mythology
Management and Self Learning Lessons from Indian MythologyShriKant Vashishtha
 
Memory Management In C++
Memory Management In C++Memory Management In C++
Memory Management In C++
ShriKant Vashishtha
 

More from ShriKant Vashishtha (14)

Evolution of Agile world with Lean Startup Concepts
 Evolution of Agile world with Lean Startup Concepts Evolution of Agile world with Lean Startup Concepts
Evolution of Agile world with Lean Startup Concepts
 
Distributed Agile Patterns
Distributed Agile PatternsDistributed Agile Patterns
Distributed Agile Patterns
 
What is Agile Testing
What is Agile TestingWhat is Agile Testing
What is Agile Testing
 
Pair Programming and XP Values
Pair Programming and XP ValuesPair Programming and XP Values
Pair Programming and XP Values
 
How to build a fun team
How to build a fun teamHow to build a fun team
How to build a fun team
 
How to Break the Requirements into User Stories
How to Break the Requirements into User StoriesHow to Break the Requirements into User Stories
How to Break the Requirements into User Stories
 
Agile Maintenance by ShriKant Vashishtha
Agile Maintenance by ShriKant VashishthaAgile Maintenance by ShriKant Vashishtha
Agile Maintenance by ShriKant Vashishtha
 
Working With Augmented Distributed Agile Team In Legacy Application
Working With Augmented Distributed Agile Team In Legacy ApplicationWorking With Augmented Distributed Agile Team In Legacy Application
Working With Augmented Distributed Agile Team In Legacy Application
 
Agile FAQs by ShriKant Vashishtha
Agile FAQs by ShriKant VashishthaAgile FAQs by ShriKant Vashishtha
Agile FAQs by ShriKant Vashishtha
 
TheOtherPages Pagination Framework by Shrikant Vashishtha
TheOtherPages Pagination Framework by Shrikant VashishthaTheOtherPages Pagination Framework by Shrikant Vashishtha
TheOtherPages Pagination Framework by Shrikant Vashishtha
 
Caching fundamentals by Shrikant Vashishtha
Caching fundamentals by Shrikant VashishthaCaching fundamentals by Shrikant Vashishtha
Caching fundamentals by Shrikant Vashishtha
 
Pair Programming Explained By Shrikant Vashishtha
Pair Programming Explained  By Shrikant VashishthaPair Programming Explained  By Shrikant Vashishtha
Pair Programming Explained By Shrikant Vashishtha
 
Management and Self Learning Lessons from Indian Mythology
Management and Self Learning Lessons from Indian MythologyManagement and Self Learning Lessons from Indian Mythology
Management and Self Learning Lessons from Indian Mythology
 
Memory Management In C++
Memory Management In C++Memory Management In C++
Memory Management In C++
 

Recently uploaded

When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
Alison B. Lowndes
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Product School
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
Elena Simperl
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
RTTS
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
g2nightmarescribd
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 

Recently uploaded (20)

When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 

Working effectively with legacy code

  • 1. Working Effectively with Legacy Code – Part I -ShriKantVashishtha Aug 19, 2009
  • 2. Four Reasons to Change Software Adding a feature Fixing a bug Improving the design Optimizing resource usage
  • 3. A Legacy Code Scenario What changes do we have to make? How will we know that we have done them correctly How will we know that we haven’t broken anything Avoiding change is a bad thing, but what is our alternative? Try harder. Hire more people
  • 4. Way of doing changes - Edit and Pray
  • 5. Way of doing changes - Cover and Modify
  • 6. Why Unit Tests Are Important? Error localization Execution time Coverage
  • 7. A Typical Legacy Code Sample
  • 8. Legacy Code Dilemma When we change code, we should have tests in place. To put tests in place, we often have to change code. Use Primitivize Parameter and Extract Interface to remove these issues
  • 11. Fake objects Support Real Tests public class FakeDisplay implements Display { private String lastLine = ""; public void showLine(String line) { lastLine = line; } public String getLastLine() { return lastLine; } } import junit.framework.*; public class SaleTest extends TestCase { public void testDisplayAnItem() { FakeDisplay display = new FakeDisplay(); Sale sale = new Sale(display); sale.scan("1"); assertEquals("Milk $3.99", display.getLastLine()); } }
  • 12. Seams boolCAsyncSslRec::Init() { … if (!m_bFailureSent) { m_bFailureSent=TRUE; PostReceiveError(SOCKETCALLBACK, SSL_FAILURE); } CreateLibrary(m_hSslDll1,"syncesel1.dll"); CreateLibrary(m_hSslDll2,"syncesel2.dll"); …. return true; }
  • 13. Object Seam class CAsyncSslRec { ... virtual void PostReceiveError(UINT type, UINT errorcode); ... }; class TestingAsyncSslRec : public CAsyncSslRec { virtual void PostReceiveError(UINT type, UINT errorcode) { } };
  • 14. Seam Types Preprocessing Seams Link Seams : static linking in C/C++/Flex and dynamic linking in Java Object Seams
  • 15. I Don't Have Much Time and I Have to Change It Sprout Method Sprout Class Wrap Method Wrap Class
  • 16. Sprout Method public class TransactionGate { public void postEntries(List entries) { for (Iterator it = entries.iterator(); it.hasNext(); ) { Entry entry = (Entry)it.next(); entry.postDate(); } transactionBundle.getListManager().add(entries); } ... }
  • 17. Sprout Method public class TransactionGate { public void postEntries(List entries) { List entriesToAdd = new LinkedList(); for (Iterator it = entries.iterator(); it.hasNext(); ) { Entry entry = (Entry)it.next(); if (!transactionBundle.getListManager().hasEntry(entry) { entry.postDate(); entriesToAdd.add(entry); } } transactionBundle.getListManager().add(entriesToAdd); } ... }
  • 18. Sprout Method public class TransactionGate { ... List uniqueEntries(List entries) { List result = new ArrayList(); for (Iterator it = entries.iterator(); it.hasNext(); ) { Entry entry = (Entry)it.next(); if (!transactionBundle.getListManager().hasEntry(entry) { result.add(entry); } } return result; } ... } public class TransactionGate { ... public void postEntries(List entries) { List entriesToAdd = uniqueEntries(entries); for (Iterator it = entriesToAdd.iterator(); it.hasNext(); ) { Entry entry = (Entry)it.next(); entry.postDate(); } transactionBundle.getListManager().add(entriesToAdd); } ... }
  • 19. Sprout Class std::string QuarterlyReportGenerator::generate() { std::vector<Result> results = database.queryResults( beginDate, endDate); std::string pageText; pageText += "<html><head><title>" "Quarterly Report" "</title></head><body><table>"; if (results.size() != 0) { for (std::vector<Result>::iterator it = results.begin(); it != results.end(); ++it) { pageText += "<tr>"; pageText += "<td>" + it->department + "</td>"; pageText += "<td>" + it->manager + "</td>"; char buffer [128]; sprintf(buffer, "<td>$%d</td>", it->netProfit / 100); pageText += std::string(buffer); sprintf(buffer, "<td>$%d</td>", it->operatingExpense / 100); pageText += std::string(buffer); pageText += "</tr>"; } } else { pageText += "No results for this period"; } pageText += "</table>"; pageText += "</body>"; pageText += "</html>"; return pageText; }
  • 20. Wrap Method public class Employee { ... public void pay() { Money amount = new Money(); for (Iterator it = timecards.iterator(); it.hasNext(); ) { Timecard card = (Timecard)it.next(); if (payPeriod.contains(date)) { amount.add(card.getHours() * payRate); } } payDispatcher.pay(this, date, amount); } }
  • 21. Wrap Method public class Employee { private void dispatchPayment() { Money amount = new Money(); for (Iterator it = timecards.iterator(); it.hasNext(); ) { Timecard card = (Timecard)it.next(); if (payPeriod.contains(date)) { amount.add(card.getHours() * payRate); } } payDispatcher.pay(this, date, amount); } public void pay() { logPayment(); dispatchPayment(); } private void logPayment() { ... } }
  • 22. Wrap Method Advantages A good way of getting new, tested functionality into an application when we can't easily write tests for the calling code It explicitly makes the new functionality independent of existing functionality Disadvantages Can lead to poor names
  • 23. Wrap Class class Employee { public void pay() { Money amount = new Money(); for (Iterator it = timecards.iterator(); it.hasNext(); ) { Timecard card = (Timecard)it.next(); if (payPeriod.contains(date)) { amount.add(card.getHours() * payRate); } } payDispatcher.pay(this, date, amount); } ... }
  • 24. Wrap Class class LoggingEmployee extends Employee { public LoggingEmployee(Employee e) { employee = e; } public void pay() { logPayment(); employee.pay(); } private void logPayment() { ... } ... }
  • 25. Wrap Class class LoggingPayDispatcher { private Employee e; public LoggingPayDispatcher(Employee e) { this.e = e; } public void pay() { employee.pay(); logPayment(); } private void logPayment() { ... } ... }
  • 26. Wrap Class Able to add new behavior into a system without adding it to an existing class When there are many calls to the code you want to wrap, it often pays to move toward a decorator-ish wrapper If new behavior has to happen at couple of places, simple class wrapper is very useful
  • 27. I Don't Have Much Time and I Have to Change It: Summary Use Sprout Method when the code you have in the existing method communicates a clear algorithm to the reader. Use Wrap Method when you think that the new feature you’re adding is as important as the work that was there before Use Wrap Class when the behavior that I want to add is completely independent

Editor's Notes

  1. It seems nearly impossible to add behavior without changing it to some degree.Improving design – a series of small structural modifications, supported by tests to make the code easier to change.Optimization – functionality exactly the same but changing something else (usually time or memory)
  2. Talk about a team policy where – if it’s not broke, don’t fix it. – Talk about problems it createsDifference between good and bad systems
  3. Working with care – leads to using tools and techniques inefficiently
  4. Use of safety netCovering software means covering with testsTesting to attempt to show correctnessVsTesting to detect change – tests as software vise – keep most of the behavior fixed and change only what you intend toRegression tests with or without writing tests – mention a story about doing the testing at the end
  5. Other kinds of tests often masquerade as unit tests. A test is not a unit test if:It talks to a database.It communicates across a network.It touches the file system.You have to do special things to your environment (such as editing configuration files) to run it.
  6. Servlet and DBConnection are two issuesPossible option – pass real db connection but how about servlet itself
  7. Mock objects are advanced type of fakes.
  8. A seam is a place where you can alter behavior in your program without editing in that place.
  9. We need to add code to verify that none of the new entries are already in transactionBundle before we post their dates and add them.
  10. Disadvantages: Giving up on the codeAdvantages: Separating new code from old code
  11. &quot;&lt;tr&gt;&lt;td&gt;Department&lt;/td&gt;&lt;td&gt;Manager&lt;/td&gt;&lt;td&gt;Profit&lt;/td&gt;&lt;td&gt;Expenses&lt;/td&gt;&lt;/tr&gt;&quot;
  12. Every time that we pay an employee, we have to update a file with the employee&apos;s name so that it can be sent off to some reporting softwareThe easiest way to do….is method
  13. We create a method with the name of the original method and have it delegate to our old code
  14. Use of decoratorToolController controller = new StepNotifyingController( new AlarmingController ( new ACMEController()), notifyees);
  15. Without using decorator