Title: "Strangling" Legacy Code
1"Strangling" Legacy Code
Mike Thomas mike_thomas_at_yahoo.com http//www.samoh
t.com
2Agenda
- Strangling Defined
- The Victim
- Planning the Attack
- Strangling in Action
- Tools and Techniques
- Observations
3Strangling Defined
Strangling Defined
- Strangling?
- Basically, replacing legacy code with new
(hopefully better) code, bit by bit - See Fowlers Strangler Application article
4Why Strangle?
Strangling Defined
- The application has business value, but the
ability to add more value decreases over time, as
technical debt builds up.
5Why Strangle?
Strangling Defined
- Strangling vs. Rewriting
- Business You want to do what?!?
- Difficult to manage scope of rewrite
- Very risky to go dark in order to rewrite
6Why Strangle?
Strangling Defined
- Strangling vs. Refactoring
- Success with refactoring depends upon
- Initial code quality
- Size/complexity of system
- Team/organization goals, values
- How soon you start
7Before Strangling
Strangling Defined
- Know your goals. For us
- Agility (leading to competitive advantage)
- Promote testability
- Increase flexibility
- Decrease complexity
- Know your values
- Know your team
- Have a well-defined architectural roadmap
- Have a feel for the types of technologies youll
be using - Our constant guide was a layered architecture
model - The Spring Framework was an important initial
selection
8The Victim
The Victim
- Successful 401k record keeping application
- Under development since 2001
- 3-4 developers at any given time
- 1 tester
- 120k LOC
- Strict code ownership
- No automated/unit testing
9Why this Victim?
The Victim
- An effective, working system, but
- Need to grow business and add more features
- Good programming, but inflexible architecture
- Massive coupling
- Almost no Java interfaces
- Heavy static/singleton use
- Chicken/egg problem cant refactor without
tests, cant build tests without refactoring - Team dynamic
- The team wanted to target a new architecture -
actually deemed easier to strangle than to
refactor
10Team Values
Planning the Attack
- Pragmatic, not dogmatic
- Pair sometimes, esp. on difficult/key code
- TDD often
- Avoid rules, use guidelines and judgment
- Openness, willing to change/refactor
- If it dont work, fix it
- Quality before speed
- Secret weapon The Costanza Principle
11The Costanza Principle
Planning the Attack
- In an episode of Seinfeld titled The Opposite,
George learned that to reverse his loserhood,
he needed only to do the opposite of what came
naturally to him. - So, do the opposite of what was done in the past
-- in other words, use your mistakes as a guide! - Who ever said George was dumb?
12Costanza Principle (contd)
Planning the Attack
Status Quo The Opposite
UI and business rules intermixed Layered Architecture Velocity for presentation
High coupling Layered Architecture DTOs
Too much data kept on session (GLOBALS) Judicious use of session data Push caching to DAO layer
Singletons (GLOBALS) Services via IoC
13Costanza Principle (contd)
Planning the Attack
Status Quo The Opposite
Unmanaged Dependencies Layered Architecture Careful physical design (more on this later)
Type codes Typesafe enums Proper inheritance
Lots o code in JSP No code in JSP (HTML code in Java) Use Velocity
No tests Lots of tests JUnit Fitnesse Canoo Webtest
14Costanza Principle (contd)
Planning the Attack
Status Quo The Opposite
Write everything from scratch Prefer Standards Leverage existing APIs Leverage Open Source (Spring, Velocity, Hibernate, Commons, etc.)
Rusty skills Brown bags Conferences
Little developer testing Test-driven development (were working on it -) )
Hand-maintained deployment environments Self-contained .war file, moving toward automation
15The Costanza Corollary
Planning the Attack
- Repeat Successes
- Form/Field Framework
- Automated layout
- Centralized basic validation
16Methodology
Planning the Attack
- Again pragmatic, not dogmatic
- Somewhat Daring programming
- SCRUM management techniques
- Sprints (iterations)
- Daily SCRUM meetings
- SCRUM planning at end of iterations
- User Stories
- Very short iterations (2 weeks these days)
- Watch burndown like a hawk
- A selection of XP practices that work for us
- Sprint review publishes metrics (new vs. old
code, etc.)
17Strangling Targets
Planning the Attack
New functionality new code Significant changes new code
CSRLink Referral Tracking Compliance Testing Document generation
18Before
Strangling in Action
19Phase I
Strangling in Action
20Phase II
Strangling in Action
21Phase III
Strangling in Action
22Phase IV
Strangling in Action
23Strangling Techniques
Tools and Techniques
Technique Purpose Application(s)
Layered Architecture (with Legacy as a Layer) Carefully separate concerns Everything
Careful Physical Design Separate architectural layers Detect and Prevent Cyclical Dependencies Promote plugability The system, itself
24Strangling Techniques
Tools and Techniques
Technique Purpose Application(s)
Gateway/Bridge Make legacy functionality available to new. Allow new code to synchronize legacy state. Referral Tracking Advisor Registration Configuration
ThreadLocal Make important global state from legacy code available to new Authorization
25Strangling Techniques
Tools and Techniques
Technique Purpose Application(s)
URL Integration (aint webapps grand?) Link UIs of old and new code Referral Tracking Document Generation
Allow Direct Access to Strangler Code from Legacy Let legacy code benefit from new features. Referral Tracking
26Tools and Techniques
Layered Architecture
- Important are these layer cake diagrams hard
to draw, or what? - The main aim is to separate the UI from the
domain/business rules (remember the Costanza
principle) - Strangler accesses legacy only via bridge
27Careful Physical Design
Tools and Techniques
- What is Physical Design?
- The organization of code in the filesystem. The
single source tree is a common physical design. - Alternative physical designs provide another tool
to help manage dependencies and promote modularity
28Careful Physical Design
Tools and Techniques
- Consider Physical Packaging of Modules
- Logical (Java) packaging groups functionality
- Physical packaging groups modules -- code that is
packaged and deployed as a unit and serves a
single purpose. - Boundaries between modules are made obvious
- Plugability can be achieved
29Careful Physical Design
Tools and Techniques
- Implementing Physical Packaging
- Define container directories
- Update Ant script to compile each container
separately and in dependency order - Consider placing module classes into separate
jars
30Careful Physical Design
Tools and Techniques
- Each package below is in its own physical
directory - This enforces a build order, from least dependent
to most - Therefore, the Ant build has a compile step for
each physical package - The build order enforces one-way dependencies
31Gateway/Bridge
Tools and Techniques
- Allows legacy features to be encapsulated and
accessed as services. - Used to keep legacy session in sync with new.
- Use Separated Interface to break cyclical
dependency between legacy and new. - Use IoC container (Spring) to configure access to
gateway impls and to access legacy configuration
data. - Be vigilant - dont let the bridge get too wide
(or you may be invaded)!
Corpus Callosum
32Separated Interface
Tools and Techniques
- Some requirements seem to require cycles
- We want our strangler decoupled from the legacy
code, so it uses the bridge - We want our legacy code to be able to take
advantage of strangler code - But cyclical dependencies ruin the modularity of
the system -- theres just too much coupling. - Also, if you use good physical design, the system
will not compile if cycles are present.
33Separated Interface (contd)
Tools and Techniques
- So, break the cycle by separating the
interface(s) of the bridge from the
implementation(s)
34Tools and Techniques
URL Integration Session Synchronization
- Legacy code jumps to strangler.
- Strangler operates, keeping legacy in sync via
bridge - Strangler jumps back to legacy.
35Strangling Tools
Tools and Techniques
- Spring Framework
- IoC, Configuration
- Web Framework
- JDBC Framework
- Hibernate
- Jakarta Commons
- Homegrown Code Generators
- Fitnesse
- JUnit
36Success Indicators/Metrics
Observations
Metric Legacy/Then Strangler/Now
NCSS 127k 21k (and growing)
Classes 770 409
of interfaces 10 58
37Success Indicators/Metrics
Observations
Metric Legacy/Then Strangler/Now
Avg. Function NCSS 10.03 3.68
Avg. Object NCSS 155.31 44.82
Avg. Object Functions 13.97 10.11
Avg. Cyclomatic Complexity 2.34 1.35
Methods with CCN gt 10 378 (3) Highest 63! 27 (0.6) Highest 29 (9 of the highest are equals())
38Success Indicators/Metrics
Observations
Metric Legacy/Then Strangler/Now
Avg. JavaDoc Comments/Class 1.02 4.02
JUnit Tests 20 550
Fitnesse Tests 250 2000
Canoo Tests ? 26
Pairing Never 50
39Some Lessons
Observations
- Its often better to bite off more than less
- Integration of details is difficult
- Presentation differences when using URL
Integration - Synchronizing session state
- Old habits die hard
- Cant I just stick it in the session?
- This stupid build wont let me put my class
where I want it.
40Resources
- Fowlers Strangler Application Articlehttp//www
.martinfowler.com/bliki/StranglerApplication.html - Patterns of Enterprise Software Architecture,
Martin Fowler - Working with Legacy Code, Michael Feathers
- Slides from this presentationhttp//www.samoht.c
om/wiki/wiki.pl?software_development - Email me at mike_thomas_at_yahoo.com