Let's say, I have created a business logic layer service (or a handler in Command/Query pattern) with a method
DoSomething which processes a bunch of entities and stores them in database.
Later on, another developer sees - "oh, this
DoSomething method does almost everything I need, I can call it from my
DoThisSomethingAndMore method." Seems the right thing to do to avoid copy-pasting the code from
DoThisSomethingAndMore. Unit tests pass, everything is OK.
Then a new business requirement comes in to modify
DoSomething operation. So, I change the code of
DoSomething, and thus
DoThisSomethingAndMore becomes broken.
If we have good tests, we can detect it early on. But how to fix the issue? Make
DoThisSomethingAndMore not to call
DoSomething and copy-paste the code instead? Refactor
DoSomething into pieces that can be reused from both
DoThisSomethingAndMore? This might be a noticeable amount of work, involving all the developers who are calling
DoSomething from their code and cascade to even more code which is calling other methods. Also, this might lead to a bunch of public methods (
DoPart2OfSomething ...) on the business layer service class, when these methods should really be internal because they don't actually perform a single atomic business operation but just a part of it.
Is this a common programming issue and should it always be solved by refactoring or does it mean that we should go for full business service and operation decoupling, accepting that it will lead to some code duplication?
Inner voice says - make each developer responsible only for his own code in business methods he created and do not call others' methods when you know that they, most probably, will change their inner implementation. This seems reasonable considering that the project is being developed by a startup company with some not so experienced developers who would benefit from clear "rule of thumb" since the very beginning instead of investigating each method call separately, and also considering that business requirements are changing often during first phases of development.
And then there's another inner voice "hey, don't duplicate the code; code reuse is one of the best practices".
So, while I would like to go with the single responsibility with code duplication approach, I cannot find a reasonable excuse or solid foundation for it. Is there any? It would be great to have a reference to some reputable source (e.g. "The Gang of Four") saying in which cases code duplication is generally acceptable.