I wanted to remember to blog about what I’m learning by reading Martin Fowler’s “Refactoring”, but I fell behind. No apologies, just moving forward from here. I’ll conflate what I’ve covered so far into one post.
I’m finally getting a theoretical understanding of why messy code is bad, and how to fix it. That’s the good news. The difficult news is that trying to apply the myriad concepts I see here is much more difficult than I imagined. But that’s okay! Learning is fun!
And as it gets tough, I lean heavily on this quote. “I’m not a great programmer; I’m just a good programmer with great habits.” So maybe we don’t have to be exceptional, just be rigorous in “how” we code. There is something quite comforting about that.
One major thing I didn’t understand, is I would try to approach refactoring, or adjusting the code, as a separate activity. First, write the code, then code it right. That’s not true at all. Fowler writes, “In almost all cases, I’m opposed to setting aside time for refactoring. In my view refactoring is not an activity you set aside time to do. Refactoring is something you do all the time in little bursts. You don’t decide to refactor, you refactor because you want to do something else, and refactoring helps you do that other thing.” It’s more of a state of mind and philosophy than a totally separate endeavor. While I understand that, I still see myself falling into bad patterns. I think the “wow” factor of getting something to work is almost too motivating — I don’t want to slow down. Teammate Serdar speaks of testing from the inside out, and part of me likes that notion. Being able to actually make something happen, but it’s not so tough to get to that first step.
And if I’m not motivated enough by seeing my code is messy, and needing to slow down, there’s a quote that speaks to that, too: “Programs have two kinds of value: What they can do for you today and what they can do for you tomorrow.” This is really big to me. When I come back to code, I’m always annoyed at my self of the past. But Past Self was just focused on what was Current Deadline. In a series of videos I watched debating the merits of testing recently, Kent Beck made a similar point. I’m paraphrasing, but it was related to the adrenaline rush he said he receives when his code is so simple and clean that when he comes back to it, he’s dreading it, because he is sure it will be difficult, but he has prepared so well for his Future Self that he still comprehends it. I’m a gazillion levels below that, but I can definitely appreciate that as a way to “reach for the stars”.
Meanwhile, I’d like to be able to understand the code I’m writing, like, an hour later.
So, what makes clean, well-factored code? Fowler again. “So, we want programs that are easy to read, that have all logic specified in one and only one place, that do not allow changes to endanger existing behavior, and that allow conditional logic to be expressed as simply as possible.” This speaks to separation of concerns (programming logic is separate from presentation), and the logic being easy to follow (lately, I seem to be the queen of having these horribly nested conditionals, which become very tough to follow. All I have to say about data work around Washington and elections are that there are a lot of special cases. Ooof.) I think these are all excellent ideas to keep in mind.
I am convinced that being more careful about code will make it easier in the long run and make me a better programmer, and better able to execute my visions, and the vision of those around me. But putting it into practice is a bit harder.
In Chapter 3, I also learned a bit about how to identify “code smells”, that is, feeling that something is wrong or messy with how code is written. While this chapter was difficult to parse, due to its reliance on chapters I haven’t yet gotten to, I already see myself knowing something is wrong, even when I don’t know how to fix it. Still, baby steps.
This book is also serving as a true introduction to classes, object-oriented programming and testing, all at once. I’ve always been a “cold turkey” kind of person, but it’s a lot to keep straight at once. Still, I’m trying to attack them all as part of a goal of “best practices”.
As Ira Glass has said, again, I’ll paraphrase, when we are learning, we recognize good work when we see it, even if we can’t yet make it happen. These first chapters of refactoring have enlightened me as to what good is, and importantly, started to give me a vocabulary to talk about the good. But trying to implement it on my own is a reminder that I’m not quite making it happen yet. But I’m getting closer, and at least I know now that is where I want to go. Each day is about doing one step better.
I am grateful for all I’m learning about Ruby, and how to organize information (attributes) and code that makes stuff happen (functions) in logical clumps. And starting to do automated testing has me thinking about the overall code in different ways. It’s impacted my thinking on the design architecture of programs, even small ones, and being much more thoughtful, even if imperfect, about the organization of the code I write.
Fundamentally, I much prefer having all of these ideas swirling in my head, and knowing that I need to embrace them, than living thinking these were all beyond me. I suppose I haven’t ever truly agreed with the phrase “Ignorance is bliss”, preferring “knowledge is power”. So, excited to move onward, with both the reading and valiantly trying to put all of this knowledge into practice. It’s simply invigorating!