SlideShare a Scribd company logo
1 of 39
How I learned to stop
worrying and love LEGACY CODE
- Mike Harris -
The Plan
• Introduce myself
• Legacy code
– Definition
– Causes
– Effects
– What we could do about it
– What we should do about it
• Sum up
• Discuss and answer questions
About me
• Got into home computers in the 1980s.
• Wrote a Fractal generator in GFA BASIC on Atari ST.
• Messed up my A levels.
• Managed to get on a computing degree ;)
• Got into Linux in early 90s.
• Set up a company to promote Free Software.
• We wrote our own CMS in Cold Fusion, then in Perl.
• Since worked as a software engineer, and IT in general.
• Found out about XP and Agile. Realised I was more of a
hacker than a software engineer.
• Joined Elsevier and SSRN in April this year.
• Now working with ColdFusion again!
About SSRN
We are a freely accessible
repository of abstracts and
pre-print full-text papers…
…and a community where
researchers can shape the
thinking in their fields
SSRN is an open access research repository
and a community for researchers
Things I’ve been heard saying…
• “The code is really awful!”
• “It takes so long to make changes!”
• “We’re always introducing bugs!”
• “We’ve no idea what this bit does!”
• “Bob is away!”
• “We hate it!”
• “We need to rewrite the whole damn thing!”
What is legacy code?
What is legacy code?
Legacy– adjective
“of, relating to, or being a previous or outdated computer
system.” – Merriam-Webster
A more recent definition in Software Engineering is…
“Source code inherited from someone else and/or source
code inherited from an older version of the software”
Michael Feathers in Working Effectively with Legacy Code
names it as “Code without tests”
Legacy code as technical debt
Technical debt
quadrant
- Martin Fowler
"As an evolving program is continually changed, its complexity, reflecting
deteriorating structure, increases unless work is done to maintain or reduce it.”
— Meir Manny Lehman, 1980
A lot of legacy
code
is to be
found here
“Bad code isn't Technical Debt, it's an unhedged Call Option”
- Steve Freeman , 2010
What is legacy code
to an organisation?
• A lot of investment.
• Models business processes.
• History of the enterprise.
• Where we are today.
• It “works”.
• But it can be a pain to maintain and extend.
What hints at legacy code?
• Unnecessary or misleading comments.
• Poor or obtuse naming of things.
• Large number of calling parameters.
• Multiple code paths in single functions.
• Functions with side-effects.
• Long and unstructured code.
• Poorly scoped variables.
• A lack of tests.
sub check_login {
my ($query, $pathinfo, $dbh) = @_;
my $login_email = $query->param($AUTH_USER_FIELD);
my $login_pass = $query->param($AUTH_PASSWORD_FIELD);
my ($statement, $sth, $id, $login, $admin_level, $cookie);
$statement = qq{SELECT id FROM $AUTH_DB_TABLE
WHERE $AUTH_USER_FIELD = '$login_email'
AND $AUTH_PASSWORD_FIELD = '$login_pass'};
$sth = $dbh->prepare($statement);
$sth->execute or die("Unable to execute $statement", $dbh->errstr);
$sth->finish;
# get the count of rows in the database
# $x is the row count going forwards
if ($sth->rows eq 0) {
ChangingPages->fetch_page(APP_OPTIONS => %APP_OPTIONS,
QUERY => $query,
FILE_NAME => $pathinfo . $query->param('_error_page'),
);
return;
}
$statement = qq{ SELECT id, $AUTH_USER_FIELD, admin_level FROM $AUTH_DB_TABLE WHERE
$AUTH_USER_FIELD = '$login_email'
AND $AUTH_PASSWORD_FIELD = '$login_pass'
AND (TO_DAYS(NOW()) - TO_DAYS(last_mod_pwd))
< $MAX_PASSWORD_EXPIRY };
$sth = $dbh->prepare($statement);
$sth->execute or die("Unable to execute $statement", $dbh->errstr);
if ($sth->rows eq 0) {
$sth->finish;
&display_change_passwd;
return;
}
$sth->bind_columns(undef, $id, $login, $admin_level);
$sth->fetch;
$sth->finish;
Closely coupled
Side-effect
Inelegant error
handling
SQL Injection?
Poor naming
Misleading
Comment
What is legacy about this Perl code?
Passing global
arrays around
Open to hacking
source HTML?
Pretty much all
of it!
There are no
tests either!
The causes of Legacy Code
The causes of legacy code
• Old programming languages & the way we used them.
• Old methodologies.
• New methodologies not well understood.
• Tasks done under pressure.
• Hacks in code to solve bugs.
• Not knowing any better – “we’ve always done it that
way, and it works for us”.
• Knowledge silos: solo programmers on one code area.
• Rigid designs.
Legacy code is language agnostic
• Legacy code isn’t necessarily code written in
BASIC, COBOL, ColdFusion, Fortran, Algol, or
even Perl.
• It can be written in even the most up to date
coolest programming language.
• Replacing your COBOL or ColdFusion code
with Java, Go, Groovy, Kotlin, ReactJS, or Scala
doesn’t stop legacy code being written.
Descriptive
naming
Structured
COBOL example
Identification division.
program-id. Stack.
*> Implements a stack in COBOL
*> Operators are: Pop, Push, and Peek
data division.
working-storage section.
01 StackTable is global.
02 StackItem pic x(20) occurs 1 to 50 times.
01 ItemsInStack pic 99 value zero is global.
linkage section.
01 Command pic x any length.
01 Item pic x any length.
procedure division using Command, Item.
Main section.
evaluate function trim(Command)
when "Push" perform PushItemOntoStack
when "Pop" perform PopItemOffStack
when "Peek" perform PeekWhichItemIsOnTopOfStack
end-evaluate
goback
.
PushItemOntoStack section.
add 1 to ItemsInStack
move Item to StackItem(ItemsInStack)
.
PeekWhichItemIsOnTopOfStack section.
move StackItem(ItemsInStack) to Item
.
PopItemOffStack section.
if ItemsInStack less than 1 then
move spaces to Item
else
move StackItem(ItemsInStack) to Item
move spaces to StackItem(ItemsInStack)
subtract 1 from ItemsInStack
end-if
.
end program Stack.
identification division.
program-id. StackTest.
*> A simple stack in COBOL
data division.
working-storage section.
01 Item pic x(10) value spaces.
01 Result pic x(10) value spaces.
procedure division.
TestShouldPopPushedItemsInReverseOrder.
*> Given
move "hello" to Item
call "Stack" using by content "Push", by content Item
move "hola" to Item
call "Stack" using by content "Push", by content Item
move "bonjour" to Item
call "Stack" using by content "Push", by content Item
*> When
call "Stack" using by content "Pop", by reference Result
*> Then
call "AssertEquals" using Result,
"bonjour", "Returned 3rd value put on stack”
*> When
call "Stack" using by content "Pop", by reference Result
*>Then
call "AssertEquals" using Result,
"hola", "Returned 2nd value put on stack”
Test Driven
The effects of legacy code
How it affects the developers
• Changes take a long time.
• Changes are risky.
• Bugs are introduced.
• Hacking makes things worse.
• Working with it is frustrating.
• Time pressures lead to stress.
• .. and more hacks
• The team has no real control over their software.
– If it’s hard or impossible to change, then it’s not really
software..
• It is demoralising.
How it affects the business
• New work can take longer than expected.
• New work is difficult to estimate.
• Changes can introduce bugs. Customer
experience and trust is reduced, more wasted
time, more cost.
• Specialisations in the code cause delays.
• Specialisations in the code are risks.
What can we do about legacy code?
What can we do about legacy code?
• Stop writing it!
• Yeah right; what can we really do about it?
• Fire everyone and get a new team!
• Leave the job and go and work somewhere
where they aren’t writing legacy code!
• Throw everything we’ve done away and start
again using something cool to do it in!
– Let’s look at this last option….
TOTAL
REWRITE
The Total Rewrite plan….
• “We’ll put a team together to re-write all the
code in a modern up-to-date framework,
language, paradigm, cloud-based-thingy.”
• “We’ll maintain the old system until the new
system is done.”
• “The spec is that the new system must do at
least everything the old system does.”
Pitfalls of the Total Rewrite
• It costs money to seemingly stand still.
• Changes to both systems; Zeno’s Paradox.
• Do you re-implement the bugs?
• The old legacy code doesn’t improve.
• Delivery pressures leading to new legacy code.
• Will you run two teams?
• What if we never make it?
Change attitude
• Stop hating the code.
• Stop blaming others (or yourself) for writing it.
• Accept that it’s where we are.
• Don’t run away from it.
• Stop ignoring it.
• Believe that it can be improved.
• Person up and deal with it.
• Make it better.
Improve our toolset & practices
• Use TDD. Improve & replace bad tests.
• Refactor code to make life easier for you; learn
refactoring techniques and patterns.
• Code standards, styles, patterns, approaches.
• IDE and other tools.
• Find seams to replace or improve parts of it.
• Employ pair or mob programming.
Use seams, slices & stranglers
• Introduce seams in the code.
• Extend the legacy code, wrapping it to extend
functionality.
• Create slices of functionality in new code.
• Strangler Pattern (Martin Fowler) – build a
framework around existing system and
gradually exterminate it.
Refactor it
• Refactor continuously. No story needed.
• Once your code passes the test, spend a little longer to
improve it.
• Get rid of useless or misleading comments.
• Rename variables and functions to be self-
documenting.
• Break up lengthy code.
• Work towards one function doing one thing.
• Encapsulate common code and data into classes.
• Abstract resources from main code; de-couple.
• If you cannot write any tests, try harder!
sub check_login {
my ($query, $pathinfo, $dbh) = @_;
my $login_email = $query->param($AUTH_USER_FIELD);
my $login_pass = $query->param($AUTH_PASSWORD_FIELD);
my ($statement, $sth, $id, $login, $admin_level, $cookie);
$statement = qq{SELECT id FROM $AUTH_DB_TABLE
WHERE $AUTH_USER_FIELD = '$login_email'
AND $AUTH_PASSWORD_FIELD = '$login_pass'};
$sth = $dbh->prepare($statement);
$sth->execute or die("Unable to execute $statement", $dbh->errstr);
$sth->finish;
# get the count of rows in the database
# $x is the row count going forwards
if ($sth->rows eq 0) {
ChangingPages->fetch_page(APP_OPTIONS => %APP_OPTIONS,
QUERY => $query,
FILE_NAME => $pathinfo . $query->param('_error_page'),
);
return;
}
$statement = qq{ SELECT id, $AUTH_USER_FIELD, admin_level FROM $AUTH_DB_TABLE WHERE
$AUTH_USER_FIELD = '$login_email'
AND $AUTH_PASSWORD_FIELD = '$login_pass'
AND (TO_DAYS(NOW()) - TO_DAYS(last_mod_pwd))
< $MAX_PASSWORD_EXPIRY };
$sth = $dbh->prepare($statement);
$sth->execute or die("Unable to execute $statement", $dbh->errstr);
if ($sth->rows eq 0) {
$sth->finish;
&display_change_passwd;
return;
}
$sth->bind_columns(undef, $id, $login, $admin_level);
$sth->fetch;
$sth->finish;
So what could we do with this?
We could write some
high-level tests in Gherkin
Given I visit the login page
And I enter a valid username
And I enter a valid password
When I click the login button
Then I am taken to the home page
Given My user login password has expired
And I visit the login page
And I enter a valid username
And I enter a valid password
When I click the login button
Then I am taken to the change password page
Given I visit the login page
And I enter an invalid username
And I enter a valid password
When I click the login button
Then I am taken to the login failed page
Given I visit the login page
And I enter a valid username
And I enter an invalid password
When I click the login button
Then I am taken to the login failed page
We could extract domain functionality
into classes with tests
sub check_login {
my ($query, $pathinfo, $dbh) = @_;
my $login_email = $query->param($AUTH_USER_FIELD);
my $login_pass = $query->param($AUTH_PASSWORD_FIELD);
my ($statement, $sth, $id, $login, $admin_level, $cookie);
$statement = qq{SELECT id FROM $AUTH_DB_TABLE
WHERE $AUTH_USER_FIELD = '$login_email'
AND $AUTH_PASSWORD_FIELD = '$login_pass'};
$sth = $dbh->prepare($statement);
$sth->execute or die("Unable to execute $statement", $dbh->errstr);
$sth->finish;
# get the count of rows in the database
# $x is the row count going forwards
if ($sth->rows eq 0) {
ChangingPages->fetch_page(APP_OPTIONS => %APP_OPTIONS,
QUERY => $query,
FILE_NAME => $pathinfo . $query->param('_error_page'),
);
return;
}
$statement = qq{ SELECT id, $AUTH_USER_FIELD, admin_level FROM $AUTH_DB_TABLE WHERE
$AUTH_USER_FIELD = '$login_email'
AND $AUTH_PASSWORD_FIELD = '$login_pass'
AND (TO_DAYS(NOW()) - TO_DAYS(last_mod_pwd))
< $MAX_PASSWORD_EXPIRY };
$sth = $dbh->prepare($statement);
$sth->execute or die("Unable to execute $statement", $dbh->errstr);
if ($sth->rows eq 0) {
$sth->finish;
&display_change_passwd;
return;
}
$sth->bind_columns(undef, $id, $login, $admin_level);
$sth->fetch;
$sth->finish;
We can end up
with more readable code
Take on Technical Debt knowingly
• It’s about knowing what the risks are
• Keep a Tech Debt Wall
• Note down any technical debt you accrue as you
develop
• Consider the risk of postponing resolution vs the cost
of sorting now
• Don’t engineer the future: resolve in the next iteration
• Regularly review the Tech Debt Wall
• Categorise the debt on the wall
• Take highest risk technical debt into backlog and
resolve
Tech Debt Wall example
What the business can do to help
• Understand that it will take time to sort out.
• Ensure the product pipeline accounts for it.
• Support training and coaching for the team.
• Create a safe environment.
• Alleviate pressures.
• Appreciate that
– some people will be more resistant to change.
– people learn in different ways
– people learn at different speeds.
– some people will not (want to) change.
How I learned to love legacy code
• I realised it’s an asset.
• I realised it needs caring for, and improving.
• I realised we shouldn’t blame ourselves or others.
• I realised we had to own the code.
• I realised we could have pride about it.
• I realised we could and had to make it better.
• I realised the Big Rewrite is tempting, but risky.
• I realised the right tools & practices really help.
Here’s a list of a few books
• Working Effectively With Legacy Code – Michael Feathers (2004)
• Clean Code – Robert C Martin (2008)
• The Clean Coder – Robert C Martin (2011)
• Beyond Legacy Code – David Scott Bernstein (2015)
• Lean Software Development – Mary & Tom Poppendieck (2003)
• Refactoring: Improving the Design of Existing Code
– Martin Fowler, Kent Beck, et al (1999, 2018)
• Refactoring Databases: Evolutionary Database Design
– Scott J Ambler & Pramod J Sadalage (2006)
• Head First Design Patterns - Eric Freeman, et al (2014)
• Domain-Driven Design: Tackling Complexity in the Heart of Software
– Eric Evans (2003)
STOP RUN.
Thank You
07811 671 893
m.harris@elsevier.com
https://www.ssrn.com
http://uk.linkedin.com/in/mbharris
https://github.com/mikebharris/
© 2017-2018 Mike Harris under GNU FDL 1.3

More Related Content

What's hot

Actor Patterns and NATS - Boulder Meetup
Actor Patterns and NATS - Boulder MeetupActor Patterns and NATS - Boulder Meetup
Actor Patterns and NATS - Boulder MeetupApcera
 
A gentle introduction into AKKA and the actor model
A gentle introduction into AKKA and the actor modelA gentle introduction into AKKA and the actor model
A gentle introduction into AKKA and the actor modelMykhailo Kotsur
 
Malicious Intent: Adventures in JavaScript Obfuscation and Deobfuscation
Malicious Intent: Adventures in JavaScript Obfuscation and DeobfuscationMalicious Intent: Adventures in JavaScript Obfuscation and Deobfuscation
Malicious Intent: Adventures in JavaScript Obfuscation and DeobfuscationHeadlessZeke
 
PowerShell - Be A Cool Blue Kid
PowerShell - Be A Cool Blue KidPowerShell - Be A Cool Blue Kid
PowerShell - Be A Cool Blue KidMatthew Johnson
 
Metaprogramming JavaScript
Metaprogramming  JavaScriptMetaprogramming  JavaScript
Metaprogramming JavaScriptdanwrong
 
The Actor Model - Towards Better Concurrency
The Actor Model - Towards Better ConcurrencyThe Actor Model - Towards Better Concurrency
The Actor Model - Towards Better ConcurrencyDror Bereznitsky
 
Work Queues
Work QueuesWork Queues
Work Queuesciconf
 
Actors and Threads
Actors and ThreadsActors and Threads
Actors and Threadsmperham
 
Modeling Tricks My Relational Database Never Taught Me
Modeling Tricks My Relational Database Never Taught MeModeling Tricks My Relational Database Never Taught Me
Modeling Tricks My Relational Database Never Taught MeDavid Boike
 
Formatting ForThe Masses
Formatting ForThe MassesFormatting ForThe Masses
Formatting ForThe MassesHolger Schill
 
SOLID, DRY, SLAP design principles
SOLID, DRY, SLAP design principlesSOLID, DRY, SLAP design principles
SOLID, DRY, SLAP design principlesSergey Karpushin
 
Day 2 - Intro to Rails
Day 2 - Intro to RailsDay 2 - Intro to Rails
Day 2 - Intro to RailsBarry Jones
 
Php melb cqrs-ddd-predaddy
Php melb cqrs-ddd-predaddyPhp melb cqrs-ddd-predaddy
Php melb cqrs-ddd-predaddyDouglas Reith
 
Testing swagger contracts without contract based testing
Testing swagger contracts without contract based testingTesting swagger contracts without contract based testing
Testing swagger contracts without contract based testingАлексей Стягайло
 

What's hot (20)

Actor Patterns and NATS - Boulder Meetup
Actor Patterns and NATS - Boulder MeetupActor Patterns and NATS - Boulder Meetup
Actor Patterns and NATS - Boulder Meetup
 
A gentle introduction into AKKA and the actor model
A gentle introduction into AKKA and the actor modelA gentle introduction into AKKA and the actor model
A gentle introduction into AKKA and the actor model
 
Zen of Akka
Zen of AkkaZen of Akka
Zen of Akka
 
Malicious Intent: Adventures in JavaScript Obfuscation and Deobfuscation
Malicious Intent: Adventures in JavaScript Obfuscation and DeobfuscationMalicious Intent: Adventures in JavaScript Obfuscation and Deobfuscation
Malicious Intent: Adventures in JavaScript Obfuscation and Deobfuscation
 
PowerShell - Be A Cool Blue Kid
PowerShell - Be A Cool Blue KidPowerShell - Be A Cool Blue Kid
PowerShell - Be A Cool Blue Kid
 
DSLs in JavaScript
DSLs in JavaScriptDSLs in JavaScript
DSLs in JavaScript
 
Metaprogramming JavaScript
Metaprogramming  JavaScriptMetaprogramming  JavaScript
Metaprogramming JavaScript
 
The Actor Model - Towards Better Concurrency
The Actor Model - Towards Better ConcurrencyThe Actor Model - Towards Better Concurrency
The Actor Model - Towards Better Concurrency
 
Work Queues
Work QueuesWork Queues
Work Queues
 
Actors and Threads
Actors and ThreadsActors and Threads
Actors and Threads
 
Akka Fundamentals
Akka FundamentalsAkka Fundamentals
Akka Fundamentals
 
Modeling Tricks My Relational Database Never Taught Me
Modeling Tricks My Relational Database Never Taught MeModeling Tricks My Relational Database Never Taught Me
Modeling Tricks My Relational Database Never Taught Me
 
Xtext Best Practices
Xtext Best PracticesXtext Best Practices
Xtext Best Practices
 
Formatting ForThe Masses
Formatting ForThe MassesFormatting ForThe Masses
Formatting ForThe Masses
 
SOLID, DRY, SLAP design principles
SOLID, DRY, SLAP design principlesSOLID, DRY, SLAP design principles
SOLID, DRY, SLAP design principles
 
Day 2 - Intro to Rails
Day 2 - Intro to RailsDay 2 - Intro to Rails
Day 2 - Intro to Rails
 
Design patterns
Design patternsDesign patterns
Design patterns
 
Php melb cqrs-ddd-predaddy
Php melb cqrs-ddd-predaddyPhp melb cqrs-ddd-predaddy
Php melb cqrs-ddd-predaddy
 
Testing swagger contracts without contract based testing
Testing swagger contracts without contract based testingTesting swagger contracts without contract based testing
Testing swagger contracts without contract based testing
 
Web Development with Smalltalk
Web Development with SmalltalkWeb Development with Smalltalk
Web Development with Smalltalk
 

Similar to How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018

How I Learned to Stop Worrying and Love Legacy Code.....
How I Learned to Stop Worrying and Love Legacy Code.....How I Learned to Stop Worrying and Love Legacy Code.....
How I Learned to Stop Worrying and Love Legacy Code.....Mike Harris
 
Guide to Destroying Codebases The Demise of Clever Code
Guide to Destroying Codebases   The Demise of Clever CodeGuide to Destroying Codebases   The Demise of Clever Code
Guide to Destroying Codebases The Demise of Clever CodeGabor Varadi
 
New Ideas for Old Code - Greach
New Ideas for Old Code - GreachNew Ideas for Old Code - Greach
New Ideas for Old Code - GreachHamletDRC
 
Introduction to the intermediate Python - v1.1
Introduction to the intermediate Python - v1.1Introduction to the intermediate Python - v1.1
Introduction to the intermediate Python - v1.1Andrei KUCHARAVY
 
Clean code, Feb 2012
Clean code, Feb 2012Clean code, Feb 2012
Clean code, Feb 2012cobyst
 
Chelberg ptcuser 2010
Chelberg ptcuser 2010Chelberg ptcuser 2010
Chelberg ptcuser 2010Clay Helberg
 
advancedzplmacroprogramming_081820.pptx
advancedzplmacroprogramming_081820.pptxadvancedzplmacroprogramming_081820.pptx
advancedzplmacroprogramming_081820.pptxssuser6a1dbf
 
Working Effectively With Legacy Perl Code
Working Effectively With Legacy Perl CodeWorking Effectively With Legacy Perl Code
Working Effectively With Legacy Perl Codeerikmsp
 
Behaviour driven development
Behaviour driven developmentBehaviour driven development
Behaviour driven developmentFraboni Ec
 
Behaviour driven development
Behaviour driven developmentBehaviour driven development
Behaviour driven developmentHarry Potter
 
Behaviour drivendevelopment
Behaviour drivendevelopmentBehaviour drivendevelopment
Behaviour drivendevelopmentYoung Alista
 
Behaviour driven development
Behaviour driven developmentBehaviour driven development
Behaviour driven developmentTony Nguyen
 
Behaviour driven development
Behaviour driven developmentBehaviour driven development
Behaviour driven developmentJames Wong
 
Behaviour drivendevelopment
Behaviour drivendevelopmentBehaviour drivendevelopment
Behaviour drivendevelopmentHoang Nguyen
 
Behaviour drivendevelopment
Behaviour drivendevelopmentBehaviour drivendevelopment
Behaviour drivendevelopmentLuis Goldster
 
Agile experiments in Machine Learning with F#
Agile experiments in Machine Learning with F#Agile experiments in Machine Learning with F#
Agile experiments in Machine Learning with F#J On The Beach
 
Intro to JavaScript
Intro to JavaScriptIntro to JavaScript
Intro to JavaScriptDan Phiffer
 

Similar to How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018 (20)

How I Learned to Stop Worrying and Love Legacy Code.....
How I Learned to Stop Worrying and Love Legacy Code.....How I Learned to Stop Worrying and Love Legacy Code.....
How I Learned to Stop Worrying and Love Legacy Code.....
 
Guide to Destroying Codebases The Demise of Clever Code
Guide to Destroying Codebases   The Demise of Clever CodeGuide to Destroying Codebases   The Demise of Clever Code
Guide to Destroying Codebases The Demise of Clever Code
 
New Ideas for Old Code - Greach
New Ideas for Old Code - GreachNew Ideas for Old Code - Greach
New Ideas for Old Code - Greach
 
Introduction to the intermediate Python - v1.1
Introduction to the intermediate Python - v1.1Introduction to the intermediate Python - v1.1
Introduction to the intermediate Python - v1.1
 
Clean code, Feb 2012
Clean code, Feb 2012Clean code, Feb 2012
Clean code, Feb 2012
 
Code Refactoring
Code RefactoringCode Refactoring
Code Refactoring
 
Chelberg ptcuser 2010
Chelberg ptcuser 2010Chelberg ptcuser 2010
Chelberg ptcuser 2010
 
advancedzplmacroprogramming_081820.pptx
advancedzplmacroprogramming_081820.pptxadvancedzplmacroprogramming_081820.pptx
advancedzplmacroprogramming_081820.pptx
 
Working Effectively With Legacy Perl Code
Working Effectively With Legacy Perl CodeWorking Effectively With Legacy Perl Code
Working Effectively With Legacy Perl Code
 
Refactoring
RefactoringRefactoring
Refactoring
 
Behaviour driven development
Behaviour driven developmentBehaviour driven development
Behaviour driven development
 
Behaviour driven development
Behaviour driven developmentBehaviour driven development
Behaviour driven development
 
Behaviour drivendevelopment
Behaviour drivendevelopmentBehaviour drivendevelopment
Behaviour drivendevelopment
 
Behaviour driven development
Behaviour driven developmentBehaviour driven development
Behaviour driven development
 
Behaviour driven development
Behaviour driven developmentBehaviour driven development
Behaviour driven development
 
Behaviour drivendevelopment
Behaviour drivendevelopmentBehaviour drivendevelopment
Behaviour drivendevelopment
 
Behaviour drivendevelopment
Behaviour drivendevelopmentBehaviour drivendevelopment
Behaviour drivendevelopment
 
Tdd is not about testing
Tdd is not about testingTdd is not about testing
Tdd is not about testing
 
Agile experiments in Machine Learning with F#
Agile experiments in Machine Learning with F#Agile experiments in Machine Learning with F#
Agile experiments in Machine Learning with F#
 
Intro to JavaScript
Intro to JavaScriptIntro to JavaScript
Intro to JavaScript
 

More from Mike Harris

Extreme Programming (XP): Revisted
Extreme Programming (XP): RevistedExtreme Programming (XP): Revisted
Extreme Programming (XP): RevistedMike Harris
 
Clean COBOL Lightning Talk - Ox:Agile 2019
Clean COBOL Lightning Talk - Ox:Agile 2019Clean COBOL Lightning Talk - Ox:Agile 2019
Clean COBOL Lightning Talk - Ox:Agile 2019Mike Harris
 
Using neuroscience to build high performance teams - Elaine Sullivan
Using neuroscience to build high performance teams - Elaine SullivanUsing neuroscience to build high performance teams - Elaine Sullivan
Using neuroscience to build high performance teams - Elaine SullivanMike Harris
 
Kotlin - A very quick introduction
Kotlin - A very quick introductionKotlin - A very quick introduction
Kotlin - A very quick introductionMike Harris
 
A Brief Introduction to Kanban
A Brief Introduction to KanbanA Brief Introduction to Kanban
A Brief Introduction to KanbanMike Harris
 
It's XP Stupid (2019)
It's XP Stupid (2019)It's XP Stupid (2019)
It's XP Stupid (2019)Mike Harris
 
Contract Testing: An Introduction
Contract Testing: An IntroductionContract Testing: An Introduction
Contract Testing: An IntroductionMike Harris
 
Being a better programmer: Writing Clean COBOL
Being a better programmer: Writing Clean COBOLBeing a better programmer: Writing Clean COBOL
Being a better programmer: Writing Clean COBOLMike Harris
 
Aws assimilation
Aws assimilationAws assimilation
Aws assimilationMike Harris
 
This is heavy doc! Lessons on just in time architecture - Adrian Potter
This is heavy doc! Lessons on just in time architecture - Adrian PotterThis is heavy doc! Lessons on just in time architecture - Adrian Potter
This is heavy doc! Lessons on just in time architecture - Adrian PotterMike Harris
 
Working towards ideal ux, product and tech partnership
Working towards ideal ux, product and tech partnershipWorking towards ideal ux, product and tech partnership
Working towards ideal ux, product and tech partnershipMike Harris
 
Agile around the World - Glaudia Califano
Agile around the World - Glaudia Califano Agile around the World - Glaudia Califano
Agile around the World - Glaudia Califano Mike Harris
 
How To Handle Your Tech Debt Better - Sean Moir
How To Handle Your Tech Debt Better - Sean MoirHow To Handle Your Tech Debt Better - Sean Moir
How To Handle Your Tech Debt Better - Sean MoirMike Harris
 
Welcome to Elsevier - presentation for Ox:Agile Conference
Welcome to Elsevier - presentation for Ox:Agile ConferenceWelcome to Elsevier - presentation for Ox:Agile Conference
Welcome to Elsevier - presentation for Ox:Agile ConferenceMike Harris
 
HacktionLab: how LEAN is your non-hierarchical community education project
HacktionLab: how LEAN is your non-hierarchical community education projectHacktionLab: how LEAN is your non-hierarchical community education project
HacktionLab: how LEAN is your non-hierarchical community education projectMike Harris
 

More from Mike Harris (16)

Extreme Programming (XP): Revisted
Extreme Programming (XP): RevistedExtreme Programming (XP): Revisted
Extreme Programming (XP): Revisted
 
Clean COBOL Lightning Talk - Ox:Agile 2019
Clean COBOL Lightning Talk - Ox:Agile 2019Clean COBOL Lightning Talk - Ox:Agile 2019
Clean COBOL Lightning Talk - Ox:Agile 2019
 
Using neuroscience to build high performance teams - Elaine Sullivan
Using neuroscience to build high performance teams - Elaine SullivanUsing neuroscience to build high performance teams - Elaine Sullivan
Using neuroscience to build high performance teams - Elaine Sullivan
 
Kotlin - A very quick introduction
Kotlin - A very quick introductionKotlin - A very quick introduction
Kotlin - A very quick introduction
 
A Brief Introduction to Kanban
A Brief Introduction to KanbanA Brief Introduction to Kanban
A Brief Introduction to Kanban
 
It's XP Stupid (2019)
It's XP Stupid (2019)It's XP Stupid (2019)
It's XP Stupid (2019)
 
Contract Testing: An Introduction
Contract Testing: An IntroductionContract Testing: An Introduction
Contract Testing: An Introduction
 
Being a better programmer: Writing Clean COBOL
Being a better programmer: Writing Clean COBOLBeing a better programmer: Writing Clean COBOL
Being a better programmer: Writing Clean COBOL
 
Aws assimilation
Aws assimilationAws assimilation
Aws assimilation
 
This is heavy doc! Lessons on just in time architecture - Adrian Potter
This is heavy doc! Lessons on just in time architecture - Adrian PotterThis is heavy doc! Lessons on just in time architecture - Adrian Potter
This is heavy doc! Lessons on just in time architecture - Adrian Potter
 
Working towards ideal ux, product and tech partnership
Working towards ideal ux, product and tech partnershipWorking towards ideal ux, product and tech partnership
Working towards ideal ux, product and tech partnership
 
Agile around the World - Glaudia Califano
Agile around the World - Glaudia Califano Agile around the World - Glaudia Califano
Agile around the World - Glaudia Califano
 
How To Handle Your Tech Debt Better - Sean Moir
How To Handle Your Tech Debt Better - Sean MoirHow To Handle Your Tech Debt Better - Sean Moir
How To Handle Your Tech Debt Better - Sean Moir
 
Welcome to Elsevier - presentation for Ox:Agile Conference
Welcome to Elsevier - presentation for Ox:Agile ConferenceWelcome to Elsevier - presentation for Ox:Agile Conference
Welcome to Elsevier - presentation for Ox:Agile Conference
 
It's XP, Stupid
It's XP, StupidIt's XP, Stupid
It's XP, Stupid
 
HacktionLab: how LEAN is your non-hierarchical community education project
HacktionLab: how LEAN is your non-hierarchical community education projectHacktionLab: how LEAN is your non-hierarchical community education project
HacktionLab: how LEAN is your non-hierarchical community education project
 

Recently uploaded

Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareJim McKeeth
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...masabamasaba
 
WSO2Con2024 - Hello Choreo Presentation - Kanchana
WSO2Con2024 - Hello Choreo Presentation - KanchanaWSO2Con2024 - Hello Choreo Presentation - Kanchana
WSO2Con2024 - Hello Choreo Presentation - KanchanaWSO2
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2
 
WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...
WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...
WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...WSO2
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2
 
WSO2CON 2024 Slides - Unlocking Value with AI
WSO2CON 2024 Slides - Unlocking Value with AIWSO2CON 2024 Slides - Unlocking Value with AI
WSO2CON 2024 Slides - Unlocking Value with AIWSO2
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Bert Jan Schrijver
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...masabamasaba
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...Jittipong Loespradit
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...WSO2
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park masabamasaba
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2
 

Recently uploaded (20)

Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 
WSO2Con2024 - Hello Choreo Presentation - Kanchana
WSO2Con2024 - Hello Choreo Presentation - KanchanaWSO2Con2024 - Hello Choreo Presentation - Kanchana
WSO2Con2024 - Hello Choreo Presentation - Kanchana
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...
WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...
WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
WSO2CON 2024 Slides - Unlocking Value with AI
WSO2CON 2024 Slides - Unlocking Value with AIWSO2CON 2024 Slides - Unlocking Value with AI
WSO2CON 2024 Slides - Unlocking Value with AI
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
 

How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018

  • 1.
  • 2.
  • 3. How I learned to stop worrying and love LEGACY CODE - Mike Harris -
  • 4. The Plan • Introduce myself • Legacy code – Definition – Causes – Effects – What we could do about it – What we should do about it • Sum up • Discuss and answer questions
  • 5. About me • Got into home computers in the 1980s. • Wrote a Fractal generator in GFA BASIC on Atari ST. • Messed up my A levels. • Managed to get on a computing degree ;) • Got into Linux in early 90s. • Set up a company to promote Free Software. • We wrote our own CMS in Cold Fusion, then in Perl. • Since worked as a software engineer, and IT in general. • Found out about XP and Agile. Realised I was more of a hacker than a software engineer. • Joined Elsevier and SSRN in April this year. • Now working with ColdFusion again!
  • 6. About SSRN We are a freely accessible repository of abstracts and pre-print full-text papers… …and a community where researchers can shape the thinking in their fields SSRN is an open access research repository and a community for researchers
  • 7. Things I’ve been heard saying… • “The code is really awful!” • “It takes so long to make changes!” • “We’re always introducing bugs!” • “We’ve no idea what this bit does!” • “Bob is away!” • “We hate it!” • “We need to rewrite the whole damn thing!”
  • 9. What is legacy code? Legacy– adjective “of, relating to, or being a previous or outdated computer system.” – Merriam-Webster A more recent definition in Software Engineering is… “Source code inherited from someone else and/or source code inherited from an older version of the software” Michael Feathers in Working Effectively with Legacy Code names it as “Code without tests”
  • 10. Legacy code as technical debt Technical debt quadrant - Martin Fowler "As an evolving program is continually changed, its complexity, reflecting deteriorating structure, increases unless work is done to maintain or reduce it.” — Meir Manny Lehman, 1980 A lot of legacy code is to be found here “Bad code isn't Technical Debt, it's an unhedged Call Option” - Steve Freeman , 2010
  • 11. What is legacy code to an organisation? • A lot of investment. • Models business processes. • History of the enterprise. • Where we are today. • It “works”. • But it can be a pain to maintain and extend.
  • 12. What hints at legacy code? • Unnecessary or misleading comments. • Poor or obtuse naming of things. • Large number of calling parameters. • Multiple code paths in single functions. • Functions with side-effects. • Long and unstructured code. • Poorly scoped variables. • A lack of tests.
  • 13. sub check_login { my ($query, $pathinfo, $dbh) = @_; my $login_email = $query->param($AUTH_USER_FIELD); my $login_pass = $query->param($AUTH_PASSWORD_FIELD); my ($statement, $sth, $id, $login, $admin_level, $cookie); $statement = qq{SELECT id FROM $AUTH_DB_TABLE WHERE $AUTH_USER_FIELD = '$login_email' AND $AUTH_PASSWORD_FIELD = '$login_pass'}; $sth = $dbh->prepare($statement); $sth->execute or die("Unable to execute $statement", $dbh->errstr); $sth->finish; # get the count of rows in the database # $x is the row count going forwards if ($sth->rows eq 0) { ChangingPages->fetch_page(APP_OPTIONS => %APP_OPTIONS, QUERY => $query, FILE_NAME => $pathinfo . $query->param('_error_page'), ); return; } $statement = qq{ SELECT id, $AUTH_USER_FIELD, admin_level FROM $AUTH_DB_TABLE WHERE $AUTH_USER_FIELD = '$login_email' AND $AUTH_PASSWORD_FIELD = '$login_pass' AND (TO_DAYS(NOW()) - TO_DAYS(last_mod_pwd)) < $MAX_PASSWORD_EXPIRY }; $sth = $dbh->prepare($statement); $sth->execute or die("Unable to execute $statement", $dbh->errstr); if ($sth->rows eq 0) { $sth->finish; &display_change_passwd; return; } $sth->bind_columns(undef, $id, $login, $admin_level); $sth->fetch; $sth->finish; Closely coupled Side-effect Inelegant error handling SQL Injection? Poor naming Misleading Comment What is legacy about this Perl code? Passing global arrays around Open to hacking source HTML? Pretty much all of it! There are no tests either!
  • 14. The causes of Legacy Code
  • 15. The causes of legacy code • Old programming languages & the way we used them. • Old methodologies. • New methodologies not well understood. • Tasks done under pressure. • Hacks in code to solve bugs. • Not knowing any better – “we’ve always done it that way, and it works for us”. • Knowledge silos: solo programmers on one code area. • Rigid designs.
  • 16. Legacy code is language agnostic • Legacy code isn’t necessarily code written in BASIC, COBOL, ColdFusion, Fortran, Algol, or even Perl. • It can be written in even the most up to date coolest programming language. • Replacing your COBOL or ColdFusion code with Java, Go, Groovy, Kotlin, ReactJS, or Scala doesn’t stop legacy code being written.
  • 17. Descriptive naming Structured COBOL example Identification division. program-id. Stack. *> Implements a stack in COBOL *> Operators are: Pop, Push, and Peek data division. working-storage section. 01 StackTable is global. 02 StackItem pic x(20) occurs 1 to 50 times. 01 ItemsInStack pic 99 value zero is global. linkage section. 01 Command pic x any length. 01 Item pic x any length. procedure division using Command, Item. Main section. evaluate function trim(Command) when "Push" perform PushItemOntoStack when "Pop" perform PopItemOffStack when "Peek" perform PeekWhichItemIsOnTopOfStack end-evaluate goback . PushItemOntoStack section. add 1 to ItemsInStack move Item to StackItem(ItemsInStack) . PeekWhichItemIsOnTopOfStack section. move StackItem(ItemsInStack) to Item . PopItemOffStack section. if ItemsInStack less than 1 then move spaces to Item else move StackItem(ItemsInStack) to Item move spaces to StackItem(ItemsInStack) subtract 1 from ItemsInStack end-if . end program Stack. identification division. program-id. StackTest. *> A simple stack in COBOL data division. working-storage section. 01 Item pic x(10) value spaces. 01 Result pic x(10) value spaces. procedure division. TestShouldPopPushedItemsInReverseOrder. *> Given move "hello" to Item call "Stack" using by content "Push", by content Item move "hola" to Item call "Stack" using by content "Push", by content Item move "bonjour" to Item call "Stack" using by content "Push", by content Item *> When call "Stack" using by content "Pop", by reference Result *> Then call "AssertEquals" using Result, "bonjour", "Returned 3rd value put on stack” *> When call "Stack" using by content "Pop", by reference Result *>Then call "AssertEquals" using Result, "hola", "Returned 2nd value put on stack” Test Driven
  • 18. The effects of legacy code
  • 19. How it affects the developers • Changes take a long time. • Changes are risky. • Bugs are introduced. • Hacking makes things worse. • Working with it is frustrating. • Time pressures lead to stress. • .. and more hacks • The team has no real control over their software. – If it’s hard or impossible to change, then it’s not really software.. • It is demoralising.
  • 20. How it affects the business • New work can take longer than expected. • New work is difficult to estimate. • Changes can introduce bugs. Customer experience and trust is reduced, more wasted time, more cost. • Specialisations in the code cause delays. • Specialisations in the code are risks.
  • 21. What can we do about legacy code?
  • 22. What can we do about legacy code? • Stop writing it! • Yeah right; what can we really do about it? • Fire everyone and get a new team! • Leave the job and go and work somewhere where they aren’t writing legacy code! • Throw everything we’ve done away and start again using something cool to do it in! – Let’s look at this last option….
  • 24. The Total Rewrite plan…. • “We’ll put a team together to re-write all the code in a modern up-to-date framework, language, paradigm, cloud-based-thingy.” • “We’ll maintain the old system until the new system is done.” • “The spec is that the new system must do at least everything the old system does.”
  • 25. Pitfalls of the Total Rewrite • It costs money to seemingly stand still. • Changes to both systems; Zeno’s Paradox. • Do you re-implement the bugs? • The old legacy code doesn’t improve. • Delivery pressures leading to new legacy code. • Will you run two teams? • What if we never make it?
  • 26. Change attitude • Stop hating the code. • Stop blaming others (or yourself) for writing it. • Accept that it’s where we are. • Don’t run away from it. • Stop ignoring it. • Believe that it can be improved. • Person up and deal with it. • Make it better.
  • 27. Improve our toolset & practices • Use TDD. Improve & replace bad tests. • Refactor code to make life easier for you; learn refactoring techniques and patterns. • Code standards, styles, patterns, approaches. • IDE and other tools. • Find seams to replace or improve parts of it. • Employ pair or mob programming.
  • 28. Use seams, slices & stranglers • Introduce seams in the code. • Extend the legacy code, wrapping it to extend functionality. • Create slices of functionality in new code. • Strangler Pattern (Martin Fowler) – build a framework around existing system and gradually exterminate it.
  • 29. Refactor it • Refactor continuously. No story needed. • Once your code passes the test, spend a little longer to improve it. • Get rid of useless or misleading comments. • Rename variables and functions to be self- documenting. • Break up lengthy code. • Work towards one function doing one thing. • Encapsulate common code and data into classes. • Abstract resources from main code; de-couple. • If you cannot write any tests, try harder!
  • 30. sub check_login { my ($query, $pathinfo, $dbh) = @_; my $login_email = $query->param($AUTH_USER_FIELD); my $login_pass = $query->param($AUTH_PASSWORD_FIELD); my ($statement, $sth, $id, $login, $admin_level, $cookie); $statement = qq{SELECT id FROM $AUTH_DB_TABLE WHERE $AUTH_USER_FIELD = '$login_email' AND $AUTH_PASSWORD_FIELD = '$login_pass'}; $sth = $dbh->prepare($statement); $sth->execute or die("Unable to execute $statement", $dbh->errstr); $sth->finish; # get the count of rows in the database # $x is the row count going forwards if ($sth->rows eq 0) { ChangingPages->fetch_page(APP_OPTIONS => %APP_OPTIONS, QUERY => $query, FILE_NAME => $pathinfo . $query->param('_error_page'), ); return; } $statement = qq{ SELECT id, $AUTH_USER_FIELD, admin_level FROM $AUTH_DB_TABLE WHERE $AUTH_USER_FIELD = '$login_email' AND $AUTH_PASSWORD_FIELD = '$login_pass' AND (TO_DAYS(NOW()) - TO_DAYS(last_mod_pwd)) < $MAX_PASSWORD_EXPIRY }; $sth = $dbh->prepare($statement); $sth->execute or die("Unable to execute $statement", $dbh->errstr); if ($sth->rows eq 0) { $sth->finish; &display_change_passwd; return; } $sth->bind_columns(undef, $id, $login, $admin_level); $sth->fetch; $sth->finish; So what could we do with this?
  • 31. We could write some high-level tests in Gherkin Given I visit the login page And I enter a valid username And I enter a valid password When I click the login button Then I am taken to the home page Given My user login password has expired And I visit the login page And I enter a valid username And I enter a valid password When I click the login button Then I am taken to the change password page Given I visit the login page And I enter an invalid username And I enter a valid password When I click the login button Then I am taken to the login failed page Given I visit the login page And I enter a valid username And I enter an invalid password When I click the login button Then I am taken to the login failed page
  • 32. We could extract domain functionality into classes with tests
  • 33. sub check_login { my ($query, $pathinfo, $dbh) = @_; my $login_email = $query->param($AUTH_USER_FIELD); my $login_pass = $query->param($AUTH_PASSWORD_FIELD); my ($statement, $sth, $id, $login, $admin_level, $cookie); $statement = qq{SELECT id FROM $AUTH_DB_TABLE WHERE $AUTH_USER_FIELD = '$login_email' AND $AUTH_PASSWORD_FIELD = '$login_pass'}; $sth = $dbh->prepare($statement); $sth->execute or die("Unable to execute $statement", $dbh->errstr); $sth->finish; # get the count of rows in the database # $x is the row count going forwards if ($sth->rows eq 0) { ChangingPages->fetch_page(APP_OPTIONS => %APP_OPTIONS, QUERY => $query, FILE_NAME => $pathinfo . $query->param('_error_page'), ); return; } $statement = qq{ SELECT id, $AUTH_USER_FIELD, admin_level FROM $AUTH_DB_TABLE WHERE $AUTH_USER_FIELD = '$login_email' AND $AUTH_PASSWORD_FIELD = '$login_pass' AND (TO_DAYS(NOW()) - TO_DAYS(last_mod_pwd)) < $MAX_PASSWORD_EXPIRY }; $sth = $dbh->prepare($statement); $sth->execute or die("Unable to execute $statement", $dbh->errstr); if ($sth->rows eq 0) { $sth->finish; &display_change_passwd; return; } $sth->bind_columns(undef, $id, $login, $admin_level); $sth->fetch; $sth->finish; We can end up with more readable code
  • 34. Take on Technical Debt knowingly • It’s about knowing what the risks are • Keep a Tech Debt Wall • Note down any technical debt you accrue as you develop • Consider the risk of postponing resolution vs the cost of sorting now • Don’t engineer the future: resolve in the next iteration • Regularly review the Tech Debt Wall • Categorise the debt on the wall • Take highest risk technical debt into backlog and resolve
  • 35. Tech Debt Wall example
  • 36. What the business can do to help • Understand that it will take time to sort out. • Ensure the product pipeline accounts for it. • Support training and coaching for the team. • Create a safe environment. • Alleviate pressures. • Appreciate that – some people will be more resistant to change. – people learn in different ways – people learn at different speeds. – some people will not (want to) change.
  • 37. How I learned to love legacy code • I realised it’s an asset. • I realised it needs caring for, and improving. • I realised we shouldn’t blame ourselves or others. • I realised we had to own the code. • I realised we could have pride about it. • I realised we could and had to make it better. • I realised the Big Rewrite is tempting, but risky. • I realised the right tools & practices really help.
  • 38. Here’s a list of a few books • Working Effectively With Legacy Code – Michael Feathers (2004) • Clean Code – Robert C Martin (2008) • The Clean Coder – Robert C Martin (2011) • Beyond Legacy Code – David Scott Bernstein (2015) • Lean Software Development – Mary & Tom Poppendieck (2003) • Refactoring: Improving the Design of Existing Code – Martin Fowler, Kent Beck, et al (1999, 2018) • Refactoring Databases: Evolutionary Database Design – Scott J Ambler & Pramod J Sadalage (2006) • Head First Design Patterns - Eric Freeman, et al (2014) • Domain-Driven Design: Tackling Complexity in the Heart of Software – Eric Evans (2003)
  • 39. STOP RUN. Thank You 07811 671 893 m.harris@elsevier.com https://www.ssrn.com http://uk.linkedin.com/in/mbharris https://github.com/mikebharris/ © 2017-2018 Mike Harris under GNU FDL 1.3

Editor's Notes

  1. ALGOL-68
  2. Call option – is that a buyer and seller have a contract by which the buyer has the right to buy a certain quantity of a certain commodity at a certain price at a certain time. Unhedged – means that no instruments have been put in place as a contingency against possible loss when the call option is exercised.