It's only some aspects of 'code quality', which do have a cost (immediate and/or upkeep, e.g., tests) which even incur any dilemma.
It's only some aspects of 'code quality', which do have a cost (immediate and/or upkeep, e.g., tests) which even incur any dilemma.
There are many people who don't write that one line of code that throws an immediate exception with a proper error message (and instead just return null or something).
I also see every few months objects and classes with code copied (as in ctrl-c ctrl-v) instead of generalized.
To them, this is getting things done (vs spending time writing descriptive exception strings or isolating the repetitive part in a separate function).
So, your point of view is of course correct, but your definition of "getting things done" takes the next few weeks already in account which, frankly, I don't see that often.
What is easier to generalise -
1. the point where you realise you need to do basically the same thing in another location with a few small changes
2. the point where you have a few cases of basically the same thing with their own small differences in context?
Counterintuitively i think it's 2. It's the "small differences in context" which cause the issue. Once you see a few examples of how the code will be used it's often much simpler to generalise. You don't need to guess any of the future use cases, you have a bunch of examples to work with and you can be far more confident in your improvement.The kicker is that 2 is much cheaper at all steps.
I think the biggest problem with this idea is setting a time limit to allow these duplications to grow - if you allow for it indefinitely, you'll end up with duplicated code building on top of duplicated code. In that scenario, the refactoring becomes harder not easier.