JavaOne 2010 – Patterns for modularity


This BOF featured Jaroslav Tulach, founder of NetBeans,along with Anton Epple and Zoran Sevarac. It was not really about new technology but about formalizing the approach and terminology for building modular systems. The talk targeted both desktop and server developers. The premise was that OO alone did not deliver on code-reuse hence the need to apply patterns, similar to the GoF patterns, to modules.

The speakers did make it clear that patterns exist within a context, i.e. some patterns might not be applicable to a given language, for example, since that language might already have constructs to provide the solution to the common problem addressed by the pattern; having said that the discussion centered exclusively on Java.

Anton defined his “Five Criteria for Modularity Patterns” even though last  I checked they were six (they were still fixing the slides as we entered the room…):

  1. Maximize re-use
  2. Minimize coupling
  3. Deal with change (i.e. a smaller system deals with change easier than a larger one; JDevelop, for example, can make changes to its core easier than, say, Eclipse)
  4. Ease of maintenance (each release should have a theme, such as release X of NetBeans will support OSGI; this well defined theme should not affect the existing system)
  5. Ease of extensibility (how powerful and simple is your plug-ins architecture)
  6. Save resources (your modules should not affect the start-up time, especially true for desktop systems, and the memory footprint should be kept manageable)

Another set of definitions followed to formalize the Relationships Dependencies Management:

  1. A Relationships Dependencies Management is said to be direct if Module 2 depends directly on Module 1:            M2 -> M1
  2. A Relationships Dependencies Management is said to be indirect if Module 3 depends on Module 2 which depends on Module 1: M3 -> M2 -> M1
  3. A Relationships Dependencies Management is said to be cyclical if Module 2 depends directly on Module 1 and Module 1 depends directly on Module 2 (no need to draw a picture)
  4. Relationships Dependencies can be defined as Incoming (M1 -> M2 <- M3) – they make M2 hard to change, or Outgoing (M1 <- M2 -> M3) – they make M2 easy to change
  5. Finally Relationships Dependencies can be designed using three classical patterns: The Adapter pattern (Adapter Interface between 2 modules to introduce an Indirect dependency; it forwards method calls from M3 to M1), the Mediator pattern (sits in between 2 or more modules, aka the Bridge pattern in NetBeans) and the Facade pattern (provides a front Interface for a set of two or more modules)

The last portion was the more practical one as it provided an overview of the existing tools in the Java space to solve the problem of Reducing Communication Dependencies. The problem of Communication Dependencies can simply be stated as follows: Given an Interface TextFilter, an implementation class UpperCaseTextFilter and  a client Class Editor, how can Editor get an implementation of TextFilter? Ideally it should know nothing about  UpperCaseTextFilter at design time. The ideal run-time solution should provide the following (now we’re getting at the heart of system modularity):

  1. Register a Service
  2. Retrieve a Service
  3. Disable a Service
  4. Replace a Service
  5. Order a Service (as in providing some sort of ranking)
  6. Declarative support for a Service (as in meta data)
  7. Codeless Service (as in configuration)
  8. Availability of required Services

Five solutions were described; I would like to point out that SCA was left out which is a shame because it is a well thought technology and Apache Tuscany is only one of its many implementations.

  1. JDK 1.6 own service loader mechanism; it is declarative (in META-INF/services) and returns an iterable typed collection of services but it is way too simple, it is not dynamic (you can’t react to a situation where the client uninstall a plug-in) , it can be dangerous as it loads all services at start-up and it does not provide factory methods
  2. NetBeans solution: Uses Lookup and XML files. This one is declarative and dynamic, allows for ordering, for lazy loading, has factory methods and codeless extensions
  3. OSGI Service Registry: Services are registered with code using bundleContext.register(), it is dynamic, it has factory methods, it filters services and it is configurable with code, which means that you now have dependencies on the OSGI framework in your code, eager creation can slowdown start-up times and it is not type safe
  4. OSGI Declarative Services (OSGI II if you prefer): It’s better than Service Registry in the sense that it is declarative (XML configs)
  5. Dependency Injection: Spring offers an alternative solution using @Autowired and it is declarative in nature (the wiring is specified in  your beans.xml) and the framework is usually transparent to your code

Jaroslav then discussed the hotly debated issue: Are Singletons evil? And the answer is “it really depends on the context” (recall the statement earlier in this post). In a Dependency Injection solution there are many contexts: The Application Context, the reckless contexts and the Session context. Singletons would then be viewed as bad given all these contexts and the false sense of security that they provide. But at the module level (say a jar) they can be helpful if they are carefully designed:

  • The Singleton must be ready for use: No prior initialization code should be required prior to requesting a Singleton
  • The Singleton must be injectable: We should be able to inject different Singleton implementations at run-time depending on the context (say DEV v/s PROD)
  • Singletons are OK when used with the proper Service Loader/Lookup mechanism

Finally a few thoughts on performance were given: Since modular applications tend to be so large start-up time becomes critical so one should obviously avoid calling in OSGI bundle.start() for each jar because it is inefficient and because often time the jar is a 3rd party library that can’t be trusted. You are better off using a declarative registration method (as in an XML config file – interpret it and cache it); which is why JSR-198 falls short in the performance area. JSR 198 is indeed declarative (XML)  but you need to create a handler for each service, which slows the start-up time.

Again, this session did not break any new grounds but it helped organizing the ideas around modules, what to look for when evaluating different solutions and last but not least how to learn from a large system such as NetBeans that has been continuously evolving for the last 13 years.

5 responses to “JavaOne 2010 – Patterns for modularity”

  1. Hi Roger,

    thanks for visiting our talk. We were not actually fixing the slides, Jarda was just joking :-). I’m impressed that you found out about our six “5 principles”. It’s an internal joke, because Jarda thinks two of them are the same ;-).

    Thanks for this report and enjoy JavaOne

    Toni

  2. Hello Toni, thanks for stopping by my blog, I really enjoyed your talk because I think that you formalized in a straightforward manner a lot of concepts related to modularity. I kind of guessed that Jarda was the joker of the group. You both did great.

  3. Actually Toni wants to use the word “five”, because “five” is said to be cooler number than “six”. I am trying to help him by claiming that one of the six principles is inherently present in the other five, and as such we don’t need to count it.

    Nice summary. Thanks. Btw. here is a link for those who want to read more about my thoughts about singletons,

    • Hello Jaroslav; first off thanks for stopping by and taking the time to comment!
      Yes, the six can become five (five is half of ten, that in itself make it cool) if we merge #3 and #4 (respectively deal with change and ease of maintenance).
      Also I am a fan of your idea of an “injectable singleton”. Don’t know what Tony thinks of this.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: