Jump to ratings and reviews
Rate this book

Re-Engineering Legacy Software

Rate this book
SummaryAs a developer, you may inherit projects built on existing codebases with design patterns, usage assumptions, infrastructure, and tooling from another time and another team. Fortunately, there are ways to breathe new life into legacy projects so you can maintain, improve, and scale them without fighting their limitations.Purchase of the print book includes a free eBook in PDF, Kindle, and ePub formats from Manning Publications.About the BookRe-Engineering Legacy Software is an experience-driven guide to revitalizing inherited projects. It covers refactoring, quality metrics, toolchain and workflow, continuous integration, infrastructure automation, and organizational culture. You'll learn techniques for introducing dependency injection for code modularity, quantitatively measuring quality, and automating infrastructure. You'll also develop practical processes for deciding whether to rewrite or refactor, organizing teams, and convincing management that quality matters. Core topics include deciphering and modularizing awkward code structures, integrating and automating tests, replacing outdated build systems, and using tools like Vagrant and Ansible for infrastructure automation. What's InsideRefactoring legacy codebasesContinuous inspection and integrationAutomating legacy infrastructureNew tests for old codeModularizing monolithic projectsAbout the ReaderThis book is written for developers and team leads comfortable with an OO language like Java or C#.About the AuthorChris Birchall is a senior developer at the Guardian in London, working on the back-end services that power the website.Table of ContentsPART 1 GETTING STARTEDUnderstanding the challenges of legacy projects Finding your starting pointPART 2 REFACTORING TO IMPROVE THE CODEBASEPreparing to refactorRefactoringRe-architectingThe Big RewritePART 3 BEYOND REFACTORING—IMPROVING PROJECT WORKFLOWAND INFRASTRUCTUREAutomating the development environmentExtending automation to test, staging, and production environmentsModernizing the development, building, and deployment of legacy softwareStop writing legacy code!

232 pages, Kindle Edition

Published April 15, 2016

7 people are currently reading
58 people want to read

About the author

Ratings & Reviews

What do you think?
Rate this book

Friends & Following

Create a free account to discover what your friends think of this book!

Community Reviews

5 stars
2 (4%)
4 stars
10 (21%)
3 stars
25 (54%)
2 stars
8 (17%)
1 star
1 (2%)
Displaying 1 - 9 of 9 reviews
Profile Image for Sebastian Gebski.
1,209 reviews1,391 followers
Read
May 12, 2016
Very entry level. Well-written, clear message, reasonable pick of sub-topics, but I couldn't help feeling like there was too much obviousness and banality. I guess I just didn't fit as a target audience.

One of the greatest sins of this book (& quite a typical one for books about tech debt, re-engineering, re-factoring, etc.) is trying to illustrate complexity- / scale-related problems with trivial, hello-world level examples. Not only that it doesn't looks trustworthy, it can also be confusing - especially for an inexperienced reader.

Anyway - no stars. I'm just afraid that my perception on this book may differ a lot from someone on a beginner level.
Profile Image for Jean Tessier.
164 reviews32 followers
July 1, 2016
Ten years prior, I had read Working Effectively with Legacy Code by Michael Feathers and I had really liked it. It had a strong focus on automated tests and refactoring. I was hoping this could be an updated take on the subject, though the table of contents looked more about the human factors involved in software development. This was a problem that I was struggling with at the time: how to modernize a sizable codebase that was too unwieldy for my small team.

Right off the bat:

This book is ambitious in scope, setting itself the aim of teaching you everything you need to do in order to transform a neglected legacy codebase into a maintainable, well-functioning piece of software that can provide value to your organization.

p. xvi


The book is barely 200 pages long!! And it's going to cover everything?!? This book is setting itself up to be a disappointment.

Overall, it brings up a lot of good points and ideas of things to try, but fails to develop any of them to a significant degree. It might work for project managers who are not very technical to get a tour of the landscape, pick up some terms, and have a general understanding of what's needed. It falls very short for technical people looking for concrete, actionable items to help them deal with their legacy software.

It does, however, suggest many avenues to explore on one's own. I appreciated the overall sense of automating as many things as possible. From developers setting up for a project to continuous integration to static analysis to deployment, the fewer things that depend on human intervention and arcane knowledge, the better it is for the project. It lists quite a few tools for all these tasks (Vagrant, Ansible, FindBugs, PMD, Jenkins, Fabric, etc.). My personal favorites, such as Docker and microservices, only get passing mentions. Some of these tools include trivial examples on how to set them up. But any substantial use case is left as an exercise for the reader.

First we need to decide what to measure. This depends largely on the particular software, but the simple answer is measure everything you can.

p. 22


This can be dangerous advice, both politically if measurements are misused or misinterpreted, and technically as it creates a lot of noise. People will optimize for what they are measured by, so beware of what you ask for.

Another important aspect is ensuring information flow through the team. Keeping it close to the code with README files and documentation files in the same code repository augments the chance that developers will keep them up-to-date as the code evolves.

I really liked the discussion of splitting a large monolithic application into services vs. SOA vs. microservices, with decent coverage of the pros and cons of each. The section on refactoring code was also a welcomed refresher. I had never heard of the Macbeth Syndrome: I've come this far, it'll be as hard to finish as to go back (not to be confused with the Lady Macbeth effect).

Some of the attempts are humor fall flat and come across as juvenile.

I will end with an interesting quote near the end regarding unit tests:

If, for example, you can't refactor a piece of code without having to fix or rewrite dozens of tests, that may be a sign that your unit tests are becoming more trouble than they're worth.

p. 203


I have been struggling with this very problem lately, trying to make one change and having to update over a hundred tests, which is discouraging. The author goes so far as to recommend deleting unit tests when you have higher-level tests to provide coverage. I'm not completely sold on the idea yet, but it does resonate.
600 reviews11 followers
May 11, 2020
This book offers many useful ideas and approaches. Unfortunately, it misses the opportunity to explain characterization tests in the dept they deserve. That type of test combined with the Mikado method could turn this book into something much more important and would help to explain the other topics more smoothly. As it is, the book promises too much and delivers too little and cannot reach the quality of Working Effectively with Legacy Code by Michael Feathers.
114 reviews19 followers
August 10, 2021
I thought the author did a nice job of summarizing some good principles to keep in mind when considering how to tackle a large chunk of legacy code, whether through refactoring or a complete re-write. While I appreciate the numerous examples the author uses throughout the book, the fact that they are so Java-focused makes the advice harder to apply to other languages such as JavaScript or Python. I think at least a mention of available tools for these other languages would've gone a long way. Still, a worthwhile read for some good advice if you've never tackled a large refactoring/rewrite effort before.
Profile Image for Alejandro Teruel.
1,332 reviews254 followers
May 6, 2024
Nice, well written, down to earth and introductory book on reengineering legacy code. It includes excellent, simple examples and case studies taken from, or based on, the author's experience in maintainance projects. In general, the book uses Java for code examples, but also mentions use of Scala, and occasionally indicates equivalent practices or packages for Python, Ruby, and C#.

The book is divided into three parts. The first part (Getting Started) contains two chapters, the first of which describes what legacy projects, legacy code and legacy infrastructure and what their key problems are. The second chapter provides an excellent suggestion as to where to start a reengineering project, which is by getting a feel for the quality of the legacy code by running static analysis tools and language style checkers, such as -in the case of Java- FindBugs, PMD and Checkstyle. He clearly shows how these tools can be used, provides examples and explains how they overlap, what their strengths and weaknesses are, and how to parametrize them so they are less verbose and report the more interesting potential flaws in the code.
The second part is about refactoring the legacy codebase. In chapter 3, Birchall deftly looks into the pros and cons of options like refactoring, rewriting from scratch, or more hybrid approaches, dealing with team members who tend to touch as little as possible for fear of breaking the code as well as team members who rashly want to rewrite everything. He includes sensible thoughts on the possibility of integrating team members by having certain members pair-program a little in order to move them to a more balanced viewpoint and strongly recommends applying code reviews throughout the project.

Chapter 4 goes into refactoring, providing some excellent advice in the process, lightly but effectively deals with the use of design patterns (particularly MVC) and refactoring patterns pointing out the key references in the area, starting with Martin Fowler's book on refactoring. Birchall also deals with issues in test development such as the use of Mockito, not getting hung up on test coverage, the use of real user traffic streams, and relying on stealth releases, that is to say running the new version of the legacy code in parallel with the old, sending data streams to both to compare the outp[ut of the two codes, and sending back the output stream of the old version so users are kept happy while the developers can compare how the new version works against real user data.

Chapter 5 provides advice on rearchitecting, looking closely at the pros of cons of migrating to service-oriented and microservices architectures.

In chapter 6 (The big rewrite), Birchall tackles projects to rewrite large portion of the legacy codebase from scratch. One of the most valuable takeaways from the book are the author's very practical and sensible recommendations on deciding and documenting the scope of rewrite projects.
Another key takeway is his description of three kinds of big rewrites: Black-box rewrites, brush-up rewrites and quid pro quo rewrites. The difference between the three kinds of rewrites boils down to what sort -if any- of changes the project aims to make to the functional specifications of the software. The chapter also includes a very nice discussion on the pros and cons of migrating the legacy database, identifying key factors in the decision and suggesting the development of a persistence layer between the new data model and the old model kept in the legacy database. Sensible warning and advice include:
When parts of a legacy application are implemented in DB triggers, stored procedures, shell scripts running as cron tasks on production servers, or anywhere else that can't be found just by looking through the source code, it can be very confusing for developers who come along to maintain the application later.

If implementing a new database, plan and be be very careful with the migration process -and the parallel operation of new software and old software, synchronizing (in real time? Via batch?) new updates to both dbs.

Plan for cutovers to old system to be prepared for when things go wrong.

Avoid splitting incoming traffic and sending some traffic to both applications at the same time. This implies that they're both writing to their respective Dbs (or even to the same DB) simultaneously, and these writes re being synchronized both ways in real time, which leads to all kinds of difficulties.
The third part of the book(Beyond refactoring – improving project workflow and infrastructure) includes topics such as automatizing setting up local machines for efficient software development, multiple environments (typically at least a development, a testing and a production environment), using a version control system effectively and deploying software to production quickly and reliably. Birchall provides quick and brief introductions to tools such as Vagrant, Ansible, Gradle and Fabric. I did not find most of the chapters in this third part as nice as the previous ones perhaps because they (necessarily?) focus on the details of tool installation and use, scripts; this part should probably be read while applying the material to a case study.

The last chapter does not belong in part 3, it sums up many of the main points of the book and sensibly recommends applying many of the techniques covered in it when writing new software in order to improve the new software's maintainability.

I very much enjoyed this book: it is easy to read and contains much sensible and sound advice -in a nutshell: highly recommended!
Profile Image for Edin Kapić.
Author 1 book8 followers
May 27, 2016
Interesting content but lacking in depth. Leaves me with a mixed feeling.
Profile Image for Yannick Grenzinger.
57 reviews6 followers
July 21, 2024
I was expecting better and more learnings :)

There are 3 parts :
- the "getting started" which quickly goes through different ideas and some general concerns.
- the "refactoring to improve the context" which presents the typical methods to improve legacy code base but without going as deep as "Refactoring" from Martin Fowler or "Working with legacy code" from Michael Feathers
- the "beyond refactoring" part which goes to explain mainly the usage of DevOps practices

The book stays at the surface of refactoring difficulties, tries to fit too many things and explain the usage of specific tools like PMD, Gradle or Vagrant which are not really relevant.
Profile Image for Zbyszek Sokolowski.
299 reviews16 followers
August 6, 2016
The book overall I found good provided that target audience is developer who is working for up to 20 years old project and he/she is so backward with up-to-date standards that need to have some refreshment. I didn't like a chapters with Ansible because book is quite generic but in those fragments seems to put his ideas somehow forcible, and forcing himself to add whatever.

I liked a part related to Microservices

below some quotes which I have found as useful:

"Most importantly, exploratory refactoring increases your understanding of the code. The more you explore, the more you understand."

You probably have a clear idea of which classes or packages are most dangerous, and you’ll avoid touching them if possible. This is counterproductive, because this “dangerous” code is exactly what should be receiving the most attention from developers, and it’s probably a good candidate for refactoring.

Unless the staging environment is an exact replica (within reason) of the production environment, its value in showing you how the software will behave in production is severely diminished.

The analogy with software is, of course, that you need to keep on top of your codebase and keep it neat and tidy. Leave too many hacks and pain points unfixed, and the quality of the code will rapidly deteriorate. Developers will lose their respect for the code and start to get sloppy.

The most important thing, far more important than anything we can say about the code, is to build software that provides value to its users. If you’re building the wrong thing, nobody will care what the code looks like. How to make sure your software provides value is outside the scope of this book, so let’s assume for now that we have a great product manager to take care of that for us.

Microservices are an SOA in which the independence of services is strongly emphasized. Services must be decoupled, so that it’s possible

Profile Image for Christophe Addinquy.
390 reviews18 followers
April 22, 2018
There are not so many book in my opinion about how to handle the "legacy problem". And a problem, it is! The Michael Feather's is the most famous one, but it brings an "inside out" approach only and it begins to be old. So I had some expectations about this text.
Unfortunately, my expectations weren't reached. The author seems to have very little idea about the required approach to legacy. he focused on aspects like quality which is a very academic concern on the subject when you don't have even control on the behavior. Overall, the text is based on some sample projects from the author experience, but doesn't convince me. It doesn't appears to be even close to the famous "working with legacy code" which predates this one by far. Then yes, disappointing.
Ma note de lecture en Français ici
Displaying 1 - 9 of 9 reviews

Can't find what you're looking for?

Get help and learn more about the design.