Technical.InversionOfControl History

Hide minor edits - Show changes to markup - Cancel

June 03, 2005, at 03:56 PM by Jettro Coenradie -
Changed line 69 from:

Very important, I borrowed this example from the book I am reading about SpringFramework, Pro Spring from Rob Harrop and Jan Machacek. I will be creating a book review in the blog the coming weeks.

to:

Very important, I borrowed this example from the book I am reading about SpringFramework, Pro Spring from Rob Harrop and Jan Machacek. I will be creating a book review in the blog the coming weeks.

June 03, 2005, at 03:55 PM by Jettro Coenradie -
Changed lines 1-69 from:

to be done

to:

FIrst of all let me state here that there is so much to read about inversion of control on the web that I will not make this to thourough on this website. I suggest you read the article of Martin Fowler about inversion of control and dependency injection.

Now we have that out of the way let's talk a bit about control and feeling comfortable about losing control. In the most common way of programming you as an object create your own related objects. In order to create more loosely coupled systems interfaces are introduced. Let the relations between objects be based on interfaces, or Design by Interface. If you programm agains interfaces there comes a moment you need an instance. Obtaining an instance can be done via a factory object. But in the end you are still requesting you instance, you are still in control. Therefore in some way you are still coupled. What if you can pass this control another object that just initializes you when you are created. Then you loose control, in other words, you have an inversion of control.

Oke, now for an example about losen up your application:

Every now and then you start learning a new framework or language you create your Hello World example. Lets continu this tradition.

public class HelloWorld {

  public static void main (String[] args) {
    System.out.println("Hello World!");
  }

}

This class both contains the message provider and the message renderer. Not able to change the message separate from the provider. And also not easy to change the renderer. Therefore we introduce two interfaces for the renderer and the provider.

public interface MessageProvider {

  public String getMessage();

}

public interface MessageRenderer {

  public void render();
  public void setMessageProvider(MessageProvider messageprovider);
  public MessageProvider getMessageProvider();

}

From this interface we can see the MessageProvider is a dependency for MessageRenderer. However MessageRendere is decoupled from retrieving a message. Now we need implementations for these interfaces. I omit these sources, lets have a look at the new decoupled hello world class.

public class HelloWorldDecoupled {

  public static void main (String[] args) {
    MessageRenderer mr = new StandardOutMessageRenderer();
    MessageProvider mp = new HelloWorldMessageProvider();
    mr.setMessageProvider(mp);
    mr.render();
  }

}

Looks nice, but we still need to know the implementations. Changing the implementation, meens changing the HelloWorld class. One way to overcome this is to use a factory object. Then the code would look like this.

public class HelloWorldDecoupledWithFactory {

  public static void main (String[] args) {
    MessageRenderer mr = MessageSupportFactory.getInstance().getMessageRenderer();
    MessageProvider mp = MessageSupportFactory.getInstance().getMessageProvider();
    mr.setMessageProvider(mp);
    mr.render();
  }

}

Now the factory object has to know the implementation and you have to code the factory objects. These factory objects need to be configured, probably via a configuration file. You still need to pass the dependencies within the code. What if the renderer receives a provider from the factory and you obtain the renderer from a generic provider that can pass the renderer all it's dependencies. Then you have an Inversion Of Control container. Part of the code would then look like this.

public class HelloWorldSpringWithDI {

  public static void main(String[] args) throws Exception {
    BeanFactory factory = getBeanFactory();
    MessageRenderer mr = (MessageRenderer) factory.getBean("renderer");
    mr.render();
  }

  private static BeanFactory getBeanFactory() throws Exception {
    ...
  }

}

Oke I admit, it is a lot of code for a HelloWorld application. But now we have

  • a decoupled renderer and provider,
  • that can be dependency injected without really changing code
  • that can have different implementations of renderers for webbrowsers and sms
  • that we can have lots of fun with

Very important, I borrowed this example from the book I am reading about SpringFramework, Pro Spring from Rob Harrop and Jan Machacek. I will be creating a book review in the blog the coming weeks.

May 16, 2005, at 12:45 PM by Jettro Coenradie -
Added line 1:

to be done


Page last modified June 03, 2005, at 03:56 PM