Tuesday, August 12, 2008

Why do J2EE applications need Spring? The core of Spring explained...

What is the core of spring? The real purpose of why it came to being and is so popular. Most Java/J2EE application code tend to become monolithic (read a single large code base) over time - i.e. the application code slowly diminishes to maintain its modularized form with the result that the dependency relation graph between the classes/objects gets really ugly with no standard form. Secondly the applications also need a lot of infrastructure services - like Life Cycle Management of their objects and important resources like database connections etc, Database Access, Transaction Management and many more.Even simple Java applications would at least require efficient management of their objects and its dependencies. Although standard J2EE API and the application servers implementing those API claim to provide all the infrastructure services, applications still tend to become monolithic and unwieldy. So we need simplicity and freedom in the following areas:

1. Externally configurable objects - It is always better to be able to configure objects externally, i.e. set their values externally without recompilation of Java code or involving developers. The whole beauty of the general concept of configuration is that any change made to it does not require a rebuild or redeployment.

2. Simple POJO based programming - If we are just able to concentrate on programming business logic and not spend time of writing infrastructural code, we speed up the time to deliver the project by at least 40%. Simplicity and speed usually are natural if we adopt the POJO-based programming model. But for a real application, we have to add code to the POJOs to access databases, coordinate transactions, locate services provided by the container/environment, and so on. We would like these tasks to be performed declaratively via configuration (and via annotations), without disturbing the POJO code.

3. Dependency Resolution - Java interfaces do provide a clear separation between a contract and implementation. Ideally we would want the client class to be dependent only on the interface class. But we still have to look up the implementation class that we want to use. If it is hard-coded in Java code, we lose the advantage of interfaces, because the client class now depends on the interface class and the implementation class. Eg. Let's say we have an interface I and 2 concrete implementations of it - say C1 and C2. The whole idea of having interface is to shield client from the concrete classes at compile-time. But the client class still had to know about C1 at compile-time. But the client class still ends up having something like this:
I iobj1 = new C1();
iobj1.executeMethod();
We do have to be aware of C1, otherwise we would never be able to work without real implementations. But it is better to have awareness outside of Java code.

4. Lookup of Resources - A Java object A, say, depending on another Java resource B or a resource like Database C, should not be concerned with looking up for them. We again need a way to externally configure lookup code. So how does Spring help us?
  • Spring helps us achieve the above by wiring the dependencies between objects, all external to Java code.
  • Spring is essentially a technology dedicated to enabling you to build applications using POJOs.The components/objects are simple POJOs providing simple getters and setters. The container wires all the objects passing the dependent objects to POJO properties or constructors.Spring achieves the above using the Dependency Injection mechanism.
  • Most importantly, Spring itself is modular and has a layered architecture. This means we can use just the core JavaBeans configuration management without using the MVC framework or AOP support or DAO support. This means we can create modularized applications of any kind; so you are not restricted to creating web-based enterprise Java applications.
A more detailed discussion on what Spring does and does not can be found here.

Sunday, August 3, 2008

Program to an interface, not an implementation

In the introduction of the GoF book, the GoF mention an important principle of reusable object-oriented design. The principle is: "Program to an interface, not an implementation". The basic reason behind it is to achieve the flexibility in choosing different implementations at run-time as many times via the interface. This is achieved because of the polymorphism feature of the OO languages. The power of interfaces is best understood in design patterns. Most of the design patterns such as Strategy, State, Command, Abstract Factory Method are actually the above principle in practice. Now how do we try to abide by the principle? The best way is to strive for having method signatures with more generic, interface or parent class type method parameters and return types. Also it is advisable to declare class member variables to be of a more generic, interface or parent class type rather than a concrete implementation. The advantages of using interfaces (pure interfaces and/or abstract base classes) are as follows:
  • It is always painless to depend on interfaces. Client classes depending on the interfaces remain unaware of the concrete classes they use indirectly via the interface , as long as the concrete classes adhere to the interface that clients expect. This makes the clients more resilient to changes in implementation details.
  • The above aspect makes unit testing also very easy. In order to test a client class that depends on a complex computation exposed by an interface, we can create a mock stub object that implements the interface to replace the complex computation object.
  • Depending on interfaces has benefits even beyond just programming. The more we depend on concrete classes, the more complex dependency structures become, as a result our build scripts and build processes also tend to be more unwieldy.
Erich Gamma, one of the GoF, explains in an interview: "This principle is really about dependency relationships which have to be carefully managed in a large app. It's easy to add a dependency on a class. It's almost too easy; just add an import statement and modern Java IDEs like Eclipse even write this statement for you.Interestingly the inverse isn't that easy and getting rid of an unwanted dependency can be real refactoring work or even worse, block you from reusing the code in another context. For this reason you have to develop with open eyes when it comes to introducing dependencies. This principle tells us that depending on an interface is often beneficial."