4 ms·
We're talking about the same thing. Perhaps I was just speaking more broadly. > don't build abstractions because you might need them later ... [snip] ... This
by 0xFACEFEED 4y ago
We're talking about the same thing. Perhaps I was just speaking more broadly.
> don't build abstractions because you might need them later ... [snip] ... This is because you'll likely be wrong about your assumptions about which abstractions you'll need, and ripping those abstractions out is going to be more expensive than just modifying simple code to do new things.
At worst, this is dangerously wrong. At best, it creates a straw man that people can use as a tool to shut down innovative ideas.
What you're describing is a very narrow/specific strategy that one might apply at a company. An example would be when a company is doing well financially and you don't need to risk amassing technical debt for some experimental side projects. Just build the MVPs, see what sticks, and only then decide whether or not to commit serious architecture to the problem.
If you're designing new systems that need to scale quickly (just one example) then you NEED to place bets on abstractions. A well designed abstraction could save you weeks (even months!) of time when you most need it.
I've seen what happens when a successful product is comprised of stitched together MVPs. It's too late for a rewrite and all of that "simple code" is creating a death-by-a-thousand-cuts nightmare.
Bad abstractions will always be bad. Bad system design will always be bad.
It's an aged/jaded mentality to claim that we should just stop designing systems ahead of time because we suck at it. Not everyone does. Some people are actually very good at it. It's possible to design an abstraction defensively so that it isn't more expensive to rip it out later.
Want a concrete example? Payment systems. If I'm writing a billing system then you bet I'm going to abstract away the interface with the payment processor. I would do this irrespective of our plans to expand to other payment processors. It shouldn't even be a debate because there's a way to build that abstraction with minimal overhead to the team.
On the other hand I would never blindly introduce an ORM into a system that doesn't need it. That would be a bad abstraction.
- vinyl7 4y ago> A well designed abstraction could save you weeks (even months!) of time when you most need it. Or it could cost you a lot if your guesses are wrong. It goes both ways. It's better to write code the simplest way to do what it needs to do now, but in a way that can be pulled out into a new system/abstraction later in an easy way. This is generally done by writing data-oriented code (focus on what the data is and how it needs to be transformed) rather than object-oriented code.
- 0xFACEFEED 4y agoThe problem is that everyone's definition of "simple" and "in a way that can be pulled out" is different. And in any case... just about everything you write is an abstraction to some degree; the question is, where is the line? It's not hard to write abstractions defensively. For example you can limit access to your abstraction to a small and strict interface. What you do behind that interface can be the wild west; as long as you can just lop it off later. > It goes both ways. It does, but the word "simple" is often used in a deceptive way. A cacophony of "simple" systems are actually very complex in aggregate. There are many cases (eg: something is your core business) where you'd want to put a lot of thought into an abstraction ahead of time. You'd then want to validate that abstraction's effectiveness and adjust as you go.
- danielovichdk 4y agoI totally agree on validating ideas but that's IMO not looking in to the future. It's trying to find a fit for something you believe is a good idea. There is a big difference in testing whether something is needed in the near future or you simply stick to your guns and blindly dictate how you believe the future will look like. Your ORM example is good and exactly what i am referring to. Too much abstraction/gold plating due to unknown requirements in the future is perhaps a better way to put what is a problem. And you also say that "If you're designing new systems that need to scale quickly..." - if you know that it will scale quickly then of course you know you need to do certain implementations to cater that. But if you do not know whether it will scale quickly then you are looking into an unknown future - and then you should step back on abstractions.
- 0xFACEFEED 4y ago> There is a big difference in testing whether something is needed in the near future or you simply stick to your guns and blindly dictate how you believe the future will look like. There are innumerable successful examples of committing blindly toward a future few people believe in. These are often cases where the objective evidence of success is very limited. If the objective evidence existed then "everyone would be doing it". This is the crux of my disagreement. Of course we'll both agree that applying the wrong/stupid abstraction is wrong. But that's not what I'm discussing. I'm talking about this quote specifically: > Don't look into the future. Because you cannot. And you are both naive and arrogant if you believe you can. Deal with what is known now! Perhaps you need to reframe this point to make it more clear? > Don't look into the future. Because you cannot. This is silly for all the aforementioned reasons. Especially when innovating in tech! > And you are both naive and arrogant if you believe you can. Calling someone arrogant for attempting to predict the future in technology. Come on, man. > Deal with what is known now! What is known now is what everyone else knows now. Unless you're dealing with the _extremely_ rare case where you have access to information no one else does, innovation requires one to commit to the unknown.
- wtetzner 4y agoI'm certainly not claiming you should never design anything up front. And I'm also not saying you should never design abstractions. As with everything, the devil is in the details. What I am trying to get at is that I've seen many times where a complex abstraction was introduced, and then it was only ever used for a single implementation of something. I've also seen many times where an abstraction was introduced, to make plugging in other backends easy, but then when it came time to plugin the second backend, the API was sufficiently different that it couldn't be shoehorned into the abstraction without a ton of extra work. Sometimes you know enough about the problem space up front to avoid those problems, but often you don't. I often the better approach is to keep things as small as possible until you need more. E.g., for payment processors, just ensuring that the surface area between payment processing and the rest of the code is as small as possible is likely sufficient. Maybe that's done through a simple abstraction, maybe not. But the point is, if you only have one payment processor now, the cost of implementing the abstraction doesn't change between now and when you actually need it (unless, of course, you chose a bad design, which we're obviously trying to avoid with either approach). So you can pay the cost of adding the abstraction when you actually need it, and can spend your time on something else that you need now. I guess maybe bringing up the word "abstraction" was the wrong way to word it. In my experience, it's usually better to keep the code as small as possible early on, regardless of whether or not its using abstractions, because making it do what you want later is much easier when there is less code (in terms of constructs/concepts, not necessarily lines/characters). Also, try to keep things as orthogonal as possible. I think the reason I mentioned abstractions is that complex abstractions trying to predict all of the possible future extensions to the system is where I most often see design go wrong.
- 0xFACEFEED 4y agoI think you and I are generally on the same page, but we're reading this statement by the root commenter very differently: > Don't look into the future. Because you cannot. And you are both naive and arrogant if you believe you can. Deal with what is known now! See my additional response to him elsewhere in the thread where I tried to break it down sentence by sentence. Everything you're saying is on point for good system design IMO. What he was saying was totally different and IMO is a "dangerous" way of thinking when innovation is important.