Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login

Working Effectively with Legacy Code by Michael Feathers. It's a bit hard to wrap your brain around the Java and C++ examples unless you have experience with them, but the techniques are timeless. You may need to practice them extensively before you understand how important they are, though. In a recent book club we did at work, a common complaint was, "This just looks like common sense". Indeed it does... though the common sense is uncommonly hard to find when you are staring at the actual situations this book helps you with.


view as:

I just finished reading this book yesterday. I am not an expert in refactoring but the book seems too old, although most advises could be still useful. Anyway, today I found a new book by the author: Brutal Refactoring: More Working Effectively with Legacy Code. Unfortunately, I couldn't find a good review of the book on the Internet. But I think it could be more useful.

"the book seems too old"

2004 is old now? Really?

Honestly, good books don't age as long as their core domain stays valid. Structurally C++ is pretty much the same as when the book came out.


Modern IDEs can deliver many of the recommendations of the book. Our productivity has increased a great deal. Back then there was no intellisense, code navigation through clicking on method names/classes etc. highlighted syntax errors, built-in unit test frameworks etc.

It was written for a different type of developer and a different type of development environment and a specific language, C++.

You haven't looked at C++ lately if you think it's the same as it was in 2004. The ISO has released new versions of the language in 2011, 2014 and ratified a new standard here in 2017. If you're writing C++ code that is consistent with 2004 C++ then you're writing a really bad version of "C with classes", not C++.

Edit:

Modern C++ contains native support for the filesystem, threads, lambda expressions, variants, upcoming networking library, coroutines (at least in Visual Studio), no more new/delete memory management, parallel algorithms and a ton more. This is a completely different language now and the code you write looks nothing like 2004 C++ code.


Our productivity has increased a great deal. Back then there was no intellisense, code navigation through clicking on method names/classes etc. highlighted syntax errors, built-in unit test frameworks etc.

Just about all of these things were around in 2004.


Intellisense (the MS one) was introduced in 1996. VB6 had good intellisense. I seem to remember having intellisense while working in classic asp vb (as in pre .Net), but could be wrong, it's so long ago now.

A lot of people have to maintain legacy C++98 codebases and don't get to play with new compilers.

"You haven't looked at C++ lately if you think it's the same as it was in 2004."

"If you're writing C++ code that is consistent with 2004 C++ then you're writing a really bad version of "C with classes", not C++."

I applaud your attempt at an authoritative voice. But you focus on mostly technical trivia that are thin scaffolding on top of the language. I agree modern C++ is nice but it's the same language still.

"This is a completely different language now and the code you write looks nothing like 2004 C++ code."

Are you trolling? This reads like a transcript from a TV commercial.


They sound like they're echoing the kinds of things that are normally said about C++11.

> I agree modern C++ is nice but it's the same language still.

Well...in the same sense that any language is the same language after you add a bunch of things to it that weren't there before and shift to using those new features as idiomatic parts of the language. I would expect C++ written in 2004 to use different patterns than C++ written in 2017. Not "completely different"...but different.


Idiomatic sounds like preference to dogmatism rather than pragmatism which is generally the worse tradeoff.

I would say generally C++ style has evolved through last decades with people understanding class based architecture as an antipattern and data pipelines based on preferably immutable data as the more robust and understandable approach. This has nothing to do with language standards or 'idiomatic' constructs - both can be expressed as perfectly elegant C++, using the '98 or '11 or '17 variant.

But anyway, within this context - refactoring old code - I would not expect a legacy codebase to resemble 2017 C++ as much as 1997 C++. This is the main reason I find the claim of methods to understand circa 2004 C++ to be outdated to be silly.


> Idiomatic sounds like preference to dogmatism rather than pragmatism which is generally the worse tradeoff.

That's never been the way that I've read it, and it's not how I meant it. New language constructs allow for more-natural ways for the code to express the intent of the programmer, replacing the use of older constructs in the places that they were clumsy.

The entire point is to make the language more practical. Patterns of use in a language aren't idiomatic because of dogma (or at least, they shouldn't be). They're idiomatic because they're a clear and elegant way (or at least the most elegant way available) to implement something.

> I would not expect a legacy codebase to resemble 2017 C++ as much as 1997 C++.

Agreed, but then we come back to the fact that we might refactor a 1997 codebase differently in 2004 than in 2017.


"Agreed, but then we come back to the fact that we might refactor a 1997 codebase differently in 2004 than in 2017."

Well, if the original code is of the worst kind of a mess, Feather's circa 2004 collection of methods to make it more understandable but functionally the same work just fine for the first part of the refactoring. In my experience this is the most difficult part as well. To what dialect of the language the code is ported after it is understandable, is a relatively trivial syntax transform after this.

I speak from experience from having recently had to implement features to a production codebase with millions of lines of code, some of which date back to Fortran, and that took the final step of evolving into C++ sometimes in the late 90's.

I prefer the definition of legacy code that it's any code that does not have unit tests. In this case every transformation to a production codebase needs to retain the original behavior - without exact understanding what that behavior is.

I think this comment should have been my original response to this thread instead of the relatively cheeky responses I wrote earlier.


Modern IDEs can do many of the refactorings required when modifying code, yes. But you still need to know where to find seams or how to create them. Refactorings are just tools for getting there. It doesn't seem like you have read the book.

Me and a friend continually send IM's to each other, "LEAN ON THE COMPILER!".

That statement alone, one of the sections of the book, recommending you to allow the compiler to find your errors for you, is an example of the "age" of the book.

At the time I read it, when it first came out, I loved it. I still love Michael's work and advice to this day, but this book was written for another time.


I do not understand this. It seems like a perfectly good advice, and in fact it's what I'm doing every day - leaning on my compiler, and in Java world, on my IDE.

And also it seems to be something lots of programmers don't realize for some reason - many times I had to instruct people to crank up their compiler warning settings and actually read them. Especially in C-land, I can't count the number of times I solved someone's problem by appending -Wall to the gcc invocation and telling them to come back after they fixed all the warnings...


My point was that with a modern IDE we can do that without resorting to a full compile, which can be burdensome with large codebases.

The IDE space has improved a lot since 2004, eg. Jetbrains' tools around refactoring and code cleanup suggestions, make things super simple.

Don't get me wrong, I've read this book, multiple times, it's on my bookshelf and think it's a great book, but it was written when the state of development was a much different landscape, IMO.


Leaning on incremental compile via a modern IDE is leaning on the compiler. The principle is the same, even if the implementation slightly differs.

Every day I wished I'd listened to the XP guys the first time I encountered it, and most of that material is from the late 90's.

And Fred Brookes' book is over 30 and sadly just as relevant.


Just looking at the responses to this comment, I have to say that I agree with both sides. The book is really dated, but the advice is timeless. The biggest problem I've had trying to get people to take the book seriously is that they can not identify with it. I had not realised that Michael Feathers had written a followup. I will definitely take a look. Thanks!!!

Legal | privacy