You ARE Allowed To Think Before You Type
I’m a big proponent of agile (lower case a) development practices and Test Driven Development (TDD) in particular. In my experience it conforms to the reality of changing understanding and moving requirements much better than BDUF. Like many things, there’s a spectrum ranging from BDUF to “Start typing and see what you come up with”. And in some specific scenarios, either one of those might be the right choice. But for the vast majority of us, in the vast majority of cases, the best choice is somewhere in the middle.
Unfortunately, the best sound bites are at the extremes. Things are so clear there. There’s no nuance or reality to get in your way. You end up with everything from “The product and architecture teams have specified every function/message/API call, so just go implement this skeleton.” to “Build me a website that tracks all of my activity. I’ll be back on Friday for a demo.” It’s easy to look at either of those and say that there’s no way that they’ll work. And they don’t.
So here’s another sound bite to get you thinking.
Continuous design is an interesting thing; it can be continuously coming up with a design (with some reversals) or it could be continuously testing pre-thought design ideas by implementing them and assessing.
Both are valid. You are allowed to think before typing.
I say nay, not just allowed. I would say you are required to think before you type.
It’s the messy middle, the land of “It Depends” where software engineering lives. The place where we need to understand not just what we’re doing, but why. To choose what to do for a valid reason, and just as importantly, choose what not to do. The way to do that is to think. Think about what your goals are. Think about what your constraints are. Think about the path, not just from 0 to 1, but from 1 to 10 as well.’
I’ve talked about only designing until you start speculating. But it goes even deeper than that. Until you’re done, you’re speculating. Even then, you might be wrong. You can (and should) design for the known knowns. You should have a approach for known unknows. But by definition, you don’t know the unknown unknowns, so you can’t design for them.
You might not be able to design for them, but you can keep from painting yourself into a corner. Especially if you’re using TDD to guide you, you have to think first. You can’t write the initial list of failing tests, let along the tests themselves, unless you have some idea of how things are going to work. How the events and data, the information is going to flow. How it’s going to be transformed.
To break things down into domains, you have to have some understanding of the situation. And not just the happiest path. You have to think about the edges. The failure cases. The places and ways things can go wrong. It’s only after you’ve thought about those things that you can create your domains and use tests to guide your development.
And all of that is speculation. You don’t know until you’ve tried.
So think. Then type. Then think some more. Then learn. Then design. And know that even those sound like separate things, they’re all happening somewhat concurrently. And that’s OK.