Monday, March 6, 2006

POJOs

Sometimes a not too familiar word suddenly pops up in totally different places. The first one or two times you ignore it, but then you start to wonder. POJO, which stands for Plain Old Java Object, is such a word for me. The concept is used to contrast between Java objects that can only exist within a larger framework and objects that only need the standard VM as their environment. For example, J2EE Java Beans can only run in a J2EE Framework because their implementations are closely intertwined with the framework’s classes and interfaces. The concept POJO was coined because of a very fundamental problem in the object oriented paradigm: coupling.

Objects entered my life more than 20 year. I had been trying to use Structured Programming techniques (Yourdon, DeMarco, Jackson, etc) in the context of embedded and distributed system software, but I was not very successful:. It just felt plain wrong. I tried many languages Assembly, Prolog, C, Plm, Pascal, Lisp but none felt right until Smalltalk (Digitalk V86) hit me. Using objects felt so right; I developed my own object oriented derivative of the C language: CO2. At that time, I remembered telling people how objects would change the software world. One of my key selling points to management was that one day we could create complex systems by just picking some objects. A rather naïve and overly optimistic view, my only excuse is that I was still pretty young.

The key reason that we cannot easily compose systems from objects can be described with one word: coupling. Objects almost got it right. They gave us encapsulation and polymorphism but we totally forgot one of the key lessons that Structured Programming taught us: coupling. Object oriented languages lack support to decrease effect of dependencies. For example, when you create a class you have to specify the exact class name, creating a very hard coupling to the implementation of that class, worse, everything that class is coupled to ad nauseam. Over the years, our community has found many solutions around this type of coupling. A key example is the factory pattern, which has the bad side effect of making the code harder to read. The causes of coupling are usually subtle but its effects are terrible. We all know the hopeless feeling that small functional changes turn into major rewrites, or when you download an interesting looking library that turns out to depend on 76 other libraries.

So what is the relation to OSGi specifications? The OSGi Service Platform was designed to address the problem of decoupling. OSGi services are POJOs, you can use any object you like for a service. This was not without opposition, some companies wanted a “Service” marker interface, but we won in the end. The whole purpose of import- and export packages is to minimize the dependencies, and therefore coupling, between bundles. The whole purpose of the service registry is to break the coupling between bundles that provide the functionality and the bundles that use the functionality.

However, also the OSGi Service Platform does not escape of being a container and thus creating unwanted dependencies. We therefore have always advised to separate OSGi code from domain specific code and minimize coupling inside your bundles. The golden rule: if a bundle can exist without knowing a fact, make sure it does not depend on that fact (that is one of the reasons why Require-Bundle is bad). In the case that couplings are necessary, concentrate them. Strive to have as few places as possible where you connect your domain objects to other subsystems. This is exactly the purpose of the popular core of the Spring Java 2 EE Framework. It is also known as Inversion of Control (IoC) or Dependency Injection (DI) principle. The Spring framework uses XML files to configure any number of Java subsystems to work together.

My favorite solution for the coupling problem since 1985 has been scripting languages. Scripting languages are perfectly suitable to connect different subsystems and to provide the always necessary glue code. A simple script language can be used both by the developer as well as the deployer to configure a system. My first attempt with a script language was EGO, a terrible forth like language just because it was easy to implement. Today there are many off the shelf solutions, a good example is the Beanshell. Beanshell is a dream for Java based solutions because it is tiny, supports the Java syntax and will integrate with any java environment seamlessly.

However, what tool you use to minimize and concentrate your dependencies is not so relevant. Most important is to reduce and concentrate coupling in large complex systems so that your users get the flexibility they need.

Peter Kriens
OSGi Evangelist

No comments:

Post a Comment