some news before we get to the essay
đ Iâve published a draft of the Introduction to Runnable Specifications. I normally write the intro at the end, once I know what Iâm going to say, but I had a lot of people holding back comments because they thought I might address them in the Introduction. Well, this is what I wanted to say in the introduction, so now thereâs no confusion. As always, I welcome comments and suggestions, critiques and insults.
đˇď¸ If you want a copy of Grokking Simplicity (GS) in any format, you can use the coupon TSSIMPLICITY for 50% off. GS is the book that I wanted to recommend to people when they were curious about functional programming.
đ Office hours have begun again in earnest. Iâve been solving the live stream problems. I think Iâve got it down now. Thursdays!
đ§ I will be speaking in Leuven, Belgium, at Heart of Clojure this year. This looks like a wonderful, human-centered conference. Iâm happy to be going. If youâd like to go, the first 10 people to buy tickets with this link will get a 5% discount.
Hiding in plain sight
I once met one of the legends of software design, Sandi Metz, after her talk. A group of people had formed around her in the hallway. Most seemed content to absorb her presence. They didnât say much. But I had an agenda.
Her talk was great. She showed how you can identify hot spots in your code. Theyâre the files with lots of code complexity that also get committed to a lot. She explained a lot about software design, how code gets to be a mess, and more. Then she refactored some code by following code smells and made everything better.
Like I said, it was a great talk, and I had studied her other talks and read her book. But something didnât sit right with me. I just didnât know what. I have tried to explain it many times, including in the talk I gave at the same conference a few hours before. Basically, I donât think refactoring is enough.
So thatâs what I said: âI donât think refactoring is enough.â
âYou have to trust that it is,â she replied.
Ugh. So unsatisfying. Of course, itâs my fault. The way I phrased it, it sounded like I didnât have confidence in my own refactoring skills. On the contrary, I use refactoring all the time, and I often have experiences like she showed in the talk where I use refactoring to find a better way to express the problem. But at the same time, what she showed us was more than refactoring. Explaining what she was doing as ârefactoringâ was not enough. Refactoring just means changing the code. It doesnât mean making it better in any particular way. And it certainly didnât explain how she chose which refactorings to do.
Hereâs a quote from an interview with her and her co-author, Katrina Owen, talking about some of their process for writing their book, 99 Bottles of OOP.
KATRINA: Over and over again, we would have this disagreement. Exactly what Sandi said, "This is wrong," and I'm like, "It can't be wrong because the rule says it's right." And we'd arrive at an understanding of a better rule.
SANDI: Yeah.
âon the Greater than Code podcast (transcript)
Sandi would present a rule, Katrina would follow it to the letter, and then Sandiâs 35 years of experience would jump in and say, âNo, thatâs not right.â It made me think of all the rules and principles and patterns that require years of experience to use correctly. Theyâre too common in the industry.
The two co-authors shared their story as an example of the wonders of collaboration. But it made me feel like all of their talk about rules was not really getting where they thought it would. I just donât believe rules can capture 35 years of software design experience. Either they miss the mark or they are so convoluted that you canât use them.
For instance, this is what one of the rules looks like after going through their collaborative process:
Flocking Rules
1. Select the things that are most alike.
2. Find the smallest difference between them.
3. Make the simplest change to remove that difference:
a. parse the new code
b. parse and execute it
c. parse, execute and use its result
d. delete unused codeAs youâre following the rules:
In general, change only one line at a time.
Run the tests after every change.
If you go red, undo and make a better change.
These are the mechanical refactoring rules they state. But they come after a lengthy (10 page) discussion of how to choose what to refactor that includes no rules as consise as these. I just donât buy that you can do this with rules alone.
Yet I believe in her. She has this skill. She does it. What was she doing? After a careful rewatching of one of her better talks on refactoring, I saw the answer. Sheâs using refactoring, yes, but sheâs using it to build a better domain model. She overemphasizes the mechanical changes to code structure and underemphasizes her deep intuitive process of seeking out a good domain model.
Once I saw it, I began to see it everywhere. Not just in her talks, but everywhere. Any time people were talking about design, they were really talking about the domain model. They just never explicitly mentioned it. But itâs there.
For instance, 99 Bottles of OOPâs third chapter is called âUnearthing Concepts.â Itâs about following duplication to find important concepts in the domain (which they call âunderlying abstractionsâ or âunderlying conceptsâ).
Section 3.7.3 (âNaming Conceptsâ) discusses how to decide what to name a method based on words from the domain
If you were to ask your users, âWhat kind of thing is a bottle?,â they wouldnât reply âItâs a unit.â Instead they might call it the container.
Throughout, thereâs a lot of discussion of code smells and coding problems (like complex if statements), but the end goal of a lot of it is âfinding the right abstractions.â That sounds like domain modeling to me.
In Nothing is Something, she use the Null Object Pattern to make functions total and also to show that many abstract things can be part of a domain.
When you first started writing in OO, it was really easy to see that real things could be modeled as objects. The chair that you're in. The person beside you.
And it didn't take long once you started writing code to figure out that more abstract things can be modeled usefully.
So, in the end, it seems that both code quality and domain modeling are important, just as style and substance are essential to creating a beautiful novel. I donât know why we focus more on the code, but I hope to refocus us, if only just a little, back onto the domain, in my upcoming book, Runnable Specifications.
Refactorings can be useful "in the small" but to refactor "in the large" definitely means being guided by _something_. Articulating that "something" isn't always easy and I think "domain modeling" is doing a lot of heavy lifting as the explanation -- the key phrase to me is "deep intuitive process" and I've always wondered how we can better teach developers about that?
×֟֡רְ×ÖśÖŁ× ×ÖźÖ°×֡רְ×ÖśÖŁ× ×Ö¸Ö×Öˇ× ×Ö°Ö×Ö´Ö××Š× ×ÖˇÖŁ×Öˇ× ×¤ÖźÖ°× ÖľÖ˝×֞ר־ע־ֽ××Öź×
As iron sharpens iron, so a man sharpens the wit of his friend.
https://www.sefaria.org/Proverbs.27.17