Presented by Robert Annett at QCon London, 14 Sep 2012.
Notes by Jeremy W. Sherman, 2013–10–13.
- Often an insult, but how odd, not like that in normal English (cf. inheritance).
- Also perhaps defined as “as opposed to its alternatives, it’s the software that actually works”.
- Often a mechanization of an earlier paper or Excel-based system.
- Mix of older versions of current tools, or old tools that failed.
- Old hardware, old languages, old tech.
- Often still working, but everyone hates it.
- Usernames and passwords to administrate the database might be missing.
- What was the last release branch? Even if it’s in SCM, that doesn’t mean you know what got baked into the last release.
- What’s the communication protocol? Needs reverse-engineering sometimes.
- How is the network structured?
- No licenses accompanying third-party code – can we still legally use this?
- Organic “agile” software
- Like London’s growth
- The “Magic Roundabout” - anticlockwise flow around big roundabout, with 6 smaller spoke roundabouts with clockwise flow; can actually go clockwise around big roundabout by looping each intermediate smaller roundabout.
- Old standing agreements not documented
- Example: Deleting a file someone else is using in /tmp at 2 am via FTP
Hidden Knowledge
- Only one person knows how to generate a report.
- Job security – “last man standing” from the original team.
- A lot of maintenance work to maintain useless code.
- Vs. Stability
- If it looks fragile, then no-one will let you touch it.
- Tight requires big lockstep coordinated releases
- Loosely coupled systems hide dependencies - big space for lost knowledge problems
- Buying 10 year old machines off eBay because that’s what your business-critical system can run on.
- Often a big issue when you move to VM land; often not allowed by past licenses without high expenses (per-hardware machine vs. per-VM).
- Regulation changes can render a legacy system’s behavior illegal.
- Damned if you do and fail
- Damned if you do and succeed (who’s out a job now?)
- Note: They might cloak their hidden knowledge from you.
- No-one likes changes except developers!
- People care about your work.
- You have actual users already to talk to.
- You can learn a lot about the industry via its system.
NO. You will run into trouble.
Might be enough to remove the system. It could be entirely superfluous. “This service costs $10k per year and just runs unix2dos and emails it?”
Sweat those assets!
Speaking of infrastructure components. Don’t wipe out everything, just update to latest APIs, latest version of language, etc.
Move to an entirely new system and platform.
Don’t just chuck in features willy-nilly, or you’re just increasing technical debt.
Still have to maintain the old system alongside the new till it’s ready. Then have to retrain everyone (users and ops) to use the new system. This is likely unnecessary!
Good news: You actually have some. Yay legacy systems.
Recommends Simon Brown’s Software Architecture for Developers on Leanpub.
C4 system:
- Context: What is in there, who uses it, and how does it fit into the current flow?
- Containers: What are the high-level tech decisions? Where do you stick new code?
- Components: What are the services in the system? Which container do they go in?
- Classes: You know how this one goes.
Needs. Moar. Diagrams.
BEWARE: What you have running might not be what is in your SCM!
- Re-create the production system as a test system.
- Take a snapshot and then migrate it into a virtualized sandbox. (VMWare gets mentioned a lot here.)
- Run tests and metrics for the copy.
- Make sure you can swap out containers within the virtual system, can build, and redeploy within that test system.
- This makes you confident you can deploy and rollback as needed, on a per-component basis!
- Create some systems tests
- Make them realistic uses of the systems
- Report runs you can compare
- Consider “test” data in the real system
- Build, virtualize, and deploy production
- Cleanse data
- Archive data
- Remove unused components
- Shift resources (virtualized)
- Tune applications/DBs
- Code changes only if required
- Proves competence, removes unneeded work, and ensures you understand the system from top to bottom.
- Hard to upgrade/migrate
- Functional and non-functional behavior will change!
- Be prepared to rollback if (when) necessary
- NOTE: Test and rollback should be methodical at this point in the process.
- Before you refactor, format everything, so you have a base that you can sanely diff.
- If you reformat as you make changes, all your changes are masked by layout and format changes.
- After that, read Michael Feathers’ Working Effectively with Legacy Code.
All that stuff that was missing when you went in? Write it and store it somewhere. Write up build and deploy instructions. Put together an asset register. Give it to your accountants. They will hold onto it for all eternity. BCP/Failover/Backup plans, for when things go wrong and fall apart in 10 years. Draw diagrams! Especially of the overall architecture.
- System
- Integration
- Functional
- Non-Functional
- UAT
- Accessibility
- Automate it all, and leave documentation.
Write up a document. Doesn’t need to be 200 pages; does need to be what you’d draw on a whiteboard when explaining it to someone today.
- Beware new stuff – will it still be around in 10 years, or will your successors be forced to migrate?