Hello authors, The following text is from the chapter 1 of your book.
If you are relying on EJBs to provide your application services, your components do not just depend on the EJB business interface. They are also responsible for retrieving these EJB objects from a directory, which entails a Java Naming and Directory Interface (JNDI) lookup and communicating with the bean�s EJBHome interface. This is not creating a decoupled application. This is tightly coupling your application to a specific implementation, namely EJB. With Spring, your beans depend on collaborators through interfaces. Since there are no implementation-specific dependencies, Spring applications are very decoupled, testable, and easier to maintain. And because the Spring container is responsible for resolving the dependencies, the active service lookup that is involved in EJB is now out of the picture and the cost of programming to interfaces is minimized.
I had know that programming to interfaces is a good practice. But the last line says that, cost of programming to interfaces is minimized ? I am wondering what does that mean ? Why would we want to minimize the cost of programming to interfaces ? [ April 15, 2005: Message edited by: Reghu Ram T ]
As you must be aware, all business interfaces must extend javax.ejb.EJBObject for remote interfaces and javax.ejb.EJBLocalObject for local interfaces.
But in addition to specifying your business behaviour, your remote interface ends up inheriting other EJBObject methods and hence tightly coupled to EJB implementation. So this interface does not make sense outside EJB enviroment. I guess it is that disadvantage they are referring to.
In Spring , your interface would be having only your business methods and hence usable in every context.
In EJB, the interfaces you're programming to extend javax.ejb.* interfaces, coupling your code with the EJB framework. Also your EJB implementation class must extend javax.ejb.* classes. This forces you to write implementations of EJB lifecycle methods. Maybe these methods are useful to you, but in my experience they are left as empty implementations most of the time. But you still have to implement them because the spec says so.
What's worse is that the interfaces you write (home and remote/local) aren't even implemented by your implementation class! You write these interfaces to describe the methods your bean will provide, but then you write the implementation class and don't even get to implement those interfaces. That's always been a peculiar piece of the EJB spec to me.
In Spring your interfaces are just POJI (plain-old Java interfaces). You aren't forced to extend any other interface. And your implementation classes are just POJOs (no need to extend anything special, except in the case of the subframeworks--MVC, AOP, etc). No need to implement special lifecycle methods.
But, if you would like, you may still implement lifecycle methods. All you need to do is implement the BeanPostProcessor and/or BeanFactoryPostProcessor interfaces. And if you'd like access to your container, you just implement either BeanFactoryAware and/or ApplicationContextAware. Sure, at this point you're implementing Spring-specific interfaces--but it's a choice, not a mandate from the framework.
I always saw the "reducing the cost of programming to interfaces" benefit in a different light. As the OP said, programming to interfaces is a good thing - it helps create decoupled applications. However, these interface dependencies have to be resolved to a concrete class somehow.
It is this "somehow" that has always been the problem for me. For non-EJB applications, I would typically create a custom factory that my objects would query to obtain the appropriate implementation of a given interface. This meant two things:
1. I had to actively look up my dependencies. I don't really like this approach. To me, it cluters up my classes with dependency look-ups that aren't really relevant to the specific duting of that class (enforcing business rules, persisting data, etc). Instead, I have junk like:
2. I had to figure out a way to configure my factory so it would know what the appropriate implementation class is for a given interface. Again, something I don't want to spend a lot of effort on - creating customizable factories.
Spring solves both of these issues. Its IoC approach elimates the need for active dependency resolution. Instead, my objects are *given* their dependant objects at run time. Cool!
More importantly, Spring already comes with a full-featured means to configure my "factory" - in this case the Spring container itself. No longer do I have to create custom factories, I just need to configure Spring with an XML file that is quite clear and intuitive.
In a nutshell, programming to interfaces *is* a good thing and Spring makes it easy to do this.