SlideShare a Scribd company logo
GreedGreed,,
for lack of a better word,for lack of a better word,
is Goodis Good
Uberto Barbini
@ramtop
LegacyLegacy
My Twitter and Medium handle is
@ramtop
if you know what it means,
either you are a Terry Pratchett fan or...
...you started
programming on
this thing:
The most scary words in a project description:
Brownfield DevelopmentBrownfield Development
➔
Everybody hates itEverybody hates it
➔
Just fix the minimumJust fix the minimum
➔
Necessary EvilNecessary Evil
An Inspiration from Japan
Cost for Feature:
change your line!
Legacy System
Problems
✔ Obsolete technology
✔ Don’t scale to new requirements
✔ Hard to change
✔ Expensive to run and maintain
Technical Debt Default
Working Overload
Temporary
unsafe
solutions
“I fixed it!”
Continuous State of Emergency
We cannot retire it because we don’t
know who is using it..
The Usual Solution
and
Its Problems
Forget the old system!
let’s rewrite it from scratch
shiny and new!
(music) Shiny! Shiny!
Like a treasure from a sunken pirate wreck
Is new always better?
.. and since we are rewriting it we
can add a new feature or two...
c
Hidden costs of rewrite
● Legacy system complexity is always
underestimated because of success bias
● All previous knowledge already in the code,
would be throw away and then slowly (and
costly) rediscovered
● New features can delay the release
● Old system get neglected but still stays critical
● Data migration is always more painful than
expected
Distressing
Position
What’s happen
if you got stuck
between
a neglected legacy
and a not properly
working new system?
Forgetting a
small detail
can be
dangerous..
New Rewrite Left Unfinished
We just need another adapter...
A Different Approach
"Legacy code" often differs from its
suggested alternative by actually
working and scaling
Bjarne Stroustrup
First decide a safe route
The big change will be delivered in small
incremental milestones
Each milestone must:
● Solve at least one problem
● Take a few weeks at most
● Be a stable solution in itself
● Be an improvement on previous version
Safe doesn’t
mean straight!
It could take more
time than a
straight rewrite, at
least apparently.
A little exercise: which steps we can
use for these routes?
● From a C/S application on DBMS to HTML5
with Rest backend running on NoSql
● From monolithic Java backend to Microservices
in different languages
● From several different applications to a
centralized dashboard
● From an MVP website to a SPA rich client
Alchemical Alchemical 
RejuvenationRejuvenation
First you seal everything with First you seal everything with 
external testsexternal tests
Then you split it in modulesThen you split it in modules
Now you clean the module you Now you clean the module you 
need to work withneed to work with
Unit tests help to keep it cleanUnit tests help to keep it clean
Repeat many times if necessaryRepeat many times if necessary
I called this process I called this process 
Alchemical RejuvenationAlchemical Rejuvenation
What really was Alchemy?
Legacy is Good
Step 0:
simplify the on-boarding
Ask your DevOps friends for advice
Wrap it with end to end tests
the important thing about e2e test
is where to put the two ends
Split in modules
Remember to always cut vertically, not horizontally
Refactor Spaghetti Code with gusto!
Then everything is tidy and tested
Time to Restart with Another Module!
...at least if we have to
Visual Recipe
The Technical Part (code examples)
Legacy Code Antipatterns
● Stovepipes
almost identical code in different systems
● Lavaflow
trail of out-of-fashion code from forgotten specs
● Spaghetti
everything depends on everything else
● God class
a class that does way too much
● Intrusive frameworks (Spring, EJB, etc.)
sometimes they are more a problem than a solution
Michael Feathers
Working Effectively with Legacy Code
Refactoring to
Patterns
Joshua
Kerievsky
Hermetic Seal
GOAL Split the code in two 
modules.
HOW Wrap the code you want to 
keep apart behind an interface 
working as Façade
It’s ok if it makes little sense as 
design because we put it there 
only to avoid involuntary 
changes, we can remove it later.
New code can be either inside the 
façade (mocked) or the one calling 
the façade (mocks), but not both.
Original codeprivate ConnHelper connHelper;
private ConfigHelper configHelper;
public Response execute(client, market, trades, connections){
Connection con = connHelper.connect(client, connections);
Context context = con.fetchContext(market);
Portfolio pf = new Portfolio(client, trades);
Options opts = configHelper.getOptions(client, context);
CalcResult res = runCalculations(pf, con, opts, context);
return new Response(context, res);
}
The problem is that we don’t want to touch
Connection and Config in a different module
Step One
Let’s create a new
module and its façade
without changing
anything else
interface DataContext(){
Connection getConnection();
Options getOptions();
Context getContext();
}
private DataContextBuilder newModule;
public ExplainResults execute(client, market, trades, conns){
Portfolio pf = new Portfolio(client, trades);
DataContext dc = newModule.createDataContext(pf, market);
CalcResult r = runCalculations(pf, dc.getConnection(),
dc.getOptions(), dc.getContext());
return new Response(dc.getContext(), r);
}
Step Two
let’s hide Options
looking inside runCalculations where is used:
...
double x = options.calculate(portfolio);
...
Let's expose the method and hide the field
interface DataContext(){
Connection getConnection();
double calculate(Portfolio portfolio);
Context getContext();
}
Step Three
let’s hide Connection
Where it’s used? looking inside runCalculations:
...
newPortfolio =
context.applyTranform(conn, portfolio);
...
Let's do the same. Since Context and Connection are
already in DataContext we don’t need to expose them
interface DataContext(){
double calculate(Portfolio portfolio);
Portfolio applyTranform(Portfolio portfolio);
Context getContext();
}
After
private CalcResult runCalculations(Portfolio portfolio,
DataContext dc) {
//some very complex calculations
Portfolio newPortfolio = dc.applyTranform(portfolio);
//others very complex calculations
double x = dc.calculate(newPortfolio);
return CalcResult.success(x);
}
private CalcResult runCalculations(Portfolio portfolio,
Connection conn, Options opts, Context context) {
//some very complex calculations
Portfolio newPortfolio = context.applyTranform(conn,
portfolio);
//others very complex calculations
double x = opts.calculate(newPortfolio);
return CalcResult.success(x);
}
Before
Finished!
private DataContextBuilder newModule; //injected with CP
public Response execute(client, market, trades){
Portfolio pf = new Portfolio(client, trades);
DataContext dc = newModule.createDataContext(market);
CalcResult r = runCalculations(pf, dc);
return new CalcResults(dc, r);
}
Now we can test execute in insulation. We can do
the same everywhere Connections and Options are
used.
We can remove connectionPool parameter as well
Solve Et Coagula
GOAL Simplify the 
interactions in a group of 
closely related classes.
HOW Transform all the 
methods in all the classes to 
static ones. Then refactor 
them trying to reduce the 
number of parameters. Then 
move them to the closest class 
and make them non static.
The original code
public class Main {
public static void main(String[] args){
Address a = new Address("777 No Street",
"London, Uk", "WWW-777");
Client c = new Client("Mr", "James
Bond", a);
Printer p = new Printer();
Label label = new Label(p, a);
p.printLabel(c, label);
}
}
output
+---------------+
| Mr James Bond |
| 777 No Street |
| London, Uk |
| WWW-777 |
+---------------+
public class Client {
public Address address;
public String title;
public String fullName;
public Client(String title, String fullname, Address address) {
this.title = title;
this.fullName = fullname;
this.address = address;
this.address.client = this;
}
}
public class Printer {
public void printLabel(Client u, Label l){
if (u != null && u.address != null)
l.sendToPrinter();
}
public void printLine(String line){
System.out.println(line); //simulate sending
}
}
public class Address {
public Client client;
private String street;
private String city;
private String areaCode;
public Address(String street, String city, String areaCode) {
this.street = street;
this.city = city;
this.areaCode = areaCode;
}
public String[] getLines() {
String[] lines = new String[4];
lines[0] = client.title + " " + client.fullName;
lines[1] = street;
lines[2] = city;
lines[3] = areaCode;
return lines;
}
}
public class Label {
private Address address;
private Printer printer;
public Label(Printer printer, Address address) {
this.printer = printer;
this.address = address;
}
public void sendToPrinter() {
int mx = 0;
for (String line : address.getLines()) {
mx = mx > line.length() ? mx: line.length();
}
String side = "+" + createString(mx - 2, "-") + "+";
printer.printLine(side);
for (String line : address.getLines()) {
String spaces = createString(mx - line.length() - 4, " ");
printer.printLine("| " + line + spaces + " |");
}
printer.printLine(side);
}
private String createString(int length, String ofChar) {
return new String(new char[length + 4]).replace("0", ofChar);
}
}
Step One - Solve
all methods become static in a new class
private fields stay in the class
public class Functions {
public static String[] getLines(Address a) {…}
public static void sendToPrinter(Address a,
Printer p) {…}
public static void printLabel(Client u, Printer
p){…}
public static void printLine(Printer p, String
line){…}
}
Step Two - Coagula
public class Client {
…
public String[] getLines() {…}
}
public class Label {
…
public static void print(Printer p, Client c){…}
}
public class Printer {
…
public void printLine(String line){…}
}
Methods go back to the closest class, or
stay static if no such class exists.
A possible final result
public class Main {
public static void main(String[] args){
Address a = new Address("777 No Street",
"London, Uk", "WWW-777");
Client c = new Client("Mr","James Bond",a);
Printer p = new Printer("usb");
Label.print(p, c);
}
}
The complete code for these examples and others
can be found at:
https://github.com/uberto/alchemical
Legacy can be Good!
The Real Software Architect
An Ounce of
Prevention
Is Worth a Pound of
Cure
Legacy degradation:
Slow Boiling Frog
Further degration: Law of Broken Windows
To invert entropy
Plan the whole lifecycle
each module should specify also
who is using it and how to remove it
if you have to.
Vitruvius
Three principles of good Architecture
If you are interested contact me!
I’d love to hear experiences
I am collecting material for a book
Please follow me
@ramtop
medium.com/@ramtop
www.gama-soft.co.uk

More Related Content

PDF
Algorithm and Programming (Looping Structure)
PDF
Contracts in Ruby - Vladyslav Hesal
PDF
Diffing Shotgun Surgery and Divergent Change smells in the two editions of Re...
PDF
Clean code
PDF
C# for-java-developers
PDF
Deep C
PDF
Algorithm and Programming (Branching Structure)
PDF
C interview-questions-techpreparation
Algorithm and Programming (Looping Structure)
Contracts in Ruby - Vladyslav Hesal
Diffing Shotgun Surgery and Divergent Change smells in the two editions of Re...
Clean code
C# for-java-developers
Deep C
Algorithm and Programming (Branching Structure)
C interview-questions-techpreparation

What's hot (20)

KEY
What's New In Python 2.5
PDF
Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...
KEY
What's New In Python 2.4
PPTX
Powerpoint presentation final requirement in fnd prg
PPTX
5. using variables, data, expressions and constants
PPTX
Final requirement in programming niperos
PDF
Miranda NG Project to Get the "Wild Pointers" Award (Part 1)
PPT
09 Methods
PPTX
Final requirement in programming
PDF
Algorithm and Programming (Procedure and Function)
PDF
Polymorphism
PDF
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
PDF
C faqs interview questions placement paper 2013
PDF
Highly Strung
PDF
Generics
PPT
Polymorphism in c++ ppt (Powerpoint) | Polymorphism in c++ with example ppt |...
PPTX
Switch case and looping new
PDF
Антихрупкий TypeScript | Odessa Frontend Meetup #17
PPTX
Final requirement in programming vinson
PPSX
C++ Programming Language
What's New In Python 2.5
Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...
What's New In Python 2.4
Powerpoint presentation final requirement in fnd prg
5. using variables, data, expressions and constants
Final requirement in programming niperos
Miranda NG Project to Get the "Wild Pointers" Award (Part 1)
09 Methods
Final requirement in programming
Algorithm and Programming (Procedure and Function)
Polymorphism
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
C faqs interview questions placement paper 2013
Highly Strung
Generics
Polymorphism in c++ ppt (Powerpoint) | Polymorphism in c++ with example ppt |...
Switch case and looping new
Антихрупкий TypeScript | Odessa Frontend Meetup #17
Final requirement in programming vinson
C++ Programming Language
Ad

Similar to Legacy is Good (20)

PDF
Presentation on design pattern software project lll
PPT
Clean code _v2003
PPTX
SPF Getting Started - Console Program
PPTX
Getting Started - Console Program and Problem Solving
PPTX
Intro to programing with java-lecture 3
PPT
Refactoring Tips by Martin Fowler
PPTX
Chapter 2.4
PDF
C++ Course - Lesson 1
PDF
Clean Code 2
PPT
3 algorithm-and-flowchart
DOCX
JLK Chapter 5 – Methods and ModularityDRAFT January 2015 Edition.docx
PDF
Basic c# cheat sheet
PPTX
Clean code
DOCX
Let's us c language (sabeel Bugti)
PPT
2.overview of c++ ________lecture2
PDF
Of complicacy of programming, or won't C# save us?
PPT
Ralf Laemmel - Not quite a sales pitch for C# 3.0 and .NET's LINQ - 2008-03-05
PDF
Addressing Scenario
PPT
C++ Function
PPTX
Presentation on design pattern software project lll
Clean code _v2003
SPF Getting Started - Console Program
Getting Started - Console Program and Problem Solving
Intro to programing with java-lecture 3
Refactoring Tips by Martin Fowler
Chapter 2.4
C++ Course - Lesson 1
Clean Code 2
3 algorithm-and-flowchart
JLK Chapter 5 – Methods and ModularityDRAFT January 2015 Edition.docx
Basic c# cheat sheet
Clean code
Let's us c language (sabeel Bugti)
2.overview of c++ ________lecture2
Of complicacy of programming, or won't C# save us?
Ralf Laemmel - Not quite a sales pitch for C# 3.0 and .NET's LINQ - 2008-03-05
Addressing Scenario
C++ Function
Ad

More from Uberto Barbini (9)

ODP
CQRS with Event Source in Functional sauce served by Kotlin
PDF
Go kotlin, Go!
PDF
It's All About Morphisms
PDF
The Role of Testing in DevOps
PDF
When Tdd Goes Awry (IAD 2013)
PDF
When Tdd Goes Awry
PDF
Boost your-oop-with-fp
PDF
The Effective Team
PDF
Develop Gwt application in TDD
CQRS with Event Source in Functional sauce served by Kotlin
Go kotlin, Go!
It's All About Morphisms
The Role of Testing in DevOps
When Tdd Goes Awry (IAD 2013)
When Tdd Goes Awry
Boost your-oop-with-fp
The Effective Team
Develop Gwt application in TDD

Recently uploaded (20)

PDF
Types of Token_ From Utility to Security.pdf
PDF
DuckDuckGo Private Browser Premium APK for Android Crack Latest 2025
PDF
Cost to Outsource Software Development in 2025
PPTX
Trending Python Topics for Data Visualization in 2025
PPTX
Advanced SystemCare Ultimate Crack + Portable (2025)
DOCX
Modern SharePoint Intranet Templates That Boost Employee Engagement in 2025.docx
PDF
AI Guide for Business Growth - Arna Softech
PDF
Designing Intelligence for the Shop Floor.pdf
DOCX
How to Use SharePoint as an ISO-Compliant Document Management System
PDF
The Dynamic Duo Transforming Financial Accounting Systems Through Modern Expe...
PPTX
Introduction to Windows Operating System
PDF
Product Update: Alluxio AI 3.7 Now with Sub-Millisecond Latency
PPTX
Monitoring Stack: Grafana, Loki & Promtail
PDF
How Tridens DevSecOps Ensures Compliance, Security, and Agility
PDF
CCleaner 6.39.11548 Crack 2025 License Key
PDF
Multiverse AI Review 2025: Access All TOP AI Model-Versions!
PPTX
"Secure File Sharing Solutions on AWS".pptx
PPTX
Why Generative AI is the Future of Content, Code & Creativity?
PDF
Website Design Services for Small Businesses.pdf
PDF
Microsoft Office 365 Crack Download Free
Types of Token_ From Utility to Security.pdf
DuckDuckGo Private Browser Premium APK for Android Crack Latest 2025
Cost to Outsource Software Development in 2025
Trending Python Topics for Data Visualization in 2025
Advanced SystemCare Ultimate Crack + Portable (2025)
Modern SharePoint Intranet Templates That Boost Employee Engagement in 2025.docx
AI Guide for Business Growth - Arna Softech
Designing Intelligence for the Shop Floor.pdf
How to Use SharePoint as an ISO-Compliant Document Management System
The Dynamic Duo Transforming Financial Accounting Systems Through Modern Expe...
Introduction to Windows Operating System
Product Update: Alluxio AI 3.7 Now with Sub-Millisecond Latency
Monitoring Stack: Grafana, Loki & Promtail
How Tridens DevSecOps Ensures Compliance, Security, and Agility
CCleaner 6.39.11548 Crack 2025 License Key
Multiverse AI Review 2025: Access All TOP AI Model-Versions!
"Secure File Sharing Solutions on AWS".pptx
Why Generative AI is the Future of Content, Code & Creativity?
Website Design Services for Small Businesses.pdf
Microsoft Office 365 Crack Download Free

Legacy is Good