Post on 16-Apr-2017
Real-World Experience: Dealing With Legacy
Dealing With Legacy:
The Real-World Experience
Why this presentation?
Share successful practices
Get suggestions regarding the challenges we struggled with (that aren't unique to us)
Provide support for pushing through design refactorings by revealing the cost of legacy
Agenda
The Application & Team
The Challenges
What Worked Well
What Could Be Improved
What I'd Have Loved To Have
Some Other Lessons Learned
Legacy Code: Manifestations, why to avoid
Selected Anti-Patterns
The Hidden Cost of Legacy
The Application & Team
Application:Ordering site critical to the business, 1-2k orders/day
Team:Team of 5+1, Scrum
WS back-end developed by a team abroad
Java 1.4, JSP, JSF
Ca 8 years, ~2.5k classes, 170 kLOC (400 classes and 50 kLOC in the core)
MonsterJsfBean (improved!): >10k LOC, 50 constants, 300 properties + 320 methods ( public)
The Challenges
The whole team exchanged within 1-2 monthsSurprisingly smooth
Huge difference in expertise levels (seniors x juniors)
Preparing migration to an upgraded platform and a different application server
Planning of a major design overhaul
Legacy code* with negligible tech/biz docs
*) See on the next slide
What did the code look like?
(More about design refactoring later)
What Worked Well
Scrum / processRetrospectives continual improvement
Common code review sessions (could be more)
Pair-programming learning (c'd be more)
Timeboxing (meetings, spikes)
Explicit commitment to each and every task
Bi-weekly releases low uncertainty
CI & deployment package building automation
Opportunistic (boy scout rule) refactoring
What Could Be Improved
ScrumStandup less reporting, more commitment
Focused sprints with a clear objective
Larger-scale refactorings to improve design
Less defects (how?! more testing?)
Test-first development and refactoringWe tried but not always (too much effort) and the tests weren't always good enough (focus, coupling)
What I'd Have Loved To Have
Living documentation Specification by ExampleUp-to-date, clear business logic documentation
Automated integration/functional testing
Operational monitoringQuick discovery of defects, outages of the app/dependencies
Knowledge of performance stats and bottlenecks
Feedback on how features are used
Efficient UI testing (fixtures/deps, jump to page)
Some Other Lessons Learned
It's crucial to refactor the design as requirements change to tame complexity
Tests too coupled to the implementation are worse than no tests
A meeting w/o action points with assigned people and checkpoints is a waste
Sometimes you must temporarily make code uglier when refactoring it towards st. better
Legacy CODE
Selected Anti-Patterns
Copy & Paste (& Adjust)
Patch & Go (aka Never Refactor Your Design)
One Class to Rule Them All
String Is the Best Data Type (never convert!)
Singletons & Static Accessors
ArrayList instead of the highest abstraction suitable
=> *plication and inconsistent design
The Hidden Cost of Legacy
May be only 10-20% time actually codingmost time spent figuring out what the code does & why (partly due to slow UI)
No specs what is a feature / bad design / workaround not needed anymore?
Prod defects due to not understanding hidden dependencies and varying usage of state variables
not fixing all the copied & pasted code fragments
Your Action Points :-)
Don't create legacy codeBeware the cost of legacy
Do refactor your design to reflect the business
Be betterConsider implementing SbE/Living document.
Implement operational monitoring
Make sure your app/UI is easy to test
Take inspiration from what worked for usRetrospectives, Common code reviews, ...
THANK YOU!