SlideShare uma empresa Scribd logo
1 de 36
Baixar para ler offline
Cork Software Crafters
Follow us on
Twitter: @CorkSwCraft
Meetup: www.meetup.com/Cork-Software-Craftsmanship-Meetup
Slack: softwarecrafters.slack.com/messages/cork
Breaking dependencies in legacy code
24th September 2019
facilitated by Paulo Clavijo
Thanks
We are always looking for new ideas, new talks and
mostly new hands-on sessions for our meetups.
Contact us if you want to collaborate!
join Software Crafters community on Slack
http://slack.softwarecrafters.org
follow Cork Software Crafters
@CorkSwCraft
6:15pm - Welcome.
6:30pm - Introduction.
6:45pm - Hands-on time.
8:00pm - Retrospective: discuss our solutions, pros and cons.
Paulo Clavijo (@pclavijo)
Agenda
Cork Software Crafters
Working with Legacy Code
What is Legay Code?
Legacy Code
“Code without tests is bad code. It doesn't matter how well
written it is; it doesn't matter how pretty or object-oriented or
well-encapsulated it is.” - Michael Feathers
Paulo Clavijo @pclavijo
Legacy Code
“Legacy code is valuable code that we’re
afraid to change.” - J.B. Rainsberger
Paulo Clavijo @pclavijo
Legacy Code
tends to be:
● Difficult to understand
● Poorly tested
suffers from design issues like:
● Tight Coupling
● Low Cohesion
● Feature Envy
● Huge (long modules, classes, methods)
● Risky to change
● Anaemic Domain
● SRP violation
The Legacy Code Dilemma
“When we have to change code, we should
have tests in place. To put tests in place, we
often have to change code.” - Michael Feathers
Steps to change Legacy Code
1. Identify change points
2. Find testing points
3. Break dependencies if necessary
4. Write tests to cover existing behavior
5. Make the change using TDD
what module /component / interface to change
The Seam Model
The Seam Model
A seam is a place where you can alter behavior in your program without editing in that
place.
Every seam has an enabling point, a place where you can make the decision to use one
behavior or another.
In most cases, a seam is a method call where the callee can be changed
without changing the caller.
Source: Working Effectively With Legacy Code, Michael Feathers
The Seam Model
In object-oriented languages, not all method calls are seams. Is the call to Recalculate an object seam?
public class CustomSpreadsheet extends Spreadsheet {
public Spreadsheet buildMartSheet() {
...
Cell cell = new FormulaCell(this, "A1", "=A2+A3");
...
cell.Recalculate();
...
}
...
}
Source: Working Effectively With Legacy Code, Michael Feathers
No. In this code, we’re creating a cell and then using it in the same method. There is no enabling point. We can’t
change which Recalculate method is called because the choice depends on the class of the cell. The class of the cell
is decided when the object is created, and we can’t change it without modifying the method.
The Seam Model
Is the call to Recalculate a seam now?
public class CustomSpreadsheet extends Spreadsheet {
public Spreadsheet buildMartSheet(Cell cell) {
...
cell.Recalculate();
...
}
...
}
Source: Working Effectively With Legacy Code, Michael Feathers
Yes. We can create a CustomSpreadsheet in a test and call buildMartSheet with whatever kind of Cell we want to use.
We’ll have ended up varying what the call to cell.Recalculate does without changing the method that calls it.
The enabling point is the argument list of buildMartSheet. We can decide what kind of an object to pass and change
the behavior of Recalculate any way that we want to for testing.
Creating Seams
If your code lacks a seam where you need one, the usual solution is to extract a method
containing the code you want to alter. Then you can either extend the class and override
the method, or move the method to a separate class or interface, and provide the caller
with the class or interface.
Depending on your programming language, there might be other options such as passing
a function or patching the extracted method at runtime.
Dependency Breaking
Dependency-Breaking Techniques
● Techniques to decouple classes well enough to get them under test.
● These refactorings are intended to be done without tests, to get tests in place.
● These techniques do not immediately make your design better.
● Help geetting code under test hence your system will be more maintainable.
Dependency-Breaking Techniques
● Parameterise Constructor
● Subclass And Override Method
○ Extract And Override Call
○ Extract And Override Factory Method
○ Replace Global Reference With Getter
● Encapsulate Global Reference
● Break Out Method Object
● Extract Pure Functions
● Adapt Parameter
...
Parameterise Constructor
public class AccountService {
private final TransactionLogger logger;
public AccountService() {
logger = new TransactionLogger();
}
public void deposit(Money amount) {
…
logger.log(transaction)
…
}
}
public class AccountService {
private final TransactionLogger logger;
public AccountService() {
this(new TransactionLogger());
}
public AccountService(TransactionLogger logger) {
this.logger = logger;
}
public void deposit(Money amount) {
…
logger.log(transaction)
…
}
}
Subclass and Override Method
private a() {
...
}
Class
Testing Subclass
protected a() {
...
}
Class
@Override
protected a() {
...
}
A core technique for breaking dependencies in OO.
Extract And Override Call
A way to break dependencies on global variables and static methods.
public a() {
...
logic
...
}
Class
public a() {
...
b()
...
}
Class
protected b() {
logic
}
Testing Subclass
@Override
protected b() {
test logic
}
Extract And Override Call
class Account {
...
void deposit(double amount) {
this.balance += amount;
String depositXml = serializeTransaction(amount);
AccountLogger.log(depositXml);
rewardPoints += calculateRewardPoints(amount);
}
...
}
class Account {
...
void deposit(double amount) {
this.balance += amount;
String depositXml = serializeTransaction(amount);
logTransaction(depositXml);
rewardPoints += calculateRewardPoints(amount);
}
void logTransaction(String transaction) {
AccountLogger.log(depositXml);
}
...
}
Extract And Override Factory Method
public A() {
b = new B()
}
Class Class
protected makeB() {
Return new B()
}
Testing Subclass
@Override
protected makeB() {
...
}
public A() {
b = makeB()
}
Replace Global Reference With Getter
public a() {
...
GLOBAL_X
...
}
Class
public a() {
...
getX()
...
}
Class
protected x() {
return GLOBAL_X
}
Testing Subclass
@Override
protected x() {
...
}
Break Out Method Object
Class
New Class
longMethod() {
...
...
}
longMethod(...) {
...
...
}
b() { … }
c() { … }
...
Extract Pure Functions
Extract Pure Functions to split large methods and classes into smaller ones that we can
understand and test.
“A pure function is a function that has the following properties: Its return value is the
same for the same arguments. Its evaluation has no side effects.” - Wikipedia
Using static methods can be a good option in Java
Practice Time
Dependency Breaking Katas
Cork Software Crafters Paulo Clavijo (@pclavijo)
http://bit.ly/2md90q9
We have some legacy code. We need to make changes. To make changes we need
to introduce tests first. We might have to change some code to enable
testing. We need to introduce so-called Seams (see Michael Feathers'
Working Effectively with Legacy Code).
Changing code without test is risky, so we want to
● Only change as little code as possible.
● Rely on automated Refactoring tools as much as possible.
● You must not change the public API of the class.
by Peter Kofler
https://github.com/emilybache/GildedRose-Refactoring-Kata
Dependency Breaking Katas
Cork Software Crafters Paulo Clavijo (@pclavijo)
Assignment A
Problem Category
The system under test depends on a collaborator with non deterministic
behaviour. The collaborator is initialised in the constructor.
Task
The given code calculates the discount for a purchase in our online shop. The
main logic is in Discount.
● Bring Discount under test. Make sure to cover all paths in the core logic.
● There is an existing DiscountTest with a first test case which might or
might not work.
● You cannot change MarketingCampaign because it is used by other teams as
well.
by Peter Kofler
https://github.com/emilybache/GildedRose-Refactoring-Kata
Dependency Breaking Katas
Cork Software Crafters Paulo Clavijo (@pclavijo)
Assignment B
Problem Category
The system under test contains non deterministic behaviour, which is located in
a few methods.
Task
The given MarketingCampaign controls the marketing actions which run on our
online shop. During campaigns we e.g. offer discounts.
● Bring MarketingCampaign under test. Make sure to cover all paths in the
core logic.
● There is an existing MarketingCampaignTest with a first test case which
might or might not work.
by Peter Kofler
https://github.com/emilybache/GildedRose-Refactoring-Kata
Dependency Breaking Katas
Cork Software Crafters Paulo Clavijo (@pclavijo)
Assignment C
Problem Category
The system under test depends on a collaborator with database access. The
database is not available in our test environment. The collaborator is a static
call.
Task
The given code creates the receipt with the calculated tax for a purchase in
our online shop. The main logic is in Checkout.
● Bring Checkout under test. Make sure to cover all paths in the core logic.
● There is an existing CheckoutTest with a first test case which might or might
not work.
● You cannot change ReceiptRepository because it is used by other teams as well.
by Peter Kofler
https://github.com/emilybache/GildedRose-Refactoring-Kata
Dependency Breaking Katas
Cork Software Crafters Paulo Clavijo (@pclavijo)
Assignment D
Problem Category
The system under test depends on a collaborator with slow behaviour due to a
HTTP call. It is not guaranteed that the REST server is available. The
collaborator is a Singleton and called multiple times.
Task
The given code calculates the shipping cost for a purchase depending on the
destination in our online shop. The main logic is in ShippingCost.
● Bring ShippingCost under test. Make sure to cover all paths in the core logic.
● There is an existing ShippingCostTest with a first test case which might or
might not work.
● You cannot change RestCountriesAPI because it is used by other teams as well.
by Peter Kofler
https://github.com/emilybache/GildedRose-Refactoring-Kata
Dependency Breaking Katas
Cork Software Crafters Paulo Clavijo (@pclavijo)
Assignment E
Problem Category
The system under test depends on a collaborator with user interaction. The
manual step is not suitable for our test environment. The collaborator is
created inside the class.
Task
The given code collects the necessary user confirmations during a purchase in
our online shop. The main logic is in Checkout.
● Bring Checkout under test. Make sure to cover all paths in the core logic.
● There is an existing CheckoutTest with a first test case which might or
might not work.
by Peter Kofler
https://github.com/emilybache/GildedRose-Refactoring-Kata
Retrospective
● What went well?
● What problems did you encounter?
● What have you learned?
● What surprised you?
Paulo Clavijo (@pclavijo)Cork Software Crafters

