Learnitweb

Factory Method Pattern – Java

1. Introduction

In this tutorial, we’ll discuss Factory Method Pattern. This design pattern comes under creational design pattern as this pattern is used to create objects. In this pattern, we hide the creation logic from the client. We only provide a uniform interface for creating objects.
In this design pattern we define an interface for creating object, but the responsibility of deciding which class to instantiate lies with the subclass. In short, Factory Method Pattern lets a class defer instantiation to subclasses.

This pattern promotes loose coupling as creation logic is separate. This pattern allows adding of more creation logic with less effort. This pattern is heavily used in Java frameworks like Spring.

2. Real-life example

There are different types of tables, like dining table, study table and so on. Suppose you want a carpenter to create a table for you. You’ll ask the carpenter to make a table for you. He’ll then ask which type of table you want. You mention the type of table and the carpenter will create the table for you based on the type of table you ask him to make.

3. Programming example

There are different type of databases like Oracle, MySql and so on. In your code, if the requirement is to connect with Oracle, you can create an Oracle DB connection and if you have requirement to connect with MySQL, you can create a MySQL database connection. You can delegate this creation logic to some other class which will return the database connection according to your requirement.

Another example is in games with several characters. Whenever a character in a game is killed, few games bring it to life again. This logic can be delegated to a class which will create the character for you based on your input.

4. Example

We’ll understand Factory Method Pattern with the help of an example. We have two types of characters – hero and villain. These two characters have one action – the hero protects and the villain destroys. Our factory method will create only these characters. If any other type of character is requested, our factory method will throw an exception. However, this is not required. You can handle such scenario according to your requirement.

4.1 Implementation

Now, we’ll write classes for our example.

ICharacter.java

package com.learnitweb.demo;

public interface ICharacter {
	void action();
}

Hero.java

package com.learnitweb.demo;

public class Hero implements ICharacter {

	@Override
	public void action() {
		System.out.println("I am hero. I protect.");
	}
}

Villain.java

package com.learnitweb.demo;

public class Villain implements ICharacter {

	@Override
	public void action() {
		System.out.println("I am Villain. I destroy.");
	}
}

ICharacterFactory.java

package com.learnitweb.demo;

public abstract class ICharacterFactory {
	public abstract ICharacter getCharacter(String characterType) throws Exception;
}

ConcreteCharacterFactory.java

package com.learnitweb.demo;

public class ConcreteCharacterFactory extends ICharacterFactory {

	@Override
	public ICharacter getCharacter(String characterType) throws Exception {
		switch (characterType) {
		case "Hero":
			return new Hero();
		case "Villain":
			return new Villain();
		default:
			throw new Exception("Character: " + characterType + " cannot be instantiated");
		}
	}
}

FactoryMethodPatternExecutor.java

package com.learnitweb.demo;

public class FactoryMethodPatternExecutor {
	public static void main(String[] args) throws Exception {
		// create factory
		ICharacterFactory characterFactory = new ConcreteCharacterFactory();

		// get hero from factory
		ICharacter hero = characterFactory.getCharacter("Hero");
		hero.action();

		// get villain from factory
		ICharacter villain = characterFactory.getCharacter("Villain");
		villain.action();

		// Since there is no Father character, an exception will be thrown
		ICharacter father = characterFactory.getCharacter("Father");
		father.action();

	}
}

Output

I am hero. I protect.
I am Villain. I destroy.
Exception in thread "main" java.lang.Exception: Character: Father cannot be instantiated
	at com.learnitweb.demo.ConcreteCharacterFactory.getCharacter(ConcreteCharacterFactory.java:13)
	at com.learnitweb.demo.FactoryMethodPatternExecutor.main(FactoryMethodPatternExecutor.java:14) 

5. Conclusion

In this tutorial, we discussed Factory Method Pattern. This creational pattern is one of the commonly used pattern in frameworks . We hope this tutorial was helpful.