I remember when code reuse first became a buzzword, back in the day. "Code duplication is bad!" they cried. "A maintenance burden! Error prone! Write code once, reuse, cut costs, and everybody wins!"
But imagine you embraced this mantra. You have a number of client systems reusing your very useful code, some in your team, some not in your team, and perhaps some you don't even know about… You want to make a change. How do you not break client code?
You turn your very useful code into a library or perhaps even a service (*waves dusty SOA banner), with well-defined interface contracts, usage guides and a versioning policy. And you start to keep track of your clients. And of course, you want to write tests. But since clients will reuse your code in surprising ways, you write more tests, for scenarios you haven't imagined (with your crystal ball.)
And all is good for a while.
Then client N+1 comes along and wants to change the common interface for legitimate reasons – change is to be expected and even embraced, right? Luckily we used XML or JSON (or both), so we have some extensibility. But no, the client is not satisfied. The change is more significant. The business is moving. We are agile. We need to change the interface fundamentally.
So we do, and we version it. We notify all our clients that there is a new version, and that version 1 is deprecated. They have 6 months to upgrade.
But some are too busy to do that, and we end up with two versions.
Or perhaps we decided the client's requirement is unique, so we write a special purpose adapter. We end up with two interfaces. Somewhere, a developer's soul dies.
Unless very carefully managed, shared code quickly becomes code nobody wants to touch. This is a very bad smell. Changes will be made around the edges, and a monster will be created. Nobody will want to own this code.
The very reuse of the code ironically becomes its own demise.