The 1, 2, n pattern
terodox.tech
terodox.tech
"My response is generally the same to all of them, the maintenance for two function is very small compared to a bad abstraction that can grown into a monster very quickly."
That's a little bit of a red flag. Bad abstractions shouldn't lead to monsters. This is more important than when to abstract! Bad abstractions are going to happen no matter what way you create them, but you should always have a design mindset that leads you to being able to back out of them and change your code. Two very simple design concepts (but often have very deep implications) help with that: composability and modularity. They should guide your refactoring a lot, not just that there is duplication, but if you do extract it, where to? and how will it compose with other things ? you do that well, often your abstractions are easier to change. (Do it badly and often you will see an explosion of types to allow composition that often then make your abstractions much harder to change)
// AB-20200405 - Hi future developer (probably me),
// if you're copying and pasting this code, then
// please take an extra five minutes to locate the
// other similar instance of this code snippet in
// the codebase, and refactor both of these into a
// method first. The other snippet will have the
// same comment that precedes this one.
//
// Here's what this overly clever snippet of code
// is doing, so that when you do refactor it into a
// method in 2023, you don't miss an important edge
// case. Ta!Later, since your team is growing, some other dev applies some other fix to the other branch (which was also copy pasted three times by three distinct devs because “rule of three”).
Soon, you have a dozen copies, and they are all wrong/diverged enough to not be clear copy pastes any more.
I’ve seen this happen more often than not, especially when scaling teams. Since the team is scaling, the original dev won’t always review all the code changes.
Which leaves us in a spot where this is always subjective. Sometimes the third duplication is the time to generalize. Sometimes it's the tenth. Sometimes the first.
Thus, every generalization is a guess, at best based on previous experience, unless you already know you're going to repeatedly use it already. So you'll always have some kind (experienced-based) hueristic; you might as well define one explicitly to go by, as a rule of thumb
I think it's easy to say, "If you copied a piece of code three times, please put that in a common place" to a junior engineer as a basic lesson for getting started with refactoring.
- having explicit variable / function names to make global search/replace easier when necessary, but generally just for clarity.
- thinking about file structure early and often
- always using constants to represent any value that is repeated across the system