

Buy anything from 5,000+ international stores. One checkout price. No surprise fees. Join 2M+ shoppers on Desertcart.
Desertcart purchases this item on your behalf and handles shipping, customs, and support to Cook Islands.
This book provides programmers with the ability to cost-effectively handle common legacy code problems without having to go through the hugely expensive task of rewriting all existing code. It describes a series of practical strategies that developers can employ to bring their existing software applications under control. The author provides useful guidance about how to use these strategies when refactoring or making functional changes to codebases. One of the book's key points is that it teaches developers to write tests that can be used to ensure they are not unintentionally changing the application as they optimize it. Examples are provided in Java, C++, and C#, and the book assumes that the reader has some knowledge of UML notation. Strategies using UML and code in C++ and Java are emphasized, while language-independent advice is delivered in sidebars and appendices for language-specific users. Review: Simply supurb, a tour de force - The vast majority of software texts are about greenfield development: creating a new application from nothing at all. But the vast majority of software work involves existing code: adding features, finding bugs, or refactoring code that someone else wrote. This book is a supurb first step in fixing that imbalance. This is not a theoretical work. For example, Feathers does not present a grand ontology of legacy systems. Not is this book heavy on methodology. Instead Feathers describes techniques --- lots of techniques, roughly 50 --- for working with legacy code. The techniques are organized by the problems they address. For example, one chapter is entitled "My Application Is All API Calls" and then presents two techniques for working with existing code that is full of calls to APIs. Feathers comes from the XP school, and he adopts that school's premise that you can safely change code if (and only if) there are sufficient tests in place to tell you when your new change has introduced a bug. Many of the techniques in this book are about different ways of putting legacy code into test harnesses, and doing that safely without introducing bugs along the way. He also introduces new concepts, or at least concepts I had never seen before. For example, a "characterization test" is a test that characterizes the actual behavior of the code, not what the code is supposed to do, but what it actually does. Why is that useful? First, it is an effective way of documenting what a system actually does, particularly if --- as with most legacy code --- there is no other documentation. And it can tell you when you have changed that existing behavior. Feathers' style is easy to read. As you would expect there is lots of example code here, and it is folded naturally into the explanatory text. My only gripe with the book is with the examples: they are largely in Java, C++, or C. I would have liked some examples in older legacy-only languages, like COBOL. But overall, this book is simply supurb, a tour de force of an important topic that has received little coverage before. Review: Practical, Realistic, and focuses on what can be done now - The book is one of the rare books I've read that has an ideal vision for programming and design that also starts with a realistic view of the true day-to-day of a some developers: stumbling through old code written to changing demands and fix bugs, needing assurance that one's changes don't break existing functionality without laborious and time-consuming investigation and ad hoc testing. Michael Feathers does a great job of modelling his mindset, choices, and techniques through short example case studies. Nothing is presented as dogma, and many cases are followed to see the effects of different techniques to solve the same problem. Many of the techniques to get code into a testable form are just best practice or are similar to a Design Pattern, but a key strength of this book is making getting from here to there within reach. Clients and superiors want code that works, and the testing and incremental approach that Michael advocates provides the net for safely and confidently making the transition to less tightly-coupled, more modular, understandable, and verified code from the time-tested battle-worn code many of us call home. Even better, Michael's approach destroys the "design vs just maintenance" dichotomy, as it satisfies that little voice to start making improvements we've been putting off when we get our code in testable form. I hope my department picks this up, and that we all start leaving the code a little better than we found it.




















| Best Sellers Rank | #75,526 in Books ( See Top 100 in Books ) #11 in Software Design & Engineering #12 in Software Testing #49 in Software Development (Books) |
| Customer Reviews | 4.5 out of 5 stars 731 Reviews |
D**D
Simply supurb, a tour de force
The vast majority of software texts are about greenfield development: creating a new application from nothing at all. But the vast majority of software work involves existing code: adding features, finding bugs, or refactoring code that someone else wrote. This book is a supurb first step in fixing that imbalance. This is not a theoretical work. For example, Feathers does not present a grand ontology of legacy systems. Not is this book heavy on methodology. Instead Feathers describes techniques --- lots of techniques, roughly 50 --- for working with legacy code. The techniques are organized by the problems they address. For example, one chapter is entitled "My Application Is All API Calls" and then presents two techniques for working with existing code that is full of calls to APIs. Feathers comes from the XP school, and he adopts that school's premise that you can safely change code if (and only if) there are sufficient tests in place to tell you when your new change has introduced a bug. Many of the techniques in this book are about different ways of putting legacy code into test harnesses, and doing that safely without introducing bugs along the way. He also introduces new concepts, or at least concepts I had never seen before. For example, a "characterization test" is a test that characterizes the actual behavior of the code, not what the code is supposed to do, but what it actually does. Why is that useful? First, it is an effective way of documenting what a system actually does, particularly if --- as with most legacy code --- there is no other documentation. And it can tell you when you have changed that existing behavior. Feathers' style is easy to read. As you would expect there is lots of example code here, and it is folded naturally into the explanatory text. My only gripe with the book is with the examples: they are largely in Java, C++, or C. I would have liked some examples in older legacy-only languages, like COBOL. But overall, this book is simply supurb, a tour de force of an important topic that has received little coverage before.
C**V
Practical, Realistic, and focuses on what can be done now
The book is one of the rare books I've read that has an ideal vision for programming and design that also starts with a realistic view of the true day-to-day of a some developers: stumbling through old code written to changing demands and fix bugs, needing assurance that one's changes don't break existing functionality without laborious and time-consuming investigation and ad hoc testing. Michael Feathers does a great job of modelling his mindset, choices, and techniques through short example case studies. Nothing is presented as dogma, and many cases are followed to see the effects of different techniques to solve the same problem. Many of the techniques to get code into a testable form are just best practice or are similar to a Design Pattern, but a key strength of this book is making getting from here to there within reach. Clients and superiors want code that works, and the testing and incremental approach that Michael advocates provides the net for safely and confidently making the transition to less tightly-coupled, more modular, understandable, and verified code from the time-tested battle-worn code many of us call home. Even better, Michael's approach destroys the "design vs just maintenance" dichotomy, as it satisfies that little voice to start making improvements we've been putting off when we get our code in testable form. I hope my department picks this up, and that we all start leaving the code a little better than we found it.
M**W
It's ok, all should read at least once
My perspective is as a mid-thirties adult male who went straight from college to a job I'm still at 11+ years later, working on a large, sprawling, legacy software suite with almost no unit test coverage. Our software is the culmination of 40+ devs and contractors who came and went over the product's 20+ year lifespan. There was never an architect. There was never much oversight, pretty much pick whatever stack you wanted to build a certain feature as long as the resulting UI was vaguely consistent. Half of our application is served by legacy Java and half is ASP .NET, and most of the time navigating the software you can't tell from the UI which codebases served your page (or what parts of your page). It is hundreds of thousands of lines of tangled legacy code which all sorts of different database access strategies and UI frameworks depending on who wanted to experiment with what at the time they were there making a new feature. Having not known anything other than this one project for my entire career, and not having a college or professional work culture that ever pushed testing on us (until now), it was kind of eerie to read through this book and find seemingly endless examples of the issues and challenges that obstruct my normal work every single day. I feel like I understand better now why some people are adamant about testing, it would have made a huge difference in what it's like to work on this legacy project of ours today, if it had been a priority way back when. It is also evident to me however after reading the book that testing is not like some magic bullet, either, and just sprinkling some tests around doesn't fix problems like the ones I face. The author comes off a bit over-excited about how unit tests could change your life (paraphrasing), and he is right, but you have to put in the actual work. I would describe it like getting hooked by one of those old Bowflex TV commercials and so you get the workout equipment and then realize "wow, I am going to have to do a lot of work to get the results I want", and then this book is at least trying to be your workout guide on what muscle groups you should be exercising and roughly how to do it. Pretty useful but you still have to put it all together yourself into a routine that is right for you/your team/your project, and then actually do the work, continuously. Reading this book and then not applying the advice within will get you about the same results as reading a book about workouts and exercise for a healthy body and then continuing to not exercise and eating fast food for lunch every day. I think in my case after working in real-life examples of whats in this book for over a decade very little of it surprised me in any way, but it was helpful to see these things spelled out with their cause and effect, ideas for solutions, how to at least avoid making the problem worse, etc. I understand now why some people we would hire as new developers to the project would get all sad and disappointed when they asked about tests and we told them we really don't have any. I literally never knew any better and wasn't convinced until I read this book. So I would say that all devs/engineers should read this book at least once, there is value in it for sure. On the downside, prepare yourself for a difficult and dull slog. The book, for all its wisdom within, is not particularly engaging to read and the examples are just. plain. awful. Truthfully even if I had read this book 10+ years ago when I was getting started, I'm not sure the examples would have spoke to me (because they are terrible), which might have made it less convincing. But it was the case that at the time I read this I had been working and playing with live examples for a decade-plus as I said before so all the examples he described were perfectly apparent to me in my own project's code. His examples stink. I think it would help newer developers if there was a digital copy that you could provide some parameters and get examples in only a language that is familiar to you. That and also re-write all the examples to not stink somehow. I don't know, the examples are hyper-realistic in the sense that "yeah, I have definitely seen people write garbage like this all the time," but the things he is trying to demonstrate in these examples don't have to be made more realistic by using awful naming, spacing, lack of comments, etc. Just my personal opinion. It is a difficult book to force yourself to keep reading through, in my opinion, but you definitely should and you will most likely be glad you did.
H**R
Must have book in your collection
If you are working in Legacy Systems, this is a must have book in your collection.
A**N
Fine Advice for Real-world Programming
It should be no secret that the majority of commercial software development effort consists of dealing with other people's poorly constructed code, yet this book is one of only a handful of sources that offer any practical advice for such undertakings, and the closest thing to a comprehensive reference on the subject so far as I know. Here you'll find dozens of useful techniques organized according to the kind of problem that they address, each explained concisely with concrete examples. Lots of them are things that I've had success with in the past, and of the ones I haven't tried yet, there's nothing in my 19 years of industry experience that leads me to doubt that they work. A word of caution, though: It understates both the difficulty and the importance of having everyone who works on the same code to buy into the ideas it puts forth. Negligent programmers will resist change because they tend to benefit from "adverse selection" (look it up on Wikipedia), and you really don't want to be the only one worrying about code coverage and maintainability while everyone else creates messes for you to clean up. Appealing to engineering wisdom and common interest is not always so easy as it sounds. But on the whole, this is fine advice, and every programmer should own a copy. Not only will it help you to better the quality of your life by improving the state of your most troublesome projects, but also it will teach you to minimize the problems that you create in the first place, as well as how to fix those problems before they become too costly.
A**G
This book will change your life as a coder for the better.
Whether taking on TDD, breaking dependencies or trying to maintain code that's lacking testing this book is a must read. Is your code a tangled mess? Are you tired of seeing telescoping methods and methods that are 100s of lines long? Want to clean up code you didn't write and get it under test but everyone's too afraid of breaking things? Does it take you forever to write unit tests? Is it painstaking and laborious? Do you write mainly integration tests because unit testing is too hard? Do you wonder how people can write lots of unit tests, let alone unit test every method? Do you want to kick your object oriented coding skills up a notch? Then this book is for you. It can teach you how to overcome all of those obstacles and so much more. For me the first roughly 100 pages of the book were a revelation. If you don't understand how to do TDD the problem probably isn't testing, it's probably the code you're trying to test or your perceptions about what it is that you are actually supposed to be testing. Michael Feathers does a great job identifying the mistakes and traps that so many developers experience when trying write and test good code and provides recipes for overcoming them. He adds clarity to what a unit test is and what it's supposed to do and in the process takes a deep dive into what good object oriented code looks like through the eyes of TDD. The book can completely change your perception about what is and is not possible. In addition to turning your perceptions about testing on their head, Feathers also provides good advice on how to create loosely coupled code, how to identify and eliminate dependencies in existing code as well as strategies for reorganizing poorly structured code into better objects. This book has clearly changed the way I code and the way I think about testing for the better. It's not just about testing it's also about turning procedural code into object oriented code and bringing your object oriented thinking to the next level. I can't say enough great things about this book. It's dearer to me than any other book in my programming collection including books about object oriented code from Bloch, Beck, Fowler and others. It wasn't until I read Working Effectively with Legacy Code that things really came together for me in the object oriented world. I got the concepts individually but failed to recognize how it all comes together. What's so great about encapsulation / getters and setter? Why is it so important to have classes and methods that do just one thing? What's so important about breaking dependencies between classes? How small is a small method? How can I ever hope to achieve open/closed? How is TDD even possible? Your mileage may vary, but if you're like me this book will change your life for the better.
C**A
Still worth a read...
This book isn't quite what I was expecting based on what I've heard from many other people about it (and some of the reviews). Having said that, it's still worth a read. The main problem I have with the book is that a good number of the examples use C++ or even C! First of all, while C/C++ applications often are "legacy applications" in the fullest sense of the word "legacy", that is not the author's interpretation of the word "legacy". The author defines "legacy code" as applications whose code does not have tests written in order to verify that the code does what it's supposed to do (or whose tests don't really test the code properly). The problem is, while there are still applications written in C/C++ today, the majority of applications are written in languages like VB.net, C#, and Java--and these languages have many various testing frameworks available for them (e.g. xUnit, JUnit, NUnit, MS Test, etc.). Therefore, some of the examples based on C/C++ really don't apply to these other, modern object-oriented languages (mainly because everything is an object in these languages and there is automatic garbage collection). Also, a lot of the refactorings he talks about again, are not relevant in languages other than C/C++. The space wasted on these refactoring patterns could have been better used. Having said all of that, there are a few nuggets in here that make this a worthwhile book to have on your shelf. So on the whole, given the choice of whether or not to buy this book again, I would still buy it. Just don't get too hyped up over it. Probably the best part about this book is that you don't have to read it from cover-to-cover to use the information in it. I did read it from cover-to-cover, but I'm equally happy to know that I can just as easily use it as a reference. So if I need to quickly find a refactoring pattern, I can find it in the contents or the index and read only that which I'm interested in.
F**O
Simple path to modernization
There is a lot of old code out there. Code that was written long before test-driven development was a thing. This book gives excellent explanation of how you can take that legacy code and nudge it towards something that can be unit tested and which is more secure. I definitely think anyone who works on a code base that has origins prior to 2010 should read this book.
M**.
Great!!!
Llegó en excelentes condiciones. Y muy rápido también 😁
P**I
Grande libro
Grande libro, devo ancora finire di leggerlo ma è molto utile. Consigliatissimo a tutte le persone che sviluppano, non solo a chi lavora con codice legacy. Lo consiglio soprattutto a chi scrive molto codice affiché non lasci in eredità ad altri altro pessimo codice legacy....
S**O
An excellent book
An excellent book if you need to modernize a legacy system without fear. Recommended for developers with experience. I realized that reading this book at the start of my career would have been pointless.
R**R
This book is a reprinting of very low quality - beware!
The book arrived with "Printed in the United States of America" in the front, and "Manufactured by Amazon.com.au in Sydney" at the back. On my copy, the cover is misprinted, and the contents of the book include printing and typesetting issues which are not present in the genuine article, such as page titles being half cut off. This book is not a genuine copy of the book, it is a locally printed book which is of severely less quality than the genuine book.
H**H
Fantastic book
This book definitely improves your programming skills. The talk about unit testing and it's benefits is good. More often than not we work in projects or on software that's old. Not every development is Greenfield. In such cases we wonder how to implement our newly learnt unit test skills. That's where this book sits and tells you exactly what to do. Don't read this book as a fresher. Gain some experience, fight some legacy code, invent some techniques of your own. Then come here and you would appreciate the book.
Trustpilot
3 weeks ago
2 months ago