Factory Method VS Simple Factory

Factory Method VS Simple Factory

While taking Interview of a senior developer, Often I asked a question to the candidate that do you know Design pattern?

They Said yes and then I ask them what are some design patterns you familiar with and use in your project?

Most of the cases I got answer Factory pattern and Singleton Pattern!!!.


As this is an article on Factory I just ignore Singleton interview discussion here.

Next question from my side is, tell me a business case and write down code fragments for Factory method.

But unfortunately, they gave the example of Shape a well-known example in google, and end up with writing a Simple factory which is not considered as a Design pattern :).

In this article, I will not show How to write Simple factory or Factory method rather than I will discuss what are they exactly and when to use them.


In the course of taking  interviews, I realize some points,
  1. we are actually trying to memorize the Design pattern not able to understand what the problem context it tries to solve.
  2. Another realization is we are not analyzing the Business justification first and then apply pattern based on this rather we try to find where in the business requirements we can fit the pattern that I know.




Simple Factory:

When To Use: If your program only bothers about creating a family of Products so a client of your code can get any products of that family at runtime you should use the Simple factory.




Coding :

To achieve the same, we create an interface where we define the set of methods which are required for creating the desired Products, Those methods implementation can be varied in Actual implementations.


Now, We will Create a TopLevel class which usually has a Static method where the client passes the desired parameter to get the Actual implementation.

Please Note that Simple factory uses a Static method and returns the actual implementation based on the parameter pass by a client. Here Client may be another code which uses your API or a request from The Web etc.

Coding Template :

Say we want to create TV and our client want to get different kinds of TV from our program like LCD, LED, Black&White, COLOR,3D etc.

So we will create an Interface ITV which has a method createTV(),
Children of ITV interface actually provide the implementation of createTV() and client calls them through a static method by passing parameter(main method).



Interface

/**
*
*/
package com.example.factory;

/**
* @author Shamik Mitra
*
*/
public interface ITV {
   
    public void createTV();

}


SimpleFactory


/**
*
*/
package com.example.factory;

/**
* @author Shamik Mitra
*
*/
public class TVSimpleFactory {
   
    enum TVMODE{COLOR,LED,LCD,THREEDIM};
   
    public static ITV getTV(TVMODE mode){
       
        if(mode.equals(TVMODE.LED)){
            return new ITV(){

                @Override
                public void createTV() {
                    System.out.println("LED TV");
                   
                }
               
            };
        }
        return null;
    }
   
    public static void main(String[] args) {
        TVSimpleFactory.getTV(TVMODE.LED).createTV();
    }

}


Justification :

By Simple Factory, we abstract the creation of the product from our client. Only our client knows, by calling the Static method and passing the desired parameter it gets an Object of that TV type. But How TV is created client code does not know, Actually they are also least bother to know How you produce that product. I only care for my SONY LED not How they create the same.

So whenever you see there are chances to create many types of implementation of an Object use Simple factory there But hey don’t take this as a Silver bullet. Try to understand the business justification then apply the pattern on it may be it is provocative to use Simple factory for a Business requirements but it may happen you are thinking of a small scope but at a broader scope that will hurt your design , read the next to see how a simple change in business requirements can change the design.


Factory Method:


When To Use: If Business needs more than Object creation, to be precise If you want to control the creation process and control the use case where any parts of the use case can be customized we use the Factory method. To put it simple way, If you want to control an Algorithm/Strategy on a family of products. you can think factory method pattern and it plays very well with Template pattern where Template method control the Strategy/Algorithm and it steps are abstract which can be created in an actual implementation of Factory.

Use Factory method when you want to make a Framework where you want to take a control from creation of the Object to management of that Object, unlike Simple factory where you only bother about the creation of product not How to create and manage it.

Recall The Headfirst Pizza Example where orderPizza() method,  create Pizza then bake cut and Box it. So it is nothing but an Algorithm which stays same for all Pizza and orderPizza is a template Method.

But you can also add an abstract method called applyTax() method in orderPizza(), in the actual implementations of the factory you can apply tax decision on Region basis,  So I can tell I can have fine control over Pizza  Lifecycle,  Not only the creation also the management part.


Back to our Example. Now If Our Business requirements want we not only Create the TV also take orders and Ship the TV and based on the city shipping charge is applicable.

So, It is clear now we need to create an algorithm which will create Different Tv and shipped them and calculate Shipping charge so factory method is ideal here we can't do it by Simple Factory so change is needed in design


Coding : We create an Interface for Product. Actual implementation create concrete product along with this also we create an abstract class called factory where
We maintain the algorithm in a template method and abstract the product creation and necessary part of the strategy  so in the subclass of the factory we can implement them according to business requirement.



Coding Template :

Interface of Product

/**
*
*/
package com.example.factory;

/**
* @author Shamik Mitra
*
*/
public interface ITV {
   
    public void createTV();

}


AbstractFactory Class

/**
*
*/
package com.example.factory;

import com.example.factory.TVSimpleFactory.TVMODE;

/**
* @author Shamik Mitra
*
*/
public abstract class AbstractFactory {

    public final void orderTV() {
        createTV();
        int charge= shippingCharge();
        System.out.println("Shipping charge :: " + charge + " INR");

    }

    protected abstract int shippingCharge();

    protected abstract void createTV();

}



Concrete Factory

/**
*
*/
package com.example.factory;


/**
* @author Shamik Mitra
*
*/
public class LEDTVFactory extends AbstractFactory {
    @Override
    public int shippingCharge() {
        // TODO Auto-generated method stub
        return 1000;
    }

    @Override
    public void createTV() {

        new ITV() {
            @Override
            public void createTV() {
                System.out.println("LED TV");

            }

        }.createTV();

    }

    public static void main(String[] args) {
        AbstractFactory factory = new LEDTVFactory();
        factory.orderTV();
    }
}

Justification : By Factory method, we not only abstract the Product creation but take one step further here we also abstract the factory which creates the product. So the benefits are that we can control the creation of Product and management of the product. If you see the above code you can see We abstract the factory with the ITV interface and in the Abstract factory, we create a template method which controls the TV lifecycle -- create TV and Shipping cost calculation and make them abstract so Children of Abstract factory can change them accordingly.

We can say Factory method Abstract the Creator from the caller. One level more abstract than Simple factory.

Benefits:

Create a Framework.
Control Product lifecycle.


TIP: If you only deal with the family of products go for Simple Factory but If you need to control the product creation and management go for Factory method.


































A word on toString()

A word on toString()



Can you spot the problem?

AccountHolder.java



package com.example.toString;

import java.util.ArrayList;
import java.util.List;

public class AccountHolder {
   
   private String name;
   private List<Account> accList=new ArrayList<Account>();
   
   public void addAccount(Account acc){
      accList.add(acc);
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   @Override
   public String toString() {
      return "AccountHolder [name=" + name + ", accList=" + accList + "]";
   }

}


Account.java
   
   
package com.example.toString;

public class Account {
   
   private String accNumber;
   private String accType;
   private AccountHolder holder;
   public String getAccNumber() {
      return accNumber;
   }
   public void setAccNumber(String accNumber) {
      this.accNumber = accNumber;
   }
   public String getAccType() {
      return accType;
   }
   public void setAccType(String accType) {
      this.accType = accType;
   }
   public AccountHolder getHolder() {
      return holder;
   }
   public void setHolder(AccountHolder holder) {
      this.holder = holder;
   }
   @Override
   public String toString() {
      return "Account [accNumber=" + accNumber + ", accType=" + accType
              + ", holder=" + holder + "]";
   }
   
   
   

}



Testing above

Main.java

package com.example.toString;

public class Main {
   
   public static void main(String[] args) {
      AccountHolder ach = new AccountHolder();
      ach.setName("Shamik Mitra");
      Account acc = new Account();
      acc.setAccNumber("100sm");
      acc.setAccType("Savings");
      acc.setHolder(ach);
      ach.addAccount(acc);
      System.out.println(ach);
   }

}



I believe you guess the problem. If you do not spot the problem please stop here and again go through the code to spot the problem.



What is the Problem?

The above code snippet, unfortunately, gives you a StackOverflowError.

While reviewing a juniors code I spotted the problem, Actually, his program runs well in the Development environment and he came to me to review his code.


To explain the essence of the problem I replicate the same here, I have an AccountHolder Object which holds the list of Account and on another hand In Account Object, we have a reference to AccountHolder.

This is a normal scenario when we design JPA entity, But the problem is we blindly populate the toString method using the editor and which create a circular call and eventually it blows up the code with StackOverflow Error.

As AccountHolder toString it tries to print the list of Account so it calls  Account toString() and in Account toString() it again tries to prints  AccountHolder so the cycle continues until StackOverFlowError occurs.
My Junior can’t spot the problem as in his program he never prints the Account or AccountHolder object so it deployed and works fine in Development server.


So what is the Point?

The point I want to convey here is that maybe this type of problem always can't be seen in naked eyes as may be there is transitive dependencies like A class has B, B has C and C has A.

So ,

  1. Try use tools which can point out your circular dependencies.(Though I am not using any due to some constraints).
  2. In a class, only prints variable which are belongs to that class. For safety purpose not print any HAS-A relation.
















Spring: Be careful when using PropertyPlaceholderConfigurer

A word on PropertyPlaceholderConfigurer

A few days back one of my juniors came to me and said that when he test his modules separately in JUnit that worked perfectly but when the modules were deployed in Server as a unit, Server fails to start.


So I checked his code and fortunately identified the problem.
in this Article, I will discuss  that problem.

Let me describe the problem in detail.
Problem Statement:

The application he works on has three layers.

1.Dao layers
2.Service layers.
3.Middleware(Spring MVC).


Which is very standard architecture, and each layer built on top of spring so maintains separate Spring context files.

Each layer maintains its own property file.

Say for  Dao layers database connection related properties are maintained in  db.properties.
In Service layer, web service URL or other service parameters are maintained in service.properties file.

To load these properties files in application it uses PropertyPlaceholderConfigurer in each SpringContext file (Dao, Service, Middleware).




Sample example

db.properties
db.url=abc@localhost:1028/BillSchema
db.user=admin
db.password=tiger


and the entry for PropertyPlaceholderConfigurer in Spring_DB_Context.xml

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
       <property name="locations">
           <list>
               <value>classpath:db.properties</value>
             </list>
       </property>
      </bean>



Same for Services

Service.properties

bil.user=admin.
bill.passwd=abcd

and the entry for PropertyPlaceholderConfigurer in Spring_Service_Context.xml
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
       <property name="locations">
           <list>
               <value>classpath:service.properties</value>
             </list>
       </property>
 </bean>


In middleware, Spring context Spring_Middleware_Context.xml   imports  Spring_DB_Context.xml and Spring_Service_Context.xml


Now when he runs each modules Junit test it can resolve the properties files and works fine, but the problem kicks in when middleware application combine other two modules as jar and import context files into Spring_middleware  context and try to deploy in Server.

It Shows an error message {db.url} can’t resolve, and server fails to start.


So, His question is why it is happening?
In Junit, it runs but when we clubbed two modules as a jar and try to deploy it on server why such error message, as we have provided the PropertyPlaceholderConfigurer in each context and both properties files are present in classpath.


Actual Problem:

Upon viewing the error message one thing is clear that somehow those properties are not resolved by PropertyPlaceholderConfigurer.

Now deep dive to Spring context to understand why it is not resolved?

There are three separate Spring context files

Spring_DB_Context.xml
Spring_Service_Context.xml
Spring_Middleware_Context.xml


Spring_DB_Context.xml,Spring_Service_Context.xml joins the big context Spring_Middleware_Context.xml while deploying, via import statement in Spring_Middleware_Context.xml.

And each context has it’s own PropertyPlaceholderConfigurer and a property file. Now, if the Service context is loaded first by classloader then it’s PropertyPlaceholderConfigurer is loaded and it properties files so this PropertyPlaceholderConfigurer can resolve the beans under Service context but won’t able to resolve the properties of DB_Context as Service PropertyPlaceholderConfigurer does not knows about that db.properties  file. So server says {db.url } can’t resolved.

Same is true for service layer if classloader load Db Context first the {service.url} can’t be resolved.


Solution

The solution is just a tweak in PropertyPlaceholderConfigurer in each context. Just add the following line

<property name="ignoreUnresolvablePlaceholders" value="true"/>


So, Updated context files

Service context

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
       <property name="locations">
           <list>
               <value>classpath:service.properties</value>
             </list>
       </property>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
 </bean>


DB context

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
       <property name="locations">
           <list>
               <value>classpath:dbproperties</value>
             </list>
       </property>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
 </bean>


By doing this we tell Spring to ignore the unresolved properties or put it in another word
By default, Spring throws an exception if it can’t resolve a property that is fail-fast in nature.
But here we will explicitly say to Spring don’t throw the exception but go on with unresolved properties defer the action so when other PropertyPlaceholderConfigurer(Db Context)  will be loaded it will resolve the other part.

NB: Please note that for each context you have to mention
<property name="ignoreUnresolvablePlaceholders" value="true"/>, unless if one context does not provide aforesaid tag it will fails there immediately as by default Spring is fail-fast.

My juniors case  was very similar like this although he provides <property name="ignoreUnresolvablePlaceholders" value="true"/> in every modules still it fails.

Then I search for transitive dependencies on its module and found that one of the modules does not define <property name="ignoreUnresolvablePlaceholders" value=" true"/> tag in its context so it fails there, we update the same and recompile it then all problem just gone like magic.


TIP: Always use <property name="ignoreUnresolvablePlaceholders" value="true"/>, with PropertyPlaceholderConfigurer  as you never know when and how other modules use your modules and they may have their own  PropertyPlaceholderConfigurer as well, So you can break their code unknowingly  and give them an opportunity to scratch their head.