A little housekeeping before I start the essay:
Runnable Specifications News
I renamed Chapter 2 to Chapter 1 because I learned that the Introduction doesn’t get a chapter number! Chapter 1 is much revised and better for it.
The chapter was getting long so I split off the section on reifying relationships and expanded it because it needed it. So now there are two chapters available. There’s one section I forgot to add to Chapter 2 which I’ll write this week. But it’s ready to read.
I would like your comments. What surprised you the most? What confused you? Just hit reply. I read them all. See the whole Table of Contents.
Changing days to Tuesday
I’ve been sending the newsletter out on Mondays for years now, but it always consumed my weekend. I’m moving it to Tuesday so I don’t have to spend Sunday night figuring it out.
Book sale
Manning is having a sale this weekend. On Thursday, 50% off all print books. On Friday-Sunday, 50% off everything. It’s a good opportunity to pick up Grokking Simplicity for you and your whole team.
And now for the essay:
What is software design?
I admit it: My next book is about software design. It wasn't easy to accept that, but I finally made peace with it. However, I’m adopting the term software design on my own terms.
To me, software design is the total of all your decisions when making software. That’s everything from what the software should do to how to architect it to the line-by-line decisions a programmer must make while coding. Anything less arbitrarily chops up the creation of software.
My definition tracks with definitions found in other fields where they use the term design. Steve Jobs has a famous quote:
Design is not just what it looks like and feels like. Design is how it works.
To me, that means design is the whole thing. It’s not just prettying up the code. It’s also the choice of data structure—which affects the memory usage—which affects its performance—which affects how the user perceives it. There’s no easy line to draw to divide design from non-design activity. Software design is holistic.
Design’s holism is also recognized by modern efforts to describe how high-performance teams operate. In Team Topologies, the authors describe stream-aligned teams that are empowered to understand customer needs and deliver them value without handoffs to other teams. Stream-aligned teams contrast with feature teams tasked with implementing features often described by someone upstream from them. There is an explicit handoff, often in Jira, between the team that invents the feature and the team that implements it.
According to the authors’ research, stream-aligned teams perform better than feature teams because splitting the craft of software arbitrarily doesn’t work. Software design is too holistic to get one team to decide what it should do and then pass it to another team to decide how to do it.
The holism also means that we can’t separate two things that seem different but are just two sides to the same coin: style and substance. The term software design tends to be used more for the style than for the substance of code. For example, recommendations for good function names, readable code, short functions, and cohesive modules are associated with software design, yet these are mostly about style. The entire refactoring movement aims to change the “structure” (read: style) of code without modifying the behavior. Style is the main topic of traditional software design.
And it’s easy to see why. If you need to talk about software design in the abstract, what else can you say than to recommend short methods and good names? You can’t say what data structure to use because you need to understand the context of the problem you’re trying to solve. But substance is more important than style. It’s the same in literature. Good style (word choice, sentence structure, etc.) can’t make up for bad substance (story, characters, etc.).
If typical software design recommendations are style, then what is the substance? Well, substance is what the software does and how it does it. Software design typically doesn’t address those questions, preferring to talk about coding patterns that make your code more maintainable or more readable. But it’s doomed from the start because you cannot separate the two. Software development is a process of learning how to solve a problem with software over time, which includes how to hire and onboard to your team, what your customers need, and how to evolve the code over time.
The final thing that bugs me about how software design is used is how it’s taught. It’s typically taught using guidelines, patterns, rules-of-thumb, and “principles.” The trouble is, they’re only useful if you’re already good at design. I just didn’t want to be associated with that crowd.
What I want to do is take someone who is new to design and make them good. The only other path available is years of hard-won experience, which is chancy. Programming for years does not guarantee you’ll get good at design. You could practice the same bad design over and over.
But design is also holistic. You can’t give blanket recommendations. The best you can do is equip the reader to be an explorer. You give them questions to ask. You tell them what to look for. You equip them with a vocabulary and important concepts. You help them exercise their judgment. Then you set them loose to make decisions.
Because design is about making decisions. And we make better decisions with more information. So I teach programmers to extract more information. Hopefully they’ll make better decisions.
Rock on!
Eric
https://youtu.be/5IUj1EZwpJY