What is software design?

Does the term "design" make sense in the context of code? I discuss Sandi Metz's definition from her book Practical Object Oriented Design in Ruby.

Transcript

Eric Normand: What is software design? Hi, my name is Eric Normand. These are my thoughts on functional programming.

I've always had this trouble with the term software design. It's used a lot in the object-oriented world, and I've never quite understood what it's supposed to mean. It kind of feels right sometimes to think of what you do when you're moving code around, and choosing where methods go. It feels like design. In the end, it doesn't seem to warrant a new term besides just coding.

It's used a lot. You see it in design patterns. You see it in the book "Practical Object-Oriented Design in Ruby." Design is just brought up so much in the object-oriented world.

For instance, design patterns, the patterns movement in architecture started by Christopher Alexander, they didn't call them design patterns, they didn't even call them architecture patterns, they were just called patterns.

When did that term design come in? Because to me, when you look at the patterns themselves, you open the book and you read them, they are coding patterns, they're behavioral templates. They're about, here's what your objects should be doing when they're playing these roles together. If you'd follow something similar to this, we call it visitor pattern.

Where is the design in that? What does that have to do with design? It seems more like a coding pattern. Maybe a behavior pattern, I don't know. Where does the design part come in?

Sandi Metz in her book Practical Object-Oriented Design in Ruby, I'd never read it before, but I started reading it a couple weeks. The first chapter is "Why Design?" [laughs] I had always just put off this book thinking I would read it later.

She does have a chapter exactly addressing the question. It cuts through a lot of my skepticism about the term. It gives me a way to think about it that I hadn't thought about before.

Whenever I had heard about refactoring, about design patterns, it all seemed very much code-oriented. Design patterns, to me, is like your language doesn't let you do this particular thing that easily, so you need a template to make it easy.

Like, you have a for-loop, maybe your language doesn't have a foreach loop so you have to have this pattern for initializing an index variable starting at zero then, checking the length of the list and you do all this stuff.

It's a for-loop, but you have to make it look a certain way to be able to iterate through a list because you don't have foreach.

I always thought of design patterns like that. "Oh, you don't have a way to walk over a data structure? We'll make a visitor pattern."

What Sandi Metz's argument is what her definition of design is, it's making choices in the code so that you can maintain a good development speed.

https://twitter.com/ericnormand/status/1062737121071501312

You make some choices, and it later slows you down because you have to make a lot more changes to your code to make a small change in the software. Or things are in the wrong place, and things are badly named, and so you can't figure out what's going on. All of those things, she's calling design.

It's one aspect because it's not about how it works. It's not about what the software does. It's about how you choose to organize it, where the methods go, what the interactions between the objects are and how your dependencies work.

She talks a lot about dependencies. All of that is not really about what it does. It's about how it does it internally in the code.

It's really a developmental concern. Design falls under the developmental stuff. Meaning there's functional, what are the features you have? There's operational, which is like, is it scalable? What platforms does it run on? Is it cost effective? Those kinds of things.

Then there's developmental, which is, how easy is it to add new features? Are your developers stressed all the time working in this code? She's putting it under that, the developmental. I always looked at it like it's a syntactic concern. It's all about code and not about the abstraction.

What she's saying is that you can't really separate out the abstraction from its representation. You might think that the size of the method is purely syntactic because it's an easy transformation to split it up into two.

What she's saying is, over time, if you're doing good design, you will approach a better model, a model that works in the present, and also is easy to use in the future, keeps your development speed high.

This gives me a lot of hope because I've always seen them as in conflict. The idea of having purely syntactic changes make any kind of progress on your domain model.

People who talk about object-oriented design, they also are the same people who talk about clean code. The problem with cleaning up your code, I mean it's great to do, and I've talked about this before, but moving stuff around is not going to fundamentally change the abstractions in your code. The abstractions are the important part.

Sandi Metz has this optimistic view I think. She's got a whole book on it, so it's more than just a view. It's well developed. It probably has a lot of good evidence for it.

The view is that they go hand in hand. That you can make refactorings that incrementally improve your model, meaning make it closer and closer to the actual model that you're trying to discover, which is great. That's like the Holy Grail is to be able to write a quick and dirty version.

You know there's problems with it, you know that you haven't really captured the model yet, that well. Over time, through actual development pressure, like, wow, this is taking a long time to make this feature change, maybe we need to make some better design decisions in our code.

Those design decisions by just focusing on getting the developers happier, faster, easier, simpler time, and all of those changes will actually align you with the model.

I don't know if it's true. It's like asking if you start with a naïve brute force approach to finding the shortest path, and you just make all these — I don't know what you'd call them — just changes, just organizational changes, code changes will you eventually wind up with Dijkstra's algorithm, just by refactoring it?

I don't know. It's a very optimistic view, and it's also a pragmatic view because that is kind of what we have. We have companies that want to get software out the door fast. They don't care so much about how clean the code is.

From the business perspective, it is a developmental concern that's what I'm saying. They just care that it's not too expensive and that it does what it needs to do. There's all this pressure to get it faster.

That pressure of getting it out faster could require the developers to go back and do these design decisions. Make design changes to make things faster. Maybe you could develop a good model that way. That's like I guess the dream of agile. I'm skeptical, but I want to keep exploring this.

Let me know what you think. My name is Eric Normand. You can reach me on Twitter @EricNormand also on email eric@lispcast.com. See you later. Bye.