Hey, what's up, John Sonmez from simpleprogrammer.com.
I got this question from Moritz about when to basically build a smaller or large solution.
We could read the word hack here, when to hack it out or a kluge.
He says, "Thanks for your podcast.
I enjoy listening to them on my commute and resonate with a lot of them.
My question for you, how do you decide when to build a small or minimal solution and when
to build a big one?
I'm developing internally used applications and we often get feature requests that could
be solved with little effort but the solution is very specific to the problem and maybe
hacky and maybe it will come back later to bite us.
Then there are more general solutions that are often more effort but feel more consistent
and maybe solve some related problems too.
But there isn't time to build the big and "proper" solution for each feature request.
How do you decide where to invest your time to make the most impact?
Cheers, Moritz."
This is sort of a tough one.
This is an age old software development question of whether or not you write the hack, you
do the shortcut or you build the big solution.
Also, it sort of reminds me of the whole over engineering type of question that we often
get.
There's not really a definite answer to this.
I hate to say it depends, but it depends on context.
This is something that's really important to understand is that sometimes it's going
to be right to do the solution that is going to just get you through the day.
I'll give you a context where you actually need to go to the production server and make
a hack.
Let's say that you are a startup and you're launching your product and if you do not sell
this product tomorrow you'll be gone and everyone will be fired.
In that case, you don't care about doing the right things.
You don't care about maintain—you just got to get it working now and today because the
site is down.
In that case you just do whatever is required to get that down, right?
That's a possible context, right?
Here's another context.
Let's say the context is that you're working on a medical device that is going to keep
someone's heart beating and you have a bug in it.
You don't want to just patch that real quick and get that working, right?
You want to build a more robust solution and make sure that it's tested well and designed
well and planned out and maybe a lot more going on there, right?
So that's another context.
There's all kinds of context in between that but you've got to think about this.
As far as just—let's say that you have sort of the middle of the road, where you just
have a problem and you're trying to decide how should you solve this problem.
Should you write something that's specific to that problem or you should write something
that's more general?
Well, you want to err on the side of writing something specific to the problem because
as human beings we're really bad at predicting the future.
We don't know what we're going to need.
What we can end up doing is we can end up packing—I mean have you ever done this?
I go on a flight and I pack my backpack here.
I got my backpack, right?
I will pack it with—oh, here it is, these things.
I'll pack 2 of these.
These are like cellphone chargers.
I don't know how many—it's 10,000 milliamps.
I pack 2 of these things and I pack all this stuff that I'm not going to need because I
think well maybe my cellphone will run out of juice.
It never does.
I never actually use any of those things.
I pack all these cables and cords and never use any of them because I'm not good at predicting
what's going to happen.
Then you know what happens?
The one thing I didn't pack that's the crap that I need.
I can't predict that at the time.
I'm not saying not to be prepared but we're bad predictors, so stop trying to predict.
What ends up happening in software development when you over predict is you over engineer
it.
You build this whole big solution, you build this whole framework.
You're like, "Look at these parts.
I can swap this thing out.
If this whole system changes, if we use a different database this will still work.
We can just change this one thing."
None of that stuff ever happens.
Instead, the one little thing you didn't account for comes in and blows up in your face.
My advice in those situations is you fix the problem, you don't hack it, you don't kluge
it.
You do a good job of fixing the problem but you fix it specifically for that problem.
When the problem comes up again or you see a variation of it then you go and you design
something that's going to be a little bit more generalized.
If it comes up again more generalized and you expand out there because you don't build
stuff you don't need until you know you need it.
Another way of looking at this is I talk about like in C# or Java specifically in the language
I say that you don't need an interface until you have more than one implementation.
A lot of people disagree with that but I think that's totally true.
I know that it goes against the whole mocking frameworks and test driven development and
whatnot.
But honestly, from a purely design perspective, unless you have more than one implementation
you don't need an interface.
When you take that to the next level, unless you have multiple implementations that you're
swapping out at runtime you don't need dependency injection, unless you have multiple dependencies
that you're actually swapping the injection of you don't need them.
Now, I know that we do it for test driven development and architecture and stuff, but
when you get down to the bare roots of the design that's the best approach, you don't
over engineer.
We've got to be pragmatic and I understand being pragmatic so I'm not saying that you
have to totally subscribe to that philosophy.
I do when I write code now but you don't have to.
The point is just you've got to balance things out and just try not to—don't think that
you're going to predict things correctly, because you can't.
Err on the side of fixing the thing specifically for the problem because it's going to take
less time, it's going to take less resources and your prediction is wrong anyway.
As you learn and adapt then you generalize out more and then eventually you get a robust
solution.
It's robust based on actual reality, actual field testing rather than robust based on
this imaginary world that you've constructed in your head of what you think is going to
happen.
Great question.
Thanks for sending it.
If you've got a question for me you can email me at john@simpleprogrammer.com.
If you like this channel, subscribe.
Take care.