Notes While Watching Schuchert Refactoring Legacy
https://vimeo.com/31927512
Conclusion: Screencasts are great but how you approach them is very important. Brett was talking the whole time to the audience about his intent and thoughts and then coding as support. Not the other way around!
Key things about legacy refactoring
Some of the key things that go into legacy refactoring. I want to try and maintain backwards compatibility. Often that means I maintain method signatures, method names and so on. I’m gonna try to do it such that existing code is unchanged because to try to change all the code is often either aggressive or not even possible (if it’s a library or jar).
In general for refactoring, legacy refactoring being a kind of it, I’m going to start by doing something creational as opposed to destruction. I create a new class and move stuff into it. I say move but what move actually means to me when I’m talking about refactoring is create, copy, update, remove.
Introduce instance delegator
//todo: check for feather’s book whats written there. show code sample of adding instance singleton, how to make method non-static etc how to reset for tests
Only for a static method that does something like require some weird classes to be loaded, goes outside the system, maybe actually it’s costly. I might write a version of it that has a precalculated result for some kind of big array or some kind of graphical analysis. And then it returns a cached result as opposed to returning back an actual result. I’m not just gonna do this anywhere. In fact, if I have a large legacy codebase I’m not gonna do it anywhere, unless I have something to change. As much as i want all the code to have tests and i want the code look nice and clean, really what i care about is the stuff thats changing. im not gonna touch stuff thats not changing.
Continuous Integration
the practise, not the tool crap
2 words, 7 steps
- my code compiles
- my tests pass
- I get all updates from everybody else
- my code still compiles
- my tests still pass
- noone else checked in since I did that
- check in
TDD vs test-after
When I’m testing a class, I’m not actually testing the methods of the class, I’m testing uses of the class, scenarios. So when I try to verify that a class does something, I think about writing a test that consumes in a way that I would expect my client code to consume it. it turns out that the smaller and more detailed the class is, the closer that happens to look like I’m testing a method. thats incidental. So i think about the consumption of a class, the scenarios of usage. thats my goal. the fact that I’m writing the test after the fact and i’m testing a method, already makes what i’m writing very different than if i did it test first.
The only relationship tests written using a test-first approach have with tests written using a test-after approach is, they both use JUnit.
Opinions
Refactoring is more of a creational step as opposed to a destructional step. The rational for that is: You are gonna be interrupted while working, so you want to take enough steps so that at any given point in time, the likelihood that your stuff still compiles and what tests you have still pass, is greater. You’re end up going through more transitions to get to the end result but you’re also more interruptable, and since you can’t change the fact that you gonna be interrupted, it’s a better approach.
If my solution requires tools then it’s not really a solution. And if we don’t take the time to fix the code then we’re gonna continue the same code in the future than we’ve done in the past. So by having to pay the cost of fixing the thing that is broken you’ll learn how not to do it in the future and then you won’t need jmockit. So a tool like jmockit, it’s a great tool, but I think it’s just delaying the inevitable of learning how to design with a modular approach in mind.
Try to focus on one thing. If I’m doing a refactoring you might as you’re in the middle of one refactoring notice, oh wow i dont like the name of that method. Im gonna change it. the temptation is great. dont do it! stick to one thing. you get it done faster. and then stick to something else again. because if you start to change in the middle of an existing change once you start that, there is nothing to stop you from going ad nosium until eventually you never get to anything finished. Pairing will help. Because if I were doing that, someone would slap me up side the head and say “hey, idiot, stop, get back on track”. Development is faster when you pair. the research shows that. there is no counter evidence to that. that doesnt mean it is true, but it has a better argument than the counter. (1:44:34)