Damn, it’s tempting. I believe we all have done it more than once - we did something we were proud of that much, that we wanted to re-use it at the next opportunity. It really makes sense, because no-one wants to re-invent the wheel on every project, but it’s a matter of scale: it’s quite easy to re-use single classes, but it’s much harder to re-utilize bigger components, not mentioning whole frameworks or even complete solutions.
Just to make sure we’re on the same page - my considerations are supposed to apply to two major scenarios:
- building a framework / re-usable library from scratch
- trying to package something that’s already created -> for now fit for this one particular case it was used for.
What are the conditions to be met? What do you have to remember about to make your solution re-usable? Actually as it’s hard in practice, it’s still quite easy to describe in theory:
- Pretty much no IT solution exists in void - everything integrates and it’s the information exchange between services and applications that multiplies the value of application / service itself. To simplify things: your component can integrate in two ways: horizontally and vertically.
- Horizontal integration is what happens when your component is a complete new "spike": it’s a new application / service that contains (and “goes through”) all the necessary layers (from the top to the bottom) and it integrates with peer services / applications using designated (limited) endpoints. Such an integration approach helps you with minimizing the junction points. And the less of them, the less painful it will be to integrate.
- Vertical integration is when you’re introducing a new layer - on the top, in the bottom or even in the middle of existing solution. Every functional “spike” for every bloody business function requires point integration of your layer with the layers of existing applications / services. This is much, much more cumbersome and in general you should try to avoid that as much as possible.
- Why is this “vertical integration” so painful (and as a result - rare): because it works only if your introduced layer is business domain agnostic or has a one fixed business domain that’s common on the market. In first case - you’re app is generic enough that it will cover anything (best example: CMS) and in the second case - everyone on the market shares the same business model, products, etc., so there’s no need for big customization or adapting to complex legacy apps (best example: typical internet e-commerce).
- To keep the long story short - “vertical integration” works only when there’s no (or very limited) domain knowledge mapping (confused about that? check: http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software-ebook/dp/B00794TAUG/ref=sr_1_1?s=digital-text&ie=UTF8&qid=1384808061&sr=1-1&keywords=domain+driven+design) needed - that usually happens when there are very many players in your customer market, so they don’t try to be very innovative, but they compete with mere marketing, QoS and pricing.
That’s why great UIs, great database DDLs, great business validation rule sets are not re-sellable and you’ll struggle to re-use them in future. The only things that make sense to be re-packaged are either:
- completely business-domain free (communication library, connection pool component, logging policy) or
- in simple words: can be published as a sepate service with a very limited access contract