Working Effectively with Legacy Code

Working Effectively with Legacy Code

Language: English

Pages: 456

ISBN: 0131177052

Format: PDF / Kindle (mobi) / ePub

Get more out of your legacy systems: more performance, functionality, reliability, and manageability Is your code easy to change? Can you get nearly instantaneous feedback when you do change it? Do you understand it? If the answer to any of these questions is no, you have legacy code, and it is draining time and money away from your development efforts. In this book, Michael Feathers offers start-to-finish strategies for working more effectively with large, untested legacy code bases. This book draws on material Michael created for his renowned Object Mentor seminars: techniques Michael has used in mentoring to help hundreds of developers, technical managers, and testers bring their legacy systems under control. adding features, fixing bugs, improving design, optimizing performance Getting legacy code into a test harness Writing tests that protect you against introducing new problems Techniques that can be used with any language or platform--with examples in Java, C++, C, and C# Accurately identifying where code changes need to be made Coping with legacy systems that aren t object-oriented Handling applications that don t seem to have any structureThis book also includes a catalog of twenty-four dependency-breaking techniques that help you work with program elements in isolation and make safer changes. (c) Copyright Pearson Education. All rights reserved.

seams. We would have had to use the link seam (36) or the preprocessing seam (33) to substitute one implementation for another. When we use the class and virtual function approach and parameterize the class, the seams that we have are explicit and easy to manage. Steps To Encapsulate Global References, follow these steps: 1. Identify the globals that you want to encapsulate. 2. Create a class that you want to reference them from. 3. Copy the globals into the class. If some of them are

do anything special to their application. It can be done, but it is usually more work than anyone on a team is prepared to admit. In addition, a user interface often isn’t the best place to write tests. UIs are often volatile and too far from the functionality being tested. When UI-based tests fail, it can be hard to figure out why. Regardless, people often spend considerable money trying to do all of their testing with those sorts of tools. The most effective testing tools I’ve run across have

that we can use to make the job easier. Let’s talk about context. In legacy code, one of the most important considerations is that we don’t have tests around much of our code. Worse, getting them in place can be difficult. People on many teams are tempted to fall back on the techniques in Chapter 6, I Don’t Have Much Time and I Have to Change It, because of this. We can use the techniques described there (sprouting and wrapping) to add to code without tests, but there are some hazards aside from

good refactoring tool will only allow you to do an automated extract method refactoring when it is safe. However, that just makes the editing that we do between uses of the tool the most hazardous part of the work. Remember that it is okay to extract methods with poor names or poor structure to get tests in place. Safety first. After the tests are in place, you can make the code much cleaner. Chapter 11: I Need to Make a Change. What Methods Should I Test? We need to make some changes, and

infect the rest of our software. Covering software means covering it with tests. When we have a good set of tests around a piece of code, we can make changes and find out very quickly whether the effects were good or bad. We still apply the same care, but with the feedback we get, we are able to make changes more carefully. If you are not familiar with this use of tests, all of this is bound to sound a little bit odd. Traditionally, tests are written and executed after development. A group of