Mais conteúdo relacionado

Mais procurados

Hexagonal architecture vs Functional core / Imperative shell
Hexagonal architecture vs Functional core / Imperative shellHexagonal architecture vs Functional core / Imperative shell
Hexagonal architecture vs Functional core / Imperative shellThomas Pierrain
 
OpenStack API's and WSGI
OpenStack API's and WSGIOpenStack API's and WSGI
OpenStack API's and WSGIMike Pittaro
 
ORM2Pwn: Exploiting injections in Hibernate ORM
ORM2Pwn: Exploiting injections in Hibernate ORMORM2Pwn: Exploiting injections in Hibernate ORM
ORM2Pwn: Exploiting injections in Hibernate ORMMikhail Egorov
 
OWASP-VulnerableFlaskApp
OWASP-VulnerableFlaskAppOWASP-VulnerableFlaskApp
OWASP-VulnerableFlaskAppanilyelken
 
Getting a live_transcript_of_your_call_using_the_ari
Getting a live_transcript_of_your_call_using_the_ariGetting a live_transcript_of_your_call_using_the_ari
Getting a live_transcript_of_your_call_using_the_ariPascal Cadotte-Michaud
 
Kamailio with Docker and Kubernetes
Kamailio with Docker and KubernetesKamailio with Docker and Kubernetes
Kamailio with Docker and KubernetesPaolo Visintin
 
Google Dataflow Intro
Google Dataflow IntroGoogle Dataflow Intro
Google Dataflow IntroIvan Glushkov
 
Pentesting Modern Web Apps: A Primer
Pentesting Modern Web Apps: A PrimerPentesting Modern Web Apps: A Primer
Pentesting Modern Web Apps: A PrimerBrian Hysell
 
Morel, a Functional Query Language
Morel, a Functional Query LanguageMorel, a Functional Query Language
Morel, a Functional Query LanguageJulian Hyde
 
Security Code Review 101
Security Code Review 101Security Code Review 101
Security Code Review 101Paul Ionescu
 
Web application security & Testing
Web application security  & TestingWeb application security  & Testing
Web application security & TestingDeepu S Nath
 
Kafka Retry and DLQ
Kafka Retry and DLQKafka Retry and DLQ
Kafka Retry and DLQGeorge Teo
 
Container security
Container securityContainer security
Container securityAnthony Chow
 
Scaling Asterisk with Kamailio
Scaling Asterisk with KamailioScaling Asterisk with Kamailio
Scaling Asterisk with KamailioFred Posner
 
Advanced mainframe hacking
Advanced mainframe hackingAdvanced mainframe hacking
Advanced mainframe hackingPhilip Young
 

Mais procurados (20)

Hexagonal architecture vs Functional core / Imperative shell
Hexagonal architecture vs Functional core / Imperative shellHexagonal architecture vs Functional core / Imperative shell
Hexagonal architecture vs Functional core / Imperative shell
 
OpenStack API's and WSGI
OpenStack API's and WSGIOpenStack API's and WSGI
OpenStack API's and WSGI
 
ORM2Pwn: Exploiting injections in Hibernate ORM
ORM2Pwn: Exploiting injections in Hibernate ORMORM2Pwn: Exploiting injections in Hibernate ORM
ORM2Pwn: Exploiting injections in Hibernate ORM
 
OWASP-VulnerableFlaskApp
OWASP-VulnerableFlaskAppOWASP-VulnerableFlaskApp
OWASP-VulnerableFlaskApp
 
Getting a live_transcript_of_your_call_using_the_ari
Getting a live_transcript_of_your_call_using_the_ariGetting a live_transcript_of_your_call_using_the_ari
Getting a live_transcript_of_your_call_using_the_ari
 
Kamailio with Docker and Kubernetes
Kamailio with Docker and KubernetesKamailio with Docker and Kubernetes
Kamailio with Docker and Kubernetes
 
Google Dataflow Intro
Google Dataflow IntroGoogle Dataflow Intro
Google Dataflow Intro
 
Corso c++
Corso c++Corso c++
Corso c++
 
Pentesting Modern Web Apps: A Primer
Pentesting Modern Web Apps: A PrimerPentesting Modern Web Apps: A Primer
Pentesting Modern Web Apps: A Primer
 
sqlmap internals
sqlmap internalssqlmap internals
sqlmap internals
 
Morel, a Functional Query Language
Morel, a Functional Query LanguageMorel, a Functional Query Language
Morel, a Functional Query Language
 
Blacklist3r
Blacklist3rBlacklist3r
Blacklist3r
 
ORM Injection
ORM InjectionORM Injection
ORM Injection
 
Security Code Review 101
Security Code Review 101Security Code Review 101
Security Code Review 101
 
Web application security & Testing
Web application security  & TestingWeb application security  & Testing
Web application security & Testing
 
Kafka Retry and DLQ
Kafka Retry and DLQKafka Retry and DLQ
Kafka Retry and DLQ
 
Comprendre la securite web
Comprendre la securite webComprendre la securite web
Comprendre la securite web
 
Container security
Container securityContainer security
Container security
 
Scaling Asterisk with Kamailio
Scaling Asterisk with KamailioScaling Asterisk with Kamailio
Scaling Asterisk with Kamailio
 
Advanced mainframe hacking
Advanced mainframe hackingAdvanced mainframe hacking
Advanced mainframe hacking
 

Semelhante a Breaking Dependencies Legacy Code - Cork Software Crafters - September 2019

System verilog important
System verilog importantSystem verilog important
System verilog importantelumalai7
 
TDD And Refactoring
TDD And RefactoringTDD And Refactoring
TDD And RefactoringNaresh Jain
 
Working Effectively With Legacy Perl Code
Working Effectively With Legacy Perl CodeWorking Effectively With Legacy Perl Code
Working Effectively With Legacy Perl Codeerikmsp
 
New Ideas for Old Code - Greach
New Ideas for Old Code - GreachNew Ideas for Old Code - Greach
New Ideas for Old Code - GreachHamletDRC
 
Desing pattern prototype-Factory Method, Prototype and Builder
Desing pattern prototype-Factory Method, Prototype and Builder Desing pattern prototype-Factory Method, Prototype and Builder
Desing pattern prototype-Factory Method, Prototype and Builder paramisoft
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to javaciklum_ods
 
P Training Presentation
P Training PresentationP Training Presentation
P Training PresentationGaurav Tyagi
 
Microservices Chaos Testing at Jet
Microservices Chaos Testing at JetMicroservices Chaos Testing at Jet
Microservices Chaos Testing at JetC4Media
 
The tests are trying to tell you something@VoxxedBucharest.pptx
The tests are trying to tell you something@VoxxedBucharest.pptxThe tests are trying to tell you something@VoxxedBucharest.pptx
The tests are trying to tell you something@VoxxedBucharest.pptxVictor Rentea
 
Assessing Unit Test Quality
Assessing Unit Test QualityAssessing Unit Test Quality
Assessing Unit Test Qualityguest268ee8
 
Testing Experience - Evolution of Test Automation Frameworks
Testing Experience - Evolution of Test Automation FrameworksTesting Experience - Evolution of Test Automation Frameworks
Testing Experience - Evolution of Test Automation FrameworksŁukasz Morawski
 
Introduction to Behavior Driven Development
Introduction to Behavior Driven Development Introduction to Behavior Driven Development
Introduction to Behavior Driven Development Robin O'Brien
 
PHP - Introduction to Object Oriented Programming with PHP
PHP -  Introduction to  Object Oriented Programming with PHPPHP -  Introduction to  Object Oriented Programming with PHP
PHP - Introduction to Object Oriented Programming with PHPVibrant Technologies & Computers
 
Agile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tddAgile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tddSrinivasa GV
 

Semelhante a Breaking Dependencies Legacy Code - Cork Software Crafters - September 2019 (20)

System verilog important
System verilog importantSystem verilog important
System verilog important
 
TDD And Refactoring
TDD And RefactoringTDD And Refactoring
TDD And Refactoring
 
Working Effectively With Legacy Perl Code
Working Effectively With Legacy Perl CodeWorking Effectively With Legacy Perl Code
Working Effectively With Legacy Perl Code
 
New Ideas for Old Code - Greach
New Ideas for Old Code - GreachNew Ideas for Old Code - Greach
New Ideas for Old Code - Greach
 
Software Design Patterns
Software Design PatternsSoftware Design Patterns
Software Design Patterns
 
Desing pattern prototype-Factory Method, Prototype and Builder
Desing pattern prototype-Factory Method, Prototype and Builder Desing pattern prototype-Factory Method, Prototype and Builder
Desing pattern prototype-Factory Method, Prototype and Builder
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
Code review
Code reviewCode review
Code review
 
P Training Presentation
P Training PresentationP Training Presentation
P Training Presentation
 
Microservices Chaos Testing at Jet
Microservices Chaos Testing at JetMicroservices Chaos Testing at Jet
Microservices Chaos Testing at Jet
 
Design Patterns
Design PatternsDesign Patterns
Design Patterns
 
The tests are trying to tell you something@VoxxedBucharest.pptx
The tests are trying to tell you something@VoxxedBucharest.pptxThe tests are trying to tell you something@VoxxedBucharest.pptx
The tests are trying to tell you something@VoxxedBucharest.pptx
 
Tech talks#6: Code Refactoring
Tech talks#6: Code RefactoringTech talks#6: Code Refactoring
Tech talks#6: Code Refactoring
 
Java scjp-part1
Java scjp-part1Java scjp-part1
Java scjp-part1
 
Need 4 Speed FI
Need 4 Speed FINeed 4 Speed FI
Need 4 Speed FI
 
Assessing Unit Test Quality
Assessing Unit Test QualityAssessing Unit Test Quality
Assessing Unit Test Quality
 
Testing Experience - Evolution of Test Automation Frameworks
Testing Experience - Evolution of Test Automation FrameworksTesting Experience - Evolution of Test Automation Frameworks
Testing Experience - Evolution of Test Automation Frameworks
 
Introduction to Behavior Driven Development
Introduction to Behavior Driven Development Introduction to Behavior Driven Development
Introduction to Behavior Driven Development
 
PHP - Introduction to Object Oriented Programming with PHP
PHP -  Introduction to  Object Oriented Programming with PHPPHP -  Introduction to  Object Oriented Programming with PHP
PHP - Introduction to Object Oriented Programming with PHP
 
Agile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tddAgile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tdd
 

Mais de Paulo Clavijo

Consumer-Driven Contract Testing - Workshop - January 2021
Consumer-Driven Contract Testing - Workshop - January 2021Consumer-Driven Contract Testing - Workshop - January 2021
Consumer-Driven Contract Testing - Workshop - January 2021Paulo Clavijo
 
User story slicing exercise
User story slicing exerciseUser story slicing exercise
User story slicing exercisePaulo Clavijo
 
CI/CD non-breaking changes exercise - Cork Software Crafters - February 2020
CI/CD non-breaking changes exercise - Cork Software Crafters - February 2020CI/CD non-breaking changes exercise - Cork Software Crafters - February 2020
CI/CD non-breaking changes exercise - Cork Software Crafters - February 2020Paulo Clavijo
 
Legacy Code and Refactoring Workshop - Session 1 - October 2019
Legacy Code and Refactoring Workshop - Session 1 - October 2019Legacy Code and Refactoring Workshop - Session 1 - October 2019
Legacy Code and Refactoring Workshop - Session 1 - October 2019Paulo Clavijo
 
Approval Testing & Mutation Testing - Cork Software Crafters - June 2019
Approval Testing & Mutation Testing - Cork Software Crafters - June 2019Approval Testing & Mutation Testing - Cork Software Crafters - June 2019
Approval Testing & Mutation Testing - Cork Software Crafters - June 2019Paulo Clavijo
 
TDD and Simple Design Workshop - Session 1 - March 2019
TDD and Simple Design Workshop - Session 1 - March 2019TDD and Simple Design Workshop - Session 1 - March 2019
TDD and Simple Design Workshop - Session 1 - March 2019Paulo Clavijo
 
TDD and Simple Design Workshop - Session 1 - November 2018
TDD and Simple Design Workshop - Session 1 - November 2018TDD and Simple Design Workshop - Session 1 - November 2018
TDD and Simple Design Workshop - Session 1 - November 2018Paulo Clavijo
 
Outside-in TDD with Test Doubles
Outside-in TDD with Test DoublesOutside-in TDD with Test Doubles
Outside-in TDD with Test DoublesPaulo Clavijo
 
DDD Strategic Design - Context Maps - Paulo Clavijo - April 2018
DDD Strategic Design - Context Maps - Paulo Clavijo - April 2018DDD Strategic Design - Context Maps - Paulo Clavijo - April 2018
DDD Strategic Design - Context Maps - Paulo Clavijo - April 2018Paulo Clavijo
 
Consumer-Driven Contract Testing
Consumer-Driven Contract TestingConsumer-Driven Contract Testing
Consumer-Driven Contract TestingPaulo Clavijo
 
ATDD - Desarrollo Dirigido por Test de Aceptación
ATDD - Desarrollo Dirigido por Test de AceptaciónATDD - Desarrollo Dirigido por Test de Aceptación
ATDD - Desarrollo Dirigido por Test de AceptaciónPaulo Clavijo
 
Tests Unitarios con JUnit 4
Tests Unitarios con JUnit 4Tests Unitarios con JUnit 4
Tests Unitarios con JUnit 4Paulo Clavijo
 
Gestión de Cambios de BBDD con LiquiBase
Gestión de Cambios de BBDD con LiquiBaseGestión de Cambios de BBDD con LiquiBase
Gestión de Cambios de BBDD con LiquiBasePaulo Clavijo
 
Introducción a Spring Roo
Introducción a Spring RooIntroducción a Spring Roo
Introducción a Spring RooPaulo Clavijo
 

Mais de Paulo Clavijo (15)

Consumer-Driven Contract Testing - Workshop - January 2021
Consumer-Driven Contract Testing - Workshop - January 2021Consumer-Driven Contract Testing - Workshop - January 2021
Consumer-Driven Contract Testing - Workshop - January 2021
 
User story slicing exercise
User story slicing exerciseUser story slicing exercise
User story slicing exercise
 
CI/CD non-breaking changes exercise - Cork Software Crafters - February 2020
CI/CD non-breaking changes exercise - Cork Software Crafters - February 2020CI/CD non-breaking changes exercise - Cork Software Crafters - February 2020
CI/CD non-breaking changes exercise - Cork Software Crafters - February 2020
 
Legacy Code and Refactoring Workshop - Session 1 - October 2019
Legacy Code and Refactoring Workshop - Session 1 - October 2019Legacy Code and Refactoring Workshop - Session 1 - October 2019
Legacy Code and Refactoring Workshop - Session 1 - October 2019
 
Approval Testing & Mutation Testing - Cork Software Crafters - June 2019
Approval Testing & Mutation Testing - Cork Software Crafters - June 2019Approval Testing & Mutation Testing - Cork Software Crafters - June 2019
Approval Testing & Mutation Testing - Cork Software Crafters - June 2019
 
TDD and Simple Design Workshop - Session 1 - March 2019
TDD and Simple Design Workshop - Session 1 - March 2019TDD and Simple Design Workshop - Session 1 - March 2019
TDD and Simple Design Workshop - Session 1 - March 2019
 
TDD and Simple Design Workshop - Session 1 - November 2018
TDD and Simple Design Workshop - Session 1 - November 2018TDD and Simple Design Workshop - Session 1 - November 2018
TDD and Simple Design Workshop - Session 1 - November 2018
 
Outside-in TDD with Test Doubles
Outside-in TDD with Test DoublesOutside-in TDD with Test Doubles
Outside-in TDD with Test Doubles
 
Angular and Redux
Angular and ReduxAngular and Redux
Angular and Redux
 
DDD Strategic Design - Context Maps - Paulo Clavijo - April 2018
DDD Strategic Design - Context Maps - Paulo Clavijo - April 2018DDD Strategic Design - Context Maps - Paulo Clavijo - April 2018
DDD Strategic Design - Context Maps - Paulo Clavijo - April 2018
 
Consumer-Driven Contract Testing
Consumer-Driven Contract TestingConsumer-Driven Contract Testing
Consumer-Driven Contract Testing
 
ATDD - Desarrollo Dirigido por Test de Aceptación
ATDD - Desarrollo Dirigido por Test de AceptaciónATDD - Desarrollo Dirigido por Test de Aceptación
ATDD - Desarrollo Dirigido por Test de Aceptación
 
Tests Unitarios con JUnit 4
Tests Unitarios con JUnit 4Tests Unitarios con JUnit 4
Tests Unitarios con JUnit 4
 
Gestión de Cambios de BBDD con LiquiBase
Gestión de Cambios de BBDD con LiquiBaseGestión de Cambios de BBDD con LiquiBase
Gestión de Cambios de BBDD con LiquiBase
 
Introducción a Spring Roo
Introducción a Spring RooIntroducción a Spring Roo
Introducción a Spring Roo
 

Último

دليل تجارب الاسفلت المختبرية - Asphalt Experiments Guide Laboratory
دليل تجارب الاسفلت المختبرية - Asphalt Experiments Guide Laboratoryدليل تجارب الاسفلت المختبرية - Asphalt Experiments Guide Laboratory
دليل تجارب الاسفلت المختبرية - Asphalt Experiments Guide LaboratoryBahzad5
 
IT3401-WEB ESSENTIALS PRESENTATIONS.pptx
IT3401-WEB ESSENTIALS PRESENTATIONS.pptxIT3401-WEB ESSENTIALS PRESENTATIONS.pptx
IT3401-WEB ESSENTIALS PRESENTATIONS.pptxSAJITHABANUS
 
cloud computing notes for anna university syllabus
cloud computing notes for anna university syllabuscloud computing notes for anna university syllabus
cloud computing notes for anna university syllabusViolet Violet
 
Landsman converter for power factor improvement
Landsman converter for power factor improvementLandsman converter for power factor improvement
Landsman converter for power factor improvementVijayMuni2
 
EPE3163_Hydro power stations_Unit2_Lect2.pptx
EPE3163_Hydro power stations_Unit2_Lect2.pptxEPE3163_Hydro power stations_Unit2_Lect2.pptx
EPE3163_Hydro power stations_Unit2_Lect2.pptxJoseeMusabyimana
 
Summer training report on BUILDING CONSTRUCTION for DIPLOMA Students.pdf
Summer training report on BUILDING CONSTRUCTION for DIPLOMA Students.pdfSummer training report on BUILDING CONSTRUCTION for DIPLOMA Students.pdf
Summer training report on BUILDING CONSTRUCTION for DIPLOMA Students.pdfNaveenVerma126
 
Basic Principle of Electrochemical Sensor
Basic Principle of  Electrochemical SensorBasic Principle of  Electrochemical Sensor
Basic Principle of Electrochemical SensorTanvir Moin
 
Popular-NO1 Kala Jadu Expert Specialist In Germany Kala Jadu Expert Specialis...
Popular-NO1 Kala Jadu Expert Specialist In Germany Kala Jadu Expert Specialis...Popular-NO1 Kala Jadu Expert Specialist In Germany Kala Jadu Expert Specialis...
Popular-NO1 Kala Jadu Expert Specialist In Germany Kala Jadu Expert Specialis...Amil baba
 
Nodal seismic construction requirements.pptx
Nodal seismic construction requirements.pptxNodal seismic construction requirements.pptx
Nodal seismic construction requirements.pptxwendy cai
 
Transforming Process Safety Management: Challenges, Benefits, and Transition ...
Transforming Process Safety Management: Challenges, Benefits, and Transition ...Transforming Process Safety Management: Challenges, Benefits, and Transition ...
Transforming Process Safety Management: Challenges, Benefits, and Transition ...soginsider
 
Technology Features of Apollo HDD Machine, Its Technical Specification with C...
Technology Features of Apollo HDD Machine, Its Technical Specification with C...Technology Features of Apollo HDD Machine, Its Technical Specification with C...
Technology Features of Apollo HDD Machine, Its Technical Specification with C...Apollo Techno Industries Pvt Ltd
 
Lecture 1: Basics of trigonometry (surveying)
Lecture 1: Basics of trigonometry (surveying)Lecture 1: Basics of trigonometry (surveying)
Lecture 1: Basics of trigonometry (surveying)Bahzad5
 
Strategies of Urban Morphologyfor Improving Outdoor Thermal Comfort and Susta...
Strategies of Urban Morphologyfor Improving Outdoor Thermal Comfort and Susta...Strategies of Urban Morphologyfor Improving Outdoor Thermal Comfort and Susta...
Strategies of Urban Morphologyfor Improving Outdoor Thermal Comfort and Susta...amrabdallah9
 
Clutches and brkesSelect any 3 position random motion out of real world and d...
Clutches and brkesSelect any 3 position random motion out of real world and d...Clutches and brkesSelect any 3 position random motion out of real world and d...
Clutches and brkesSelect any 3 position random motion out of real world and d...sahb78428
 
ASME BPVC 2023 Section I para leer y entender
ASME BPVC 2023 Section I para leer y entenderASME BPVC 2023 Section I para leer y entender
ASME BPVC 2023 Section I para leer y entenderjuancarlos286641
 
Quasi-Stochastic Approximation: Algorithm Design Principles with Applications...
Quasi-Stochastic Approximation: Algorithm Design Principles with Applications...Quasi-Stochastic Approximation: Algorithm Design Principles with Applications...
Quasi-Stochastic Approximation: Algorithm Design Principles with Applications...Sean Meyn
 
UNIT4_ESD_wfffffggggggggggggith_ARM.pptx
UNIT4_ESD_wfffffggggggggggggith_ARM.pptxUNIT4_ESD_wfffffggggggggggggith_ARM.pptx
UNIT4_ESD_wfffffggggggggggggith_ARM.pptxrealme6igamerr
 
Gender Bias in Engineer, Honors 203 Project
Gender Bias in Engineer, Honors 203 ProjectGender Bias in Engineer, Honors 203 Project
Gender Bias in Engineer, Honors 203 Projectreemakb03
 

Último (20)

دليل تجارب الاسفلت المختبرية - Asphalt Experiments Guide Laboratory
دليل تجارب الاسفلت المختبرية - Asphalt Experiments Guide Laboratoryدليل تجارب الاسفلت المختبرية - Asphalt Experiments Guide Laboratory
دليل تجارب الاسفلت المختبرية - Asphalt Experiments Guide Laboratory
 
IT3401-WEB ESSENTIALS PRESENTATIONS.pptx
IT3401-WEB ESSENTIALS PRESENTATIONS.pptxIT3401-WEB ESSENTIALS PRESENTATIONS.pptx
IT3401-WEB ESSENTIALS PRESENTATIONS.pptx
 
cloud computing notes for anna university syllabus
cloud computing notes for anna university syllabuscloud computing notes for anna university syllabus
cloud computing notes for anna university syllabus
 
Landsman converter for power factor improvement
Landsman converter for power factor improvementLandsman converter for power factor improvement
Landsman converter for power factor improvement
 
EPE3163_Hydro power stations_Unit2_Lect2.pptx
EPE3163_Hydro power stations_Unit2_Lect2.pptxEPE3163_Hydro power stations_Unit2_Lect2.pptx
EPE3163_Hydro power stations_Unit2_Lect2.pptx
 
Summer training report on BUILDING CONSTRUCTION for DIPLOMA Students.pdf
Summer training report on BUILDING CONSTRUCTION for DIPLOMA Students.pdfSummer training report on BUILDING CONSTRUCTION for DIPLOMA Students.pdf
Summer training report on BUILDING CONSTRUCTION for DIPLOMA Students.pdf
 
Basic Principle of Electrochemical Sensor
Basic Principle of  Electrochemical SensorBasic Principle of  Electrochemical Sensor
Basic Principle of Electrochemical Sensor
 
Popular-NO1 Kala Jadu Expert Specialist In Germany Kala Jadu Expert Specialis...
Popular-NO1 Kala Jadu Expert Specialist In Germany Kala Jadu Expert Specialis...Popular-NO1 Kala Jadu Expert Specialist In Germany Kala Jadu Expert Specialis...
Popular-NO1 Kala Jadu Expert Specialist In Germany Kala Jadu Expert Specialis...
 
Nodal seismic construction requirements.pptx
Nodal seismic construction requirements.pptxNodal seismic construction requirements.pptx
Nodal seismic construction requirements.pptx
 
Transforming Process Safety Management: Challenges, Benefits, and Transition ...
Transforming Process Safety Management: Challenges, Benefits, and Transition ...Transforming Process Safety Management: Challenges, Benefits, and Transition ...
Transforming Process Safety Management: Challenges, Benefits, and Transition ...
 
Lecture 4 .pdf
Lecture 4                              .pdfLecture 4                              .pdf
Lecture 4 .pdf
 
Technology Features of Apollo HDD Machine, Its Technical Specification with C...
Technology Features of Apollo HDD Machine, Its Technical Specification with C...Technology Features of Apollo HDD Machine, Its Technical Specification with C...
Technology Features of Apollo HDD Machine, Its Technical Specification with C...
 
Lecture 1: Basics of trigonometry (surveying)
Lecture 1: Basics of trigonometry (surveying)Lecture 1: Basics of trigonometry (surveying)
Lecture 1: Basics of trigonometry (surveying)
 
Strategies of Urban Morphologyfor Improving Outdoor Thermal Comfort and Susta...
Strategies of Urban Morphologyfor Improving Outdoor Thermal Comfort and Susta...Strategies of Urban Morphologyfor Improving Outdoor Thermal Comfort and Susta...
Strategies of Urban Morphologyfor Improving Outdoor Thermal Comfort and Susta...
 
Clutches and brkesSelect any 3 position random motion out of real world and d...
Clutches and brkesSelect any 3 position random motion out of real world and d...Clutches and brkesSelect any 3 position random motion out of real world and d...
Clutches and brkesSelect any 3 position random motion out of real world and d...
 
ASME BPVC 2023 Section I para leer y entender
ASME BPVC 2023 Section I para leer y entenderASME BPVC 2023 Section I para leer y entender
ASME BPVC 2023 Section I para leer y entender
 
Quasi-Stochastic Approximation: Algorithm Design Principles with Applications...
Quasi-Stochastic Approximation: Algorithm Design Principles with Applications...Quasi-Stochastic Approximation: Algorithm Design Principles with Applications...
Quasi-Stochastic Approximation: Algorithm Design Principles with Applications...
 
UNIT4_ESD_wfffffggggggggggggith_ARM.pptx
UNIT4_ESD_wfffffggggggggggggith_ARM.pptxUNIT4_ESD_wfffffggggggggggggith_ARM.pptx
UNIT4_ESD_wfffffggggggggggggith_ARM.pptx
 
Gender Bias in Engineer, Honors 203 Project
Gender Bias in Engineer, Honors 203 ProjectGender Bias in Engineer, Honors 203 Project
Gender Bias in Engineer, Honors 203 Project
 
Litature Review: Research Paper work for Engineering
Litature Review: Research Paper work for EngineeringLitature Review: Research Paper work for Engineering
Litature Review: Research Paper work for Engineering
 

Breaking Dependencies Legacy Code - Cork Software Crafters - September 2019

  • 1. Cork Software Crafters Follow us on Twitter: @CorkSwCraft Meetup: www.meetup.com/Cork-Software-Craftsmanship-Meetup Slack: softwarecrafters.slack.com/messages/cork Breaking dependencies in legacy code 24th September 2019 facilitated by Paulo Clavijo Thanks
  • 2. We are always looking for new ideas, new talks and mostly new hands-on sessions for our meetups. Contact us if you want to collaborate!
  • 3. join Software Crafters community on Slack http://slack.softwarecrafters.org
  • 4. follow Cork Software Crafters @CorkSwCraft
  • 5. 6:15pm - Welcome. 6:30pm - Introduction. 6:45pm - Hands-on time. 8:00pm - Retrospective: discuss our solutions, pros and cons. Paulo Clavijo (@pclavijo) Agenda Cork Software Crafters
  • 8. Legacy Code “Code without tests is bad code. It doesn't matter how well written it is; it doesn't matter how pretty or object-oriented or well-encapsulated it is.” - Michael Feathers Paulo Clavijo @pclavijo
  • 9. Legacy Code “Legacy code is valuable code that we’re afraid to change.” - J.B. Rainsberger Paulo Clavijo @pclavijo
  • 10. Legacy Code tends to be: ● Difficult to understand ● Poorly tested suffers from design issues like: ● Tight Coupling ● Low Cohesion ● Feature Envy ● Huge (long modules, classes, methods) ● Risky to change ● Anaemic Domain ● SRP violation
  • 11. The Legacy Code Dilemma “When we have to change code, we should have tests in place. To put tests in place, we often have to change code.” - Michael Feathers
  • 12. Steps to change Legacy Code 1. Identify change points 2. Find testing points 3. Break dependencies if necessary 4. Write tests to cover existing behavior 5. Make the change using TDD what module /component / interface to change
  • 14. The Seam Model A seam is a place where you can alter behavior in your program without editing in that place. Every seam has an enabling point, a place where you can make the decision to use one behavior or another. In most cases, a seam is a method call where the callee can be changed without changing the caller. Source: Working Effectively With Legacy Code, Michael Feathers
  • 15. The Seam Model In object-oriented languages, not all method calls are seams. Is the call to Recalculate an object seam? public class CustomSpreadsheet extends Spreadsheet { public Spreadsheet buildMartSheet() { ... Cell cell = new FormulaCell(this, "A1", "=A2+A3"); ... cell.Recalculate(); ... } ... } Source: Working Effectively With Legacy Code, Michael Feathers No. In this code, we’re creating a cell and then using it in the same method. There is no enabling point. We can’t change which Recalculate method is called because the choice depends on the class of the cell. The class of the cell is decided when the object is created, and we can’t change it without modifying the method.
  • 16. The Seam Model Is the call to Recalculate a seam now? public class CustomSpreadsheet extends Spreadsheet { public Spreadsheet buildMartSheet(Cell cell) { ... cell.Recalculate(); ... } ... } Source: Working Effectively With Legacy Code, Michael Feathers Yes. We can create a CustomSpreadsheet in a test and call buildMartSheet with whatever kind of Cell we want to use. We’ll have ended up varying what the call to cell.Recalculate does without changing the method that calls it. The enabling point is the argument list of buildMartSheet. We can decide what kind of an object to pass and change the behavior of Recalculate any way that we want to for testing.
  • 17. Creating Seams If your code lacks a seam where you need one, the usual solution is to extract a method containing the code you want to alter. Then you can either extend the class and override the method, or move the method to a separate class or interface, and provide the caller with the class or interface. Depending on your programming language, there might be other options such as passing a function or patching the extracted method at runtime.
  • 19. Dependency-Breaking Techniques ● Techniques to decouple classes well enough to get them under test. ● These refactorings are intended to be done without tests, to get tests in place. ● These techniques do not immediately make your design better. ● Help geetting code under test hence your system will be more maintainable.
  • 20. Dependency-Breaking Techniques ● Parameterise Constructor ● Subclass And Override Method ○ Extract And Override Call ○ Extract And Override Factory Method ○ Replace Global Reference With Getter ● Encapsulate Global Reference ● Break Out Method Object ● Extract Pure Functions ● Adapt Parameter ...
  • 21. Parameterise Constructor public class AccountService { private final TransactionLogger logger; public AccountService() { logger = new TransactionLogger(); } public void deposit(Money amount) { … logger.log(transaction) … } } public class AccountService { private final TransactionLogger logger; public AccountService() { this(new TransactionLogger()); } public AccountService(TransactionLogger logger) { this.logger = logger; } public void deposit(Money amount) { … logger.log(transaction) … } }
  • 22. Subclass and Override Method private a() { ... } Class Testing Subclass protected a() { ... } Class @Override protected a() { ... } A core technique for breaking dependencies in OO.
  • 23. Extract And Override Call A way to break dependencies on global variables and static methods. public a() { ... logic ... } Class public a() { ... b() ... } Class protected b() { logic } Testing Subclass @Override protected b() { test logic }
  • 24. Extract And Override Call class Account { ... void deposit(double amount) { this.balance += amount; String depositXml = serializeTransaction(amount); AccountLogger.log(depositXml); rewardPoints += calculateRewardPoints(amount); } ... } class Account { ... void deposit(double amount) { this.balance += amount; String depositXml = serializeTransaction(amount); logTransaction(depositXml); rewardPoints += calculateRewardPoints(amount); } void logTransaction(String transaction) { AccountLogger.log(depositXml); } ... }
  • 25. Extract And Override Factory Method public A() { b = new B() } Class Class protected makeB() { Return new B() } Testing Subclass @Override protected makeB() { ... } public A() { b = makeB() }
  • 26. Replace Global Reference With Getter public a() { ... GLOBAL_X ... } Class public a() { ... getX() ... } Class protected x() { return GLOBAL_X } Testing Subclass @Override protected x() { ... }
  • 27. Break Out Method Object Class New Class longMethod() { ... ... } longMethod(...) { ... ... } b() { … } c() { … } ...
  • 28. Extract Pure Functions Extract Pure Functions to split large methods and classes into smaller ones that we can understand and test. “A pure function is a function that has the following properties: Its return value is the same for the same arguments. Its evaluation has no side effects.” - Wikipedia Using static methods can be a good option in Java
  • 30. Dependency Breaking Katas Cork Software Crafters Paulo Clavijo (@pclavijo) http://bit.ly/2md90q9 We have some legacy code. We need to make changes. To make changes we need to introduce tests first. We might have to change some code to enable testing. We need to introduce so-called Seams (see Michael Feathers' Working Effectively with Legacy Code). Changing code without test is risky, so we want to ● Only change as little code as possible. ● Rely on automated Refactoring tools as much as possible. ● You must not change the public API of the class. by Peter Kofler https://github.com/emilybache/GildedRose-Refactoring-Kata
  • 31. Dependency Breaking Katas Cork Software Crafters Paulo Clavijo (@pclavijo) Assignment A Problem Category The system under test depends on a collaborator with non deterministic behaviour. The collaborator is initialised in the constructor. Task The given code calculates the discount for a purchase in our online shop. The main logic is in Discount. ● Bring Discount under test. Make sure to cover all paths in the core logic. ● There is an existing DiscountTest with a first test case which might or might not work. ● You cannot change MarketingCampaign because it is used by other teams as well. by Peter Kofler https://github.com/emilybache/GildedRose-Refactoring-Kata
  • 32. Dependency Breaking Katas Cork Software Crafters Paulo Clavijo (@pclavijo) Assignment B Problem Category The system under test contains non deterministic behaviour, which is located in a few methods. Task The given MarketingCampaign controls the marketing actions which run on our online shop. During campaigns we e.g. offer discounts. ● Bring MarketingCampaign under test. Make sure to cover all paths in the core logic. ● There is an existing MarketingCampaignTest with a first test case which might or might not work. by Peter Kofler https://github.com/emilybache/GildedRose-Refactoring-Kata
  • 33. Dependency Breaking Katas Cork Software Crafters Paulo Clavijo (@pclavijo) Assignment C Problem Category The system under test depends on a collaborator with database access. The database is not available in our test environment. The collaborator is a static call. Task The given code creates the receipt with the calculated tax for a purchase in our online shop. The main logic is in Checkout. ● Bring Checkout under test. Make sure to cover all paths in the core logic. ● There is an existing CheckoutTest with a first test case which might or might not work. ● You cannot change ReceiptRepository because it is used by other teams as well. by Peter Kofler https://github.com/emilybache/GildedRose-Refactoring-Kata
  • 34. Dependency Breaking Katas Cork Software Crafters Paulo Clavijo (@pclavijo) Assignment D Problem Category The system under test depends on a collaborator with slow behaviour due to a HTTP call. It is not guaranteed that the REST server is available. The collaborator is a Singleton and called multiple times. Task The given code calculates the shipping cost for a purchase depending on the destination in our online shop. The main logic is in ShippingCost. ● Bring ShippingCost under test. Make sure to cover all paths in the core logic. ● There is an existing ShippingCostTest with a first test case which might or might not work. ● You cannot change RestCountriesAPI because it is used by other teams as well. by Peter Kofler https://github.com/emilybache/GildedRose-Refactoring-Kata
  • 35. Dependency Breaking Katas Cork Software Crafters Paulo Clavijo (@pclavijo) Assignment E Problem Category The system under test depends on a collaborator with user interaction. The manual step is not suitable for our test environment. The collaborator is created inside the class. Task The given code collects the necessary user confirmations during a purchase in our online shop. The main logic is in Checkout. ● Bring Checkout under test. Make sure to cover all paths in the core logic. ● There is an existing CheckoutTest with a first test case which might or might not work. by Peter Kofler https://github.com/emilybache/GildedRose-Refactoring-Kata
  • 36. Retrospective ● What went well? ● What problems did you encounter? ● What have you learned? ● What surprised you? Paulo Clavijo (@pclavijo)Cork Software Crafters