strangling legacy code
TRANSCRIPT
04/11/23RMSS Fall 20041
"Strangling" Legacy Code"Strangling" Legacy Code
Mike [email protected]
http://www.samoht.com
04/11/23RMSS Fall 20042
AgendaAgendaStrangling DefinedThe VictimPlanning the AttackStrangling in ActionTools and TechniquesObservations
QuickTime™ and aTIFF (Uncompressed) decompressor
are needed to see this picture.
04/11/23RMSS Fall 20043
Strangling Defined Strangling Defined
Strangling?– Basically, replacing legacy code
with new (hopefully better) code, bit by bit
– See Fowler’s “Strangler Application” article
Strangling Defined
04/11/23RMSS Fall 20044
Why Strangle? Why Strangle?
The application has business value, but the ability to add more value decreases over time, as technical debt builds up.
Strangling Defined
04/11/23RMSS Fall 20045
Why Strangle? Why Strangle?
Strangling vs. Rewriting– Business: “You want to do what?!?”– Difficult to manage scope of rewrite– Very risky to “go dark” in order to
rewrite
Strangling Defined
04/11/23RMSS Fall 20046
Why Strangle? Why Strangle?
Strangling vs. Refactoring– Success with refactoring depends upon:
Initial code qualitySize/complexity of systemTeam/organization goals, valuesHow soon you start
Strangling Defined
04/11/23RMSS Fall 20047
Before StranglingBefore Strangling 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 you’ll be using– Our constant guide was a layered architecture model– The Spring Framework was an important initial selection
Strangling Defined
04/11/23RMSS Fall 20048
The VictimThe VictimSuccessful 401k “record keeping”
applicationUnder development since 20013-4 developers at any given time1 tester120k LOCStrict code ownershipNo automated/unit testing
The Victim
04/11/23RMSS Fall 20049
Why this Victim?Why this Victim?An effective, working system, but:
– Need to grow business and add more features– Good programming, but inflexible architecture
Massive couplingAlmost no Java interfacesHeavy static/singleton useChicken/egg problem: can’t refactor without tests, can’t
build tests without refactoring
– Team dynamicThe team wanted to target a new architecture - actually
deemed easier to strangle than to refactor
The Victim
04/11/23RMSS Fall 200410
Team ValuesTeam ValuesPragmatic, not dogmatic
– Pair sometimes, esp. on difficult/key code
– TDD often
– Avoid rules, use guidelines and judgment
Openness, willing to change/refactor– If it don’t work, fix it
Quality before speedSecret weapon: The Costanza Principle
Planning the Attack
04/11/23RMSS Fall 200411
The Costanza PrincipleThe Costanza Principle 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?
QuickTime™ and aTIFF (Uncompressed) decompressor
are needed to see this picture.
Planning the Attack
04/11/23RMSS Fall 200412
Costanza Principle (cont’d)Costanza Principle (cont’d)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
Planning the Attack
04/11/23RMSS Fall 200413
Costanza Principle (cont’d)Costanza Principle (cont’d)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
Planning the Attack
04/11/23RMSS Fall 200414
Costanza Principle (cont’d)Costanza Principle (cont’d)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(we’re working on it :-) )
Hand-maintained deployment environments
Self-contained .war file, moving toward automation
Planning the Attack
04/11/23RMSS Fall 200415
The Costanza CorollaryThe Costanza Corollary
Repeat Successes– Form/Field Framework:
Automated layoutCentralized basic validation
Planning the Attack
04/11/23RMSS Fall 200416
MethodologyMethodology 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.)
Planning the Attack
04/11/23RMSS Fall 200417
Strangling TargetsStrangling Targets
New functionality == new code
Significant changes == new code
•CSRLink•Referral Tracking
•Compliance Testing•Document generation
Planning the Attack
04/11/23RMSS Fall 200418
BeforeBefore
Strangling in Action
04/11/23RMSS Fall 200419
Phase IPhase I
Strangling in Action
04/11/23RMSS Fall 200420
Phase IIPhase II
Strangling in Action
04/11/23RMSS Fall 200421
Phase IIIPhase III
Strangling in Action
04/11/23RMSS Fall 200422
Phase IVPhase IV
Strangling in Action
04/11/23RMSS Fall 200423
Strangling TechniquesStrangling 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
Tools and Techniques
04/11/23RMSS Fall 200424
Strangling TechniquesStrangling 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
Tools and Techniques
04/11/23RMSS Fall 200425
Strangling TechniquesStrangling Techniques
Technique Purpose Application(s)URL Integration(ain’t 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
Tools and Techniques
04/11/23RMSS Fall 200426
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
Layered ArchitectureLayered Architecture
Tools and Techniques
04/11/23RMSS Fall 200427
Careful Physical DesignCareful Physical Design
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
Tools and Techniques
04/11/23RMSS Fall 200428
Careful Physical DesignCareful Physical Design 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
Tools and Techniques
04/11/23RMSS Fall 200429
Careful Physical DesignCareful Physical Design
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
Tools and Techniques
04/11/23RMSS Fall 200430
Careful Physical DesignCareful Physical Design•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
Tools and Techniques
04/11/23RMSS Fall 200431
Gateway/BridgeGateway/Bridge 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 - don’t let the bridge get too wide (or you may be invaded)!
Tools and Techniques
Corpus Callosum
04/11/23RMSS Fall 200432
Separated InterfaceSeparated Interface 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 -- there’s just too much coupling.
Also, if you use good physical design, the system will not compile if cycles are present.
Tools and Techniques
04/11/23RMSS Fall 200433
Separated Interface (cont’d)Separated Interface (cont’d) So, break the cycle by separating the interface(s) of the bridge
from the implementation(s):
Tools and Techniques
04/11/23RMSS Fall 200434
Legacy code jumps to strangler.
Strangler operates, keeping legacy in sync via bridge
Strangler jumps back to legacy.
URL Integration & Session SynchronizationURL Integration & Session Synchronization
Tools and Techniques
04/11/23RMSS Fall 200435
Strangling ToolsStrangling Tools Spring Framework
– IoC, Configuration– Web Framework– JDBC Framework
Hibernate Jakarta Commons Homegrown Code Generators Fitnesse JUnit
Tools and Techniques
04/11/23RMSS Fall 200436
Success Indicators/MetricsSuccess Indicators/MetricsMetric Legacy/Then Strangler/Now
NCSS 127k 21k (and growing)
Classes 770 409
# of interfaces 10 58
Observations
04/11/23RMSS Fall 200437
Success Indicators/MetricsSuccess Indicators/Metrics
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 >= 10
378 (3%)Highest: 63!
27 (0.6%)Highest: 29(9 of the highest are equals())
Observations
04/11/23RMSS Fall 200438
Success Indicators/MetricsSuccess Indicators/Metrics
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%
Observations
04/11/23RMSS Fall 200439
Some LessonsSome Lessons
It’s often better to bite off more than less:– Integration of details is difficult
Presentation differences when using URL Integration
Synchronizing session stateOld habits die hard
– “Can’t I just stick it in the session?”– “This stupid build won’t let me put my class
where I want it.”
Observations
04/11/23RMSS Fall 200440
ResourcesResources Fowler’s Strangler Application Article:
http://www.martinfowler.com/bliki/StranglerApplication.html
Patterns of Enterprise Software Architecture, Martin Fowler
Working with Legacy Code, Michael Feathers Slides from this presentation:
http://www.samoht.com/wiki/wiki.pl?software_development
Email me at: [email protected]