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, and 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 and flexible.
I had the following situation at 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:
Get the source code to follow the article:
https://github.com/rafadelnero/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:
- Instantiated the class BillingServiceFactory
- Passed the command in the constructor
- 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:
- The Invoker class instantiates the Factory class
- The Factory class decides what Service is going to be invoked
- The Invoker gets the Service
- The Invoker invokes the method of the Service implementation
- 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!
Thanks for sharing your experience!
And by the way, diagram is so cool, that I want to know in what software did you make it?
Hello Alexander, thanks for the compliment! I used genmymodel! See you!
Good article, combination of design patterns together can do wonders. Also nice diagram, interested to know how did you created. Btw, I have also shared my 2 cents on Strategy pattern and OCP principle @ http://javarevisited.blogspot.com/2015/07/strategy-design-pattern-and-open-closed-principle-java-example.html, let me know if you like it.
Hello JavaRevisited, I used genmymodel! Awesome, I will check your article out! Thank you!
Great explanation of patterns! I will stick near to this SAGA =D
Thanks for sharing!
Awesome Rodrigo! Thank you! Stay tuned for more real situations with Design Patterns, I will cover them all! See you!
It’s exactly *not* polymorphism when you decide per enum which class to instantiate.
Atleast have the BillingEnum’s return its BillingService directly, that saves the switch-case.
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.
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
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!
didn’t received my ebook.
Hi Manish, go to this url:
https://javachallengers.com/no-bugs-no-stress-free-ebook/
Then, once you put your email there, you will receive the ebook on your email 🙂
Let me know if you got it! Keep the code on!
Hi Manish, you will receive your e-book after informing your email on our landing page, then you will receive the book right away. Let me know if you still didn’t get it.
Keep the code on!