Live data from Hacker News

Prefer duplication over the wrong abstraction (2016)

sandimetz.com

271–280 of 375 posts

Re: Prefer duplication over the wrong abstraction (2016)

#271

Earlier quoted context omitted.

The issue with not having a single source of truth is not the fact that you have to update code in 2-3 places, it’s that you have to know to update code in 2-3 places. Accidental divergence is the problem, not intentional.

This assumes the bug exists in both places which might not be true at all even if they both are dependent on the same duplicated code. If you only spot the bug in path A and not path B, why fix the bug for B?

Why bother having to reason out if path B is or is not buggy? Instead of potentially getting that analysis wrong, DRY, fix it in the one place, be sure that it's fixed for that case, and move onto the next bug.

Re: Prefer duplication over the wrong abstraction (2016)

#272
post #257

Earlier quoted context omitted.

> when we update one pattern we wonder about the others places in code with the same pattern. Avoiding duplication doesn’t solve that It can, that's all about how aggressively you factor and structure your code, eg. combinators make it easy to reuse code in different application patterns without rewriting.

In which language do you use combinators for that ? Even in that case the refactor can introduce mental overhead when having too many different variable / properties names

Any language that I can write a combinator in. It's quite easy in C, for example.

Re: Prefer duplication over the wrong abstraction (2016)

#273
I like to think most seniors know to not blindly follow DRY. However, I can tell many of us are uncomfortable with the idea of needing to maintain multiple duplicated sources of code.

To help with that, I think the simple model of two callers depending on a common code needs to be scrutinized. If the common code needs to change because only one of the caller needs it, then it doesn’t belong in the common.

The wrong goal for DRY is attempting to do it with encapsulation. Encapsulation shifts the refactoring work from the caller to the common code. However this is not what you want because there’s a lot more consequence in updating the common code than the caller.

You can avoid encapsulation and still be DRY by having multiple thin abstractions that the caller needs to be aware about is better. In OOP you are taught SRP and IoC for this. In procedural programming, this just comes naturally as code calling series of helper functions.

Re: Prefer duplication over the wrong abstraction (2016)

#274
post #164

Earlier quoted context omitted.

> I believe that "single source of truth" is a principle that should always be followed Fundamentally, the article addresses cases where it's not clear yet how many sources of truth there will be. Are the two spots in the code using the same algorithm, or slightly different versions? More importantly, will they change for the same sorts of reasons? The title adage (correctly, imo) argues that making two different thi…

The issue with not having a single source of truth is not the fact that you have to update code in 2-3 places, it’s that you have to know to update code in 2-3 places. Accidental divergence is the problem, not intentional.

No, the issue is when there are not two or three places, it's when there's hundreds or even thousands of different places. Two or three is annoying, but not a big deal. However, as you get into the hundreds and thousands, it becomes a real problem. In real world code, this is an all too common case.

Re: Prefer duplication over the wrong abstraction (2016)

#275
I always liked the advice "Abstract for replacement. Not for reuse."

If you have code that is reusable, you'll want it to have a nice interface. But, you don't need an abstraction on top of a nice interface. Just use it.

For abstraction, what you need to focus on is "What is most likely to change in the future?" You want to put in abstractions that will make those changes low-cost.

Ex: At work there was a small debate about which C++ JSON parser to use with no stand-out winner for our framework's needs. So, we picked one and I put a thin layer over it for everyone to use. We have since then swapped out the parser and swapped it back over the years of a hundred devs using it in our framework and no one noticed the swaps.

Re: Prefer duplication over the wrong abstraction (2016)

#276

Earlier quoted context omitted.

The issue with not having a single source of truth is not the fact that you have to update code in 2-3 places, it’s that you have to know to update code in 2-3 places. Accidental divergence is the problem, not intentional.

This assumes the bug exists in both places which might not be true at all even if they both are dependent on the same duplicated code. If you only spot the bug in path A and not path B, why fix the bug for B?

You still need to know to assess B to make sure that it is not affected, and verify that it is not adversely affected if it interacts with the output of A after you have changed it.

Re: Prefer duplication over the wrong abstraction (2016)

#277
To me it’s distracting to think about duplicating vs creating an abstraction, because the answer is always “it depends”, which is not really an answer.

To me, the question is: can you look at this abstraction and understand why it exists, without knowing who’s calling it? If so, it’s probably fine.

If an abstraction only makes sense because of the particular weird details of these 3 callers that have to pass mutually exclusive arguments to it to get their desired behavior, it’s probably wrong. An abstraction needs “a place to live” in your architecture. It needs to be self-evident in justifying its existence.

If you find yourself repeating code, but de-duping it would create these sort of weird non-self-justifying abstractions, your architecture is probably a bad fit for the problem you’re trying to solve. Maybe that’s because the problem changed since the software started (which is a bit of a pickle: do you re-architect, or do you continue writing weird inscrutable code?) or maybe it’s because you just picked the wrong abstraction in the first place. But you should recognize it: duplicating vs wrong-abstraction is about choosing the lesser evil. If the abstraction was a natural fit for the problem, you wouldn’t need to answer this question in the first place.

Re: Prefer duplication over the wrong abstraction (2016)

#278
post #164

Earlier quoted context omitted.

> I believe that "single source of truth" is a principle that should always be followed Fundamentally, the article addresses cases where it's not clear yet how many sources of truth there will be. Are the two spots in the code using the same algorithm, or slightly different versions? More importantly, will they change for the same sorts of reasons? The title adage (correctly, imo) argues that making two different thi…

The issue with not having a single source of truth is not the fact that you have to update code in 2-3 places, it’s that you have to know to update code in 2-3 places. Accidental divergence is the problem, not intentional.

Sometimes it is genuinely easier to duplicate when that happens - e.g. if three teams maintain an enum with 4 values and there is no existing mechanism for sharing code between the projects.

Re: Prefer duplication over the wrong abstraction (2016)

#279
post #164

Earlier quoted context omitted.

> I believe that "single source of truth" is a principle that should always be followed Fundamentally, the article addresses cases where it's not clear yet how many sources of truth there will be. Are the two spots in the code using the same algorithm, or slightly different versions? More importantly, will they change for the same sorts of reasons? The title adage (correctly, imo) argues that making two different thi…

The issue with not having a single source of truth is not the fact that you have to update code in 2-3 places, it’s that you have to know to update code in 2-3 places. Accidental divergence is the problem, not intentional.

This sometimes falls under “be cautious with what you output, but generous (i.e. flexible) or very careful (full validation, good logging, making sure you fail safe upon receiving any/all unexpected input) with what you accept”. This usually makes duplication the worst choice because you could have to do a lot more thinking (and maybe coding) down the line to make sure all is well everywhere, and you need to document (or at least comment) so that others know these requirements when they make future changes, but it can be a valid approach especially in related but loosely coupled parts.

Re: Prefer duplication over the wrong abstraction (2016)

#280

Earlier quoted context omitted.

Of course, in theory this is true. In practice people tend to avoid ANY duplication no matter what. Especially junior developers, as if duplication would be the root of all evil.

Definitely the hallmark of junior. Obsession with code deduplication as the highest pri when it’s quite low among others.

Well I have seen a lot of „expert beginners” who have years of experience on paper but fight tiny duplications like their life depends on it.

„How Software Groups Rot: Legacy of the Expert Beginner”.

https://daedtech.com/how-software-groups-rot-legacy-of-the-e...

Post reply on HN