My recommendation is to go for replaceability instead of re-use. Replaceability leads in the right direction: you think about how to separate responsibilities in order to make them replaceable, which gives you loose coupling. You think about separating clients from the implementation in order to keep it replaceable, which gives you client-driven APIs.
And, if you might realize after a while, that a component tends to be used several times, you go the extra mile to make it really re-usable in terms of additional testing, documentation and hardening. Therefore I would like to add one more line to the learnings: strive for replaceability, not re-use. It will lead you the right way.
Premature abstraction really is the worst type of evil in engineering, as well as in any other design discipline.via blog.codecentric.de