A couple of weeks ago I was talking about the Reuse/Release Principle, which states that the unit of reuse is also the unit of release - whatever you want others to reuse, you need to release with a predictable schedule. The rule doesn’t tell much about the code itself, different languages and frameworks will require different approaches to achieving that. On one hand you want to package all the classes that are meant to be reused, on the other hand you don’t want the consumers hurt themselves with lower levels of abstractions or depend on something that is likely to change in the future.
Over the development of several projects I figured that the most convenient way to structure you code is using Google Guice. It is a Dependency Inversion container, that’s way easier to pick up than the more popular Spring Framework. Unfortunately, since it’s so easy to pick up, many developers do not try to learn more about Guice. This leads to medium-sized projects with a single module, with ridiculous number of dependencies defined, and with very few reusable components. One thing that helps to keep you project easier to comprehend and maintain reusable modules is to use private modules.
The default way to create modules in Guice is to extend from
AbstractModule class, and bind everything in
configure() method, like this:
Private modules are very similar in usage, which makes the transition extremely easy. The only difference in their API is the
expose(Class<?> clazz) method and the
@Exposed annotation. You can use them to explicitly allow injector to bind the given implementation outside of the current module.
Foo classes, which means that only these two injections will be possible in the injector. If you try to get other objects bound in the module, Guice will refuse to get you the object like this:
As you can see, private modules are easy to use in terms of the changes in your code. They are not much more complicated than regular modules, but give you much better encapsulation of classes of your modules. Applying the private modules is a whole different story, and I intend to do a separate post on that.comments powered by Disqus