ryanlevell / books

MIT License
0 stars 0 forks source link

Working Effectively with Legacy Code (72%) #16

Open ryanlevell opened 1 year ago

github-actions[bot] commented 1 year ago

Congrats on starting Working Effectively with Legacy Code by Michael Feathers, I hope you enjoy it! It has an average of 4.5/5 stars and 6 ratings on Google Books.

Book details (JSON) ```json { "title": "Working Effectively with Legacy Code", "authors": [ "Michael Feathers" ], "publisher": "Prentice Hall Professional", "publishedDate": "2004-09-22", "description": "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. The topics covered include Understanding the mechanics of software change: 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 structure This book also includes a catalog of twenty-four dependency-breaking techniques that help you work with program elements in isolation and make safer changes.", "image": "http://books.google.com/books/content?id=fB6s_Z6g0gIC&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api", "language": "en", "averageRating": 4.5, "ratingsCount": 6, "categories": [ "Computers" ], "pageCount": 456, "isbn10": "0132931753", "isbn13": "9780132931755", "googleBooks": { "id": "fB6s_Z6g0gIC", "preview": "http://books.google.com/books?id=fB6s_Z6g0gIC&printsec=frontcover&dq=intitle:Working+Effectively+with+Legacy+Code&hl=&cd=1&source=gbs_api", "info": "https://play.google.com/store/books/details?id=fB6s_Z6g0gIC&source=gbs_api", "canonical": "https://play.google.com/store/books/details?id=fB6s_Z6g0gIC" } } ```
When you're finished with reading this book, just close this issue and I'll mark it as completed. Best of luck! đź‘Ť
ryanlevell commented 1 year ago

As recommended by the intro, I plan to read Part I and Part III, and use Part II as an FAQ.

Page 8:

Most reams that I've worked with have tried to manage risk in a very conservative way. They minimize the number of changes that they make to the code base. [...] "What? Create another method for that? No. I'll just put the lines of code right here in the method, where I can see them and the rest of the code. It involves less editing, and it's safer."

It's tempting to think that we can minimize software problems by avoiding them, but, unfortunately, it always catches up with us. When we avoid creating new classes and methods, the existing ones grow larger and harder to understand.

When people don't make changes often they get rusty at it. Breaking down a big class into pieces can be pretty involved work unless you do it a couple of times a week. When you do, it becomes routine. You get better at figuring out what can break and what can't, and it is much easier to do.

ryanlevell commented 1 year ago

Page 13:

One of the most frustrating things about larger tests is that it seems that we can have error localization if we run our tests more often, but it is an illusion. It we run our tests and they pass, and then we make a small change and they fail, we know precisely where the problem was triggered

ryanlevell commented 1 year ago

Page 18:

The Legacy Code Change Algorithm:

1. Identify change points.
2. Find test points.
3. Break dependencies.
4. Write tests.
S. Make changes and refactor.
ryanlevell commented 1 year ago

Skipped Part II, Part III:

Page 311-312:

Has this ever happened to you? You start to work on one thing, and then you think, "Hmm, maybe I should clean this up." So you stop to refactor a bit, but you start to think about what the code should really look like, and then you pause. That feature you were working on still needs to be done, so you go back to the original place where you were editing code. You decide that you need to call a method, and then you hop over to where the method is, but you discover that the method is going to need to do something else, so you start to change it while the original change was pending [...] Well, that's how it goes on some teams. A pair has an exciting programming episode, but the last three quarters of it involve fixing all of the code they broke in the previous quarter.

I have this little mantra that I repeat to myself when I'm working: "Programming is the art of doing one thing at a time." When I'm pairing, I always ask my partner to challenge me on that, to ask me "What are you doing." If answer more than one thing, we pick one.

ryanlevell commented 1 year ago

Page 317:

It's easy to make a mistake and have no idea that you've broken the software. A second set of eyes definitely helps. Let's face it, working in legacy code is surgery, and doctors never operate alone.

ryanlevell commented 1 year ago

Page 328:

Superficially, this might look like we're making things pretty for prettys-sake, but one pervasive problem in legacy code bases is that there often aren't any layers of abstraction; the most important code in the system often sits intermingled with low-level API calls. We've already seen how this can make testing difficult, but the problems go beyond testing. Code is harder to understand when it is littered with wide interfaces containing dozens of unused methods. When you create narrow abstractions targeted toward what you need, your code communicates better and you are left with a better seam.

Your bias should be toward making changes that you feel more confident in rather than changes that give you the best structure. Those can come after your tests.