I tend to build things differently from other people. It’s an annoying fact about myself that I can’t seem to accept. One, what I build tends to be robust, extendable, and, non-idiomatic (I hate idiomatic code). Two, what I build tends to be more complex than it needs to be, right now.
One of the more interesting parts of having these little time-boxed side projects is that it forces you to rethink your approaches to solving problems while planning out two or three steps ahead. These kinds of projects really make the negative of my software design into a positive.
By making software extendable, you add complexity to the design. Legos are just a bunch of blocks, but adding the parts that allow them to “stick together” adds quite a bit of complexity to the initial mold, while allowing more composability later on. I imagine over the decades, these molds went over many iterations to make them stronger and more resilient.
A problem comes when the complexity increases beyond the scope of the original idea. This usually happens when you start at the wrong place. For example, if you were to build a website that allowed people to host a Bingo game, with players playing on their phone: where would you start?
- You can start at making a piece of the software that draws random Bingo numbers
- You can build the user interfaces
- You can build the user management interface (admin)
- You can build the authentication pieces
- You can build the game logic
- Or, you can build the ability to keep track of what players have selected which squares
You can argue that there’s no need to do #3 (just use the db for now) and #4 (things like auth0 work fine), essentially cutting out 1/3 of the work and tabling it as technical debt.
You could start on 5, making some logic that makes it more likely a number is selected that’s on a user’s board so that games are shorter and more fun with less players. That’s kind of hard to do without #1, #2, or, #6.
You probably should start with one of those, but which one?
Starting with #2 will let you know what kind of data structures you need, as well as any api endpoints. It also gives you something to visualize what you’re doing as you go along and let’s the UI drive the data instead of the other way around.
However, there’s something to be said about #1. By starting with the core of the application (picking random numbers), you end up getting it right most of the time. In fact, the rest of the application is mostly just chrome around a pretty random number with a B, I, N, G, or, O in front of it.
Starting at #6 forces you to think about the multiplayer bit first, which will be a hurdle. You could probably get away with something like rethinkdb to stream changes to the application and let the host there might be a winner, or something.
If you start too far outside of the core domain (uh, random numbers in this case), you’ll end up building features that may have no purpose, if you want to get finished in a finite amount of time. By starting with #5, you’d be forced to create interfaces you don’t understand yet. Starting with #1 might get you stuck building unit tests that don’t prove anything but that you’ve tested all the code. Of course #6, you’ll probably get dragged into some fun multiplayer logic that you may or may not need.
So, invariably, I will almost always start with #2. I want to know what it feels like to use the application. Does something in my mind have a bad experience in real life? Does it feel intuitive to me? What kind of data is needed on the screen without it feeling cluttered?
I work backwards from there to discover how to store the data in a way that is displayable and provides actionable data in the future to discover if the app is something that people actually use. I’ll try and think about some features I might create in the future and start tracking that data now, so I’ll have it for historical reference. That might be tracking how long between drawings by recording each individual drawing. That might involve tracking which devices people use to build a native app …
As anyone who’s ever designed something knows, it’s never finished. This is my kryptonite … I’ll literally design and redesign the UI/UX until it’s “perfect” and waste away many, many hours to do so. This is why I stay away from this in my day job and let someone else handle it. I’d never get anything done.
And that’s why these little time-boxed side projects are nice. At some point you have to say “enough is enough” and let it go. It’s a lesson worth learning.