DRY principle is about extracting repeatable code into smaller, reuseable units and using them instead.
Big benefit of DRY is less code & requirements grouped in one logical unit of it. In theory following DRY principle should lead to higher maintainability, easier implementation of change requests etc.
Should you try to remove duplicates at all cost?
Of course not. Having code that is very generic leads to logical coupling. It’s often better to stop extending existing code that is similar to cover ‘just this one more case’.
Sometimes it’s better to just duplicate some part of logic.
Write Everything Twice?
This is the opposite pole of DRY. Is violating the DRY always a bad thing?
Sometimes it’s just cheaper to write the similar code for second time (take Distributted Systems for example). Writing too generic code is also not good, as it gets harder and harder to change. Introducing bug to generic method can cause mutliple components to stop working.
The good example when using DRY is going into wrong direction is achieving it with kind of inheritance that feels to be a little bit strange.
What about code changes?
One of the important arguments behind DRY principle is that in case of logic change it happens in one place. So how to solve it when there is a need to duplicate some parts of logic?
Track it by using your source control system. Link requirements/work items to commits and pull requests. In case of change request it’s easy to find where the logic has been used.
So DRY or WET?
It depends on the situation. DRY principle is good until you notice that it’s very hard to change the generic peace of code. It also might lead to tight logical coupling which should be avoided.
Copy & paste of code is not good. It should be avoided.
Writing the similar piece of code, when maintaining generic method gets hard is definetely thing to consider.
Always think if following specific principle is justified. There’s no principle that works in every case.