Design Patterns Saga #1: Real Project Situations with Factory Method and Strategy

The problem: If we don’t know what Design Patterns we have available to solve day-to-day situations, it’s going to be very difficult to implement the best solutions.

Our code can have very high coupling and no cohesion which causes no flexibility and no scalability. Then, you-know-who is going to appear. If you thought bugs, yes! You are right! The bugs will have a party in the code, making our lives very stressful.

Very experienced programmers of GOF (Gang of Four) Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides created Design Patterns, solutions for common and day-to-day coding situations. Many of the problems GOF faced were solved after creating the Patterns, that’s why it’s so important to know them.

Instead of going through the same problems they did for many years, we can learn those Patterns and make our code clean, flexible and powerful.

I had the following situation in my job. I had to receive a command from a Web Service and call the specific Service for each command.

What solution would be appropriate for this situation?

Factory Method + Strategy

The diagram:

class_diagram.PNG

Get the source code:

https://github.com/rafadelnero/nobugsproject.git >> design-patterns-saga

1 – Invoker class: the executeAction() method will receive the command and depending on the command received, it will invoke the correspondent Service.

public class BillingInvoker {

	public void executeAction(String command) {
		int idContract = 1;

		new BillingServiceFactory(command).getService().execute(idContract);
	}

}

2 – This is where we use the pattern Factory Method. Pretty simple, isn’t it? We receive the command in the constructor and decide what Service we are going to invoke.

I created an Enum to make the selection clearer and easier to read. I just make a parse to an Enum. Then I choose the Service to be invoked in the command ‘switch case’.

Another important thing to be aware of is that the method getService() is returning an interface. I am using polymorphism in this method. It returns any BillingService, any class that implements it.

public class BillingServiceFactory {

	private String command;

	public BillingServiceFactory(String command) {
		this.command = command;
	}

	public BillingService getService() {
		BillingEnum billingEnum = BillingEnum.parse(command);

		switch (billingEnum) {

		case PRE_CALCULATION:
			return new BillingPreCalculation();

		case CALCULATION:
			return new BillingCalculation();

		default:
			throw new IllegalArgumentException("The service does not exist.");
		}
	}

}

3 – Let’s check out the BillingService interface. Actually, it’s very simple, but necessary to make the Strategy pattern work. With this interface, we can use the very powerful technique, polymorphism. We can invoke the execute(long idContract) method from any class that implements BillingService.

public interface BillingService {

	public void execute(long idContract);

}

4 – Now that we know about the BillingService interface, we can come back to the Invoker class and check it out better. No secret, we just:

  1. Instantiated the class BillingServiceFactory
  2. Passed the command in the constructor
  3. Invoked the getService() method where we get one implementation of the interface BillingService

Here is the magic! We are going to invoke the execute(long idContract) method from the interface, and guess what, we are controlling what implementation we are invoking by the command!

We are isolating the responsibilities and making the code powerful! An important detail is that we must create a generic method name in BillingService, because we don’t know what we are going to invoke. When we return the implementation of the interface we can only use the interface method. You could use a specific method from the implementation if you use class cast only.

public class BillingInvoker {

	public void executeAction(String command) {
		int idContract = 1;

		new BillingServiceFactory(command).getService().execute(idContract);
	}

}

5 – The invocation! Let’s suppose we receive a command to invoke BillingCalculation. What are we going to do? We are going to invoke the BillingCalculation method!

public class BillingCalculation implements BillingService {

	public void execute(long idContract) {
		calculateContract(idContract);
	}

	public void calculateContract(long idContract) {
		System.out.println("BillingCalculation was invoked");
	}

}

6 – The output! It will be printed: BillingCalculation was invoked

We made it!

Summary of our actions:

  1. The Invoker class instantiates the Factory class
  2. The Factory class decides what Service is going to be invoked
  3. The Invoker gets the Service
  4. The Invoker invokes the method of the Service implementation
  5. The output of the Service implementation is printed

You can test the pattern with these Unitary Tests:

public class StrategyFactoryMethodTest {

	private static final long idContract = 1;

	@Test
	public void invokePreCalculationTest() {
		BillingService billingService = new BillingServiceFactory(BillingEnum.PRE_CALCULATION.getCode()).getService();

		billingService.execute(idContract);
		Assert.assertTrue(billingService instanceof BillingPreCalculation);
	}

	@Test
	public void invokeCalculationTest() {
		BillingService billingService = new BillingServiceFactory(BillingEnum.CALCULATION.getCode()).getService();

		billingService.execute(idContract);
		Assert.assertTrue(billingService instanceof BillingCalculation);
	}

	@Test(expected = IllegalArgumentException.class)
	public void notExistentCommandTest() {
		new BillingServiceFactory("777").getService();
	}

}

To practice using this Pattern you can implement a new unitary test to a new Service and make it work!

Design Patterns Saga #1: Real Project Situations with Factory Method and Strategy

11 thoughts on “Design Patterns Saga #1: Real Project Situations with Factory Method and Strategy

    1. Hello SG, it’s polymorphism at the moment I am returning a generic type, the BillingService. The Enum is only used to decide what instance I am going to return.

    2. kamineko says:

      At one point you have to decide which class to instantiate – how would you do it?
      For this is java, I do not know if my approach is possible. In .NET/C# I always use attributes and reflection to gather factory methods by some key (like the enum), in which case I “magically” get the correct instance by key without any switch/case or if/else

      1. Hi Kamineko, it’s possible to use Reflection in Java also. We can ‘magically’ create instances using Reflection too. I intend to create Reflection posts maybe after the Design Patterns Saga. Stay tuned for more next week!

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