
Every abstraction is a bet on the future
I've been thinking about this while working on a small developer tool.
Say you have one Python implementation but think you might support other languages someday. It's tempting to start with a generic LanguageFrontend interface.
Or you have one duplicate detector, so you create a DuplicateDetector abstraction in case you eventually add structural or semantic detection.
None of that is necessarily bad design. But I think we often call it "flexibility" without acknowledging that we're making predictions about requirements we don't actually have.
The thing I've started asking myself is:
What variation am I modeling?
If the answer is mostly "well, someday we might..." I'm increasingly inclined to leave it concrete.
That doesn't mean putting everything in main(). The tool I'm building has real boundaries between discovery, parsing/normalization, detection, reporting, etc. Those boundaries exist because the current problem actually has those responsibilities.
I'm just less convinced that hypothetical variation deserves an abstraction before the variation exists.
I wrote up the longer argument here:
https://medium.com/@bobltaylorjr/every-abstraction-is-a-bet-on-the-future-9ce709b428ff
Arid is the project I used as the concrete example:
https://github.com/sponge-b0b/arid
Curious where other people draw the line. How much future change do you design for before you have an actual requirement?