From time to time I do a Clean Code Workshop for coworkers or customers. A large part of these workshops deals with legacy code. I always start with the Ugly Trivia Game by J. B. Rainsberger, which actually isn't by him, but I use his version anyway. While it is a great resource it gets boring after you have reviewed, tested, refactored, tested it some more and reviewed the tests and refactorings. Also: does it really look like the average legacy code we find in our projects? I don't think so. Real life legacy code has more dependencies and does more really stupid stuff. My favorite so far was a class that loaded stuff from the database in the constructor. Not fun.

Therefor I like to create a little code base for working with legacy code that is very realistic but still small enough so one can handle it in the setting of a workshop and it is actually really simple to do that:

First pick some class that is ugly. Big methods are great. Sometimes you come a cross classes that are super tangled with 2-5 other classes. Those are super awesome. Don't pick anything to large. A class with 5000 lines just create more work, not more learning opportunities.

Second copy that class (or that small class cluster) in a new project. No dependencies, none of the other stuff it works with. Most likely it wont compile, we gonna fix that in the next step.

Third fix all the compile problems using one of the following approaches:

This is really fast, works with 98% of all legacy code I came across so far and creates some mean challenges for working with legacy code.