How to implement Factory Method pattern in Java?

Lets say you want to sell headphones.

You create an application to handle your sales.

You create a generic HeadPhoneShop class which can handle creating(buying from the manufacturer) the head phones and sell them.

But you don’t want it to do the actual creation.

You want to delegate it a shop which deals with creating specific type of headphones , say a BossHeadPhone or a PhilipsHeadPhone.

So you create an interface as how to create the phone in your parent class and delegate the actual creation to its subclasses , a BossHeadPhoneShop and a PhilipsHeadPhoneShop.

That explains the ‘Factory Method’ pattern.

Here is the client code :

package creational.factormethod.pattern;
public class Client {
	
	
	public static void main(String a[]) {
		
		
		HeadPhonesShop bossShop = new BossHeadPhonesShop();
		bossShop.sellHeadPhone();
		
		HeadPhonesShop philipsShop = new PhilipsHeadPhonesShop();
		philipsShop.sellHeadPhone();
	}
}

HeadPhonesShop class just sells head phone. The creation of the type of head phones is abstracted . That logic is defined in the type of head phone shop.

Here is the HeadPhonesShop interface:

package creational.factormethod.pattern;
public interface HeadPhonesShop {
	HeadPhones createHeadPhone();
	default void sellHeadPhone() {
		HeadPhones headPhone = createHeadPhone();
		System.out.println("Rate of HeadPhone" + headPhone.getRate());
		System.out.println("Packing and Delivering..");
	}
}

The above class has the method “createHeadPhone()” but does not implement it. It delegates it to its sub classes. Here are the sub classes:

package creational.factormethod.pattern;
public class BossHeadPhonesShop implements HeadPhonesShop{
	@Override
	public HeadPhones createHeadPhone() {
		
		System.out.println("Creating Boss Head Phones");
		return new BossHeadPhones();
	}
	
}

package creational.factormethod.pattern;
public class PhilipsHeadPhonesShop implements HeadPhonesShop{
	@Override
	public HeadPhones createHeadPhone() {
		
		System.out.println("Creating Philips HeadPhones");
		
		return new PhilipsHeadPhones();
	}
}

Here is the product ‘HeadPhones’:

package creational.factormethod.pattern;
public interface HeadPhones {
	int getRate();
}

I have just added one method to get the product specific rate.

Here are the concrete class implementations of the above interface:

package creational.factormethod.pattern;
public class BossHeadPhones implements HeadPhones {
	@Override
	public int getRate() {
		
		return 8000;
	}
}

package creational.factormethod.pattern;
public class PhilipsHeadPhones implements HeadPhones{
	@Override
	public int getRate() {
		
		return 2500;
	}
}

Below is the output on running the application :

Creating Boss Head Phones
Rate of HeadPhone8000
Packing and Delivering..
Creating Philips HeadPhones
Rate of HeadPhone2500
Packing and Delivering..

That’s it.

The Gang of Four call “HeadPhonesShop” as the Creator,

“BossHeadPhonesShop” and “PhilipsHeadPhonesShop” as the ConcreteCreator s.

“HeadPhones” as the Product and

“BossHeadPhones” and “PhilipsHeadPhones” as the ConcreteProducts.

A Creator defers the instantiation of ConcreteProduct to its subclass ConcreteCreator.

That is the factory method design pattern.

Further they define the pattern as :

Define an interface for creating an object but let subclasses decide which class to instantiate. Factory method lets a class defer instantiation to subclasses.

In our case the interface for creating an object is provided in HeadPhonesShop class. The subclasses BossHeadPhonesShop and PhilipsHeadPhonesShop do the actual creation of head phones through the factory method createHeadPhone().

And here is their advice on when to use the factory method pattern :

Use the factory method pattern when

– a class can’t anticipate the class of objects it must create ( in our case HeadPhonesShop doesn’t know what are all the possible type of head phones it needs to create)

– a class wants its subclasses to specify the objects it creates

– classes delegate responsibility to one of several helper subclasses and you want to localize the knowledge of which helper subclass is the delegate

In our case , “the knowledge of which helper subclass is the delegate” is known only to the “Client” class and thus it is localized.

Here is the entire code :

https://github.com/vijaysrj/designPatternsGoF/tree/master/src/creational/factormethod/pattern


Posted

in

,

by

Comments

Leave a Reply

Discover more from The Full Stack Developer

Subscribe now to keep reading and get access to the full archive.

Continue reading