Trimming the fat around constructors

Lately I have been seeing a lot of classes that does a lot operations such as

1. having static method calls to instantiate other classes,
2. having complex control flow (conditional or looping logic), or
3. using initialization block.

I shall refer to these type constructors as “Fat Constructor”. First of all please excuse the bad indentation of the codes. I still can’t figure out how to indent paragraph properly in wordpress.

private AddressBar addrBar;
{
   public Browser()
   {
       //retrieve the last url that user visited from the DB.
       String lastVisitedURL = BrowserHelper.getLastVisitedURL();addrBar = new AddressBar();
       addrBar.setURL(lastVisitedURL);
   }

  public String getBrowserURL()
  {
     return addrBar.getURL();
  }

}

The Browser class initialise its address bar with the last URL that user visited. Look great, but testing this class will be a problem. For example:

public class BrowserTest
{
    @Test
    public testBrowser()
    {
         Browser browser = new Browser();
    }
}

When you run this class most likely you will get an error unless you have a database connection live behind you.

So how can we fix this ? One solution would be to shift the responsibility of instatiating the AddressBar to somewhere else, like a Factory class. Using a factory may not be the best solution, nor the way we refactor the constructor.

</code>
public Browser()
{
   private AddressBar addrBar;
   private String URL;

   public Browser(String lastVisitedURL)
   {
       addrBar = new AddressBar();
       addrBar.setURL(lastVisitedURL);
   }

   public String getBrowserURL()
   {
       return addrBar.getURL();
   }
}

public Class BrowserFactory
{

     public Browser createBrowser()
     {
         AddressBar addressBar = new AddressBar();
         String lastVisitedURL = addressBar.setURL(BrowserHelper.getLastVisitedURL());

         Browser browser = new Browser(lastVisitedURL);
         return browser;
     }
}

Now the constructor is doing less things and now the Browser class is more testable. At lest now we can instantiate the Browser class in our unit test without having to worry about setting up a database connection to load the last visited url.

Okay great. Now let us try to test the getBrowserURL method.


public BrowserTest
{
    @Test
    public void testGetBrowserURL()
    {
          Browser browser = new Browser(“http://somerandomurl.com”);
          browser.getBrowserURL();
    }
}

the above unit test will most likely hit a null pointer exception. Since the constructor is the one who is responsible to instantiate the AddressBar, there is almost no way we can test the getBrowserURL. We can improve this by passing the AddressBar into the browser:

public Browser
{
     private AddressBar addrBar;

     public Browser(AddressBar addrBar)
     {
          this.addrBar = addrBar;
     }
}

Now we can easily write a simple test for the getBrowserURL method.

public BrowserTest
{
@Test
    public void testGetBrowserURL()
    {
        //create a mock address bar
        AddressBar mockAddressBar = EasyMock.createMock(AddressBar.class);

        //define the mock address bar behaviourBrowser browser = new Browser(mockAddressBar);
        browser.getBrowserURL();assertTest(“expectedURL”,browser.getBrowserURL);}
    }

Creating a constructor with an AddressBar as a parameter implies that it is mandatory for every Browser instance to have an AddressBar. This is pretty logical. It is pretty unusual to create a Browser without an AddressBar. You will definitely want to be type in a site URL in your browser.

But there are at times when you would not want to show adress bar in your browser. For example, yesterday I went to my neighbourhood library. They have a library system where you can use internet explorer (wow it is so hard to type that) to browse their catalogue. And these browser does not have an address bar. So if we would like to have such feature, it will be good to be able to create a Browser without an address bar. One way to achieve this would be to create a Browser class with a constructor that does not take in an AddressBar and create a setter method to set the AddressBar in to the Browser class:

public class Browser
{
      private AddressBar addrBar;

      public Browser() {}

      public void setAddressBar(AddressBar addrBar)
      {
          this.addrBar = addrBar;
      }
}

We can then use a good dependency injection framework such as Spring or Guice to inject the AddressBar into the Browser class.

Fat constructors are very difficult to test. When a constructor perform object initilisation, we are limiting the reusability of the class because the class now must have these objects attach to them to be usable. Sure we can subclass the class and override the constructor to test it in our test class as a work around. But why do we want to create extra classes just for the sake of testing ?

Related Articles:

1. Misko Hevery – The Testability Explorer Blog

2. Alexandre Gazola – Testability

add to del.icio.us Digg it Stumble It! post to facebook

Advertisements

About zainul franciscus

Hi, I am a software developer and tech blogger who is currently living in Wellington, New Zealand. I write stuff that I find interesting on
This entry was posted in programming and tagged , . Bookmark the permalink.

One Response to Trimming the fat around constructors

  1. Alexandre Gazola says:

    Hello!

    Nice article!

    Cheers

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 )

Google+ photo

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

Connecting to %s