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.

 

 

 

 

 

 

 

 

 

 

“little” is different. When I say “little,” I mean two or three lines—five, at most, a chunk of code that you can easily name. The key thing to pay attention to when you do these little extractions is the coupling count of the extraction. The coupling count is the number of values that pass into and out of the method you are extracting. For example, if we extract a max method out of the following method, its count will be 3: void process(int a, int b, int c) { int maximum; if (a > b) maximum

assertEquals(400, employee.getPay()); } } In the EmployeeTest class, we have a special method named setUp. The setUp method is defined in TestCase and is run in each test object before the test method is run. The setUp method allows us to create a set of objects that we’ll use in a test. That set of objects is created the same way before each test’s execution. In the object that runs testNormalPay, an employee created in setUp is checked to see if it calculates pay correctly for one timecard,

it’s producing. The header row should look something like this: "
Department Manager Profit Expenses

" Furthermore, let’s suppose that this is a huge class and that it would take about a day to get the class in a test harness, and this is time that we just can’t afford right now. We could formulate the change as a little class called QuarterlyReportTableHeaderProducer and develop it using test-driven development (88). using namespace std; class

helps development go faster. The human mind has some interesting qualities. If we have to perform a short task (5-10 seconds long) and we can only take a step once every minute, we usually do it and then pause. If we have to do some work to figure out what to do at the next step, we start to plan. After we plan, our minds wander until we can do the next step. If we compress the time between steps down from a minute to a few seconds, the quality of the mental work becomes different. We can use

set the validation flag becomeValid(); } }; Facility facility = new IndustrialFacility(Facility.HT_1, "b", new AlwaysValidPermit()); assertTrue(facility.hasPermits()); } In many languages, we can create classes “on the fly” like this in methods. Although I don’t like to do it often in production code, it is very convenient when we are testing. We can make special cases very easily. Subclass and Override Method (401) helps us break dependencies on parameters, but sometimes the factoring

Download sample

Download