Factory method pattern – interesting appliance

Today I’m going to talk about factory method pattern and it’s very interesting appliance. It is very common  situation when you’ve got complex object which performs complex initialization. How can we test behaviour of this complex object and avoid it’s construction complexity? Factory method pattern comes to rescue.

Let’s start from practical example. Personally while implementing my jxmpp-bot application (hosted here) I’ve faced with situation when some service object should be tested using unit tests. But this service object has sophisticated initialization sequence.

Let’s see the pictures:

facPtSeq

facPtClass

As you can see from sequence diagram Service user creates Database wrapper, Repository and finally Service and performs some actions by calling useService() method. This is the method we want to test.

Service object itself invokes initializeService() private method in it’s constructor in order to perform some complex initialization.

The common technique in this situation is to extract interface from Service and create MOC object. MOC object “skips” initalization issues in it’s constructor but provides simulation of useService():

public class ServiceMoc {
    public ServiceMoc(){
	//nothing todo here
    }
    public void useService(){
	//emulate service behaviour here
    }
}

It would be really sweet if we can test service like this:

import static org.junit.Assert.assertTrue;

import org.junit.Test;

public class ServiceTest {
    @Test
    public void testUseService() {
	Service service = new ServiceMoc();
	assertTrue(service.useService());
    }
}

But unfortunately ServiceMoc isn’t subclass of Service. Yeah we can extract interface of service:

public interface IService {
    boolean useService();
}

public class Service implements IService {

    public Service(Repository repo) throws Exception {
	if (!initializeService(repo))
	    throw new Exception("Can't initialize service");
    }

    @Override
    public boolean useService() {
	// Perform complex behavior here
	return true;
    }

    private boolean initializeService(Repository repo) throws Exception {
	if (repo == null)
	    throw new Exception(
		    "Repository must be initialized since it is heavy used during initialization");
            // do initialization here
	return true;
    }
}

And test it like this:

import static org.junit.Assert.assertTrue;

import org.junit.Test;

public class ServiceTest {

    @Test
    public void testUseService() {
	IService service = new ServiceMoc();
	assertTrue(service.useService());
    }
}

But there is another alternative – Factory method pattern.

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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s

%d bloggers like this: