Frankly speaking there are not so many good approaches to make your application modular
(I think this is the proper way to rephrase your requirements).
Please also note, there were so many discussions, failed attempts and strange designs to simplify development of modular applications, but still we have so many monolithic monsters. I've been supporting enough enterprise systems to be frightened till the end of my life.
Initial design is very important and it is not only about basic concepts like interfaces
. Please don't get me wrong. Interfaces are important, but I would prefer to use a bit different terminology -- contracts
or extension points
Let's imagine you've defined extension points
properly. What will you do next? I'd say eventually you'll implement some kind of plugin framework
. (You can spend an hour to play with JSPF and see how it simplifies development of modular applications and encourages loose coupling).
Bad news, this solution might be a bit dangerous for any production system. Mainly because complex class loading strategy (introduced by this approach) might cause memory leaks. So you'll find yourself analyzing memory dumps quite soon. Class-loaders and all related stuff became a bit complex :)
Anyway, let's assume you've solved all issues with class loading, but what about plugins/modules life-cycle? In any loosely coupled system you'll need to to strictly define how modules will interact. Plugin framework will not entirely solve this problem.
Eventually you'll come up with modules life-cycle
in order to define all important aspects. For example:
My suggestion is to avoid reinventing the wheel. OSGi might be a good solution for you. Please also note OSGi is good, mature and provides a lot stuff out of the box, but it is also somewhat complex:
So you'd definitely need some time to investigate it a bit deeply. Please also check the following : What benefits does OSGi's component system provide you?
Another suggestion is to check any existing big software product known to be good and modular (Jenkins, for example).
Update
Ok, taking into the account the discussion below I would suggest the following:
- Reed or looks through several relevant books Real World Java EE Patterns Rethinking Best Practices, Real World Java EE Night Hacks Dissecting the Business Tier
- Look through EE patterns
- Consider using of ServiceLocator
- Consider using Injection over ServiceLocator
- Decide whether or not you need DAO (some help)
- Do not forget to review Java EE 7 Tutorial
- Looks through all patterns once again and create small cheat-sheet in order to refresh your mind from time to time, something like the following - example
- Design for the future
- Finally, create several PoCs in order to prove your approach is good enough.
Conclusion
Sorry for the long answer, but I have to make sure there is a clear and logical point behind it. Your initial intention is 100% correct and good. It is really better to define interfaces/contracts and hide all complexity behind them. This is exactly what OOP is about.
Anyway, the most important task is not to provide good design, but preserve it over time. My suggestion is to enforce good design by using loosely-coupled approach from the same beginning. Service Locator patter is what you actually need.
It will act as a some kind of barrier to save your project and minimize spaghetti-like code. If you identify some problematic module - ok, no problem, it will be properly isolated and easy to replace.
If you have enough confidence skip Service Locator
and go for Dependency Injection
. Additional reading: Fowler on Dependency Injection vs Service Locator