Factory Design Pattern

In the Factory Design pattern we have an Interface or an abstract class and we decide which subclass gets instantiated depending on the arguments we pass. The object creation logic is hidden from the user.

In the factory design pattern we can pass arguments, and we can get an instance of a class depending on the arguments, we do not exactly know which class object we will get since its determined by the arguments that we pass.

The factory pattern is generally used at a higher level of an inheritance tree. and the classes at a lower level of the inheritance tree will generally invoke it.

An example for the Factory design pattern in Java is the NumberFormat class.

Consider the following scenario to get an idea of how the factory pattern is used.

Consider a TV provider. The TV provider has provides different types of channels based on the Package of the User. If the user has a Sports package the TV provider will provide channels related to sports, if the user has a news Package the TV provider will provide channels related to News

Imagine that the TV provider has 5 types of packages, Basic, News, Sports, Entertainment and Premium.

Lets say that

  • The Basic package has the Channel BasicChannel1
  • The News package has the Channel NewsChannel1
  • The Entertainment package the Channel MovieChannel and SongsChannel
  • The Sports package the Channel SportsChannel1 and SportsChannel2
    The Premium package has all the channels including channels of Basic, News and Sports

In this case we can use the factory design pattern as shown below.

The following are the classes that we are going to use to create for this.

The classes can be explained as follows.

  • A Super class for all the Channels
  • A class for each channel.
  • A PackageFactoryClass.
  • A super class for all the Packages.
  • Each class for each Package
  • An enum class just to have the PackageCodes.
  • A Main class just to have the main method.

The channel classes would look like this

//Super class for all the channels
public abstract class Channel {
}
public class BasicChannel1 extends Channel{
@Override
public String toString(){
return ("Basic Channel 1");
}
}
public class MovieChannel extends Channel{
@Override
public String toString(){
return ("Movie Channel");
}
}
public class MusicChannel extends Channel{
@Override
public String toString(){
return ("Music Channel");
}
}
public class NewsChannel1 extends Channel{
@Override
public String toString(){
return ("News Channel 1");
}
}
public class SportChannel1 extends Channel{
@Override
public String toString(){
return ("Sports Channel 1");
}
}
public class SportChannel2 extends Channel{
@Override
public String toString(){
return ("Sports Channel 2");
}
}

There is nothing major in these classes. We have just overridden the toString method so that it will be easier to understand when we see the output.

we have created an enum just to hold the packageCodes for each package.

enum Packages {
BASIC,
NEWS,
SPORTS,
ENTERTAINMENT,
PREMIUM
}

As We did for the Channels we need to create classes for different packages as well.

The Package class would look like this, which is the super class for all package classes

public abstract class Package {
protected List<Channel> channels = new ArrayList<>();

public Package(){
createPackage();
}

//This is an abstract method.
protected abstract void createPackage();

@Override
public String toString(){
return ("This package has these Channels : "+channels);
}
}

The important thing to notice here is that we have an abstract method called create package. Therefore the createPackage method is always implemented by the classes that extends the Package class (The subclasses of the package class which are BasicPackage, NewsPackage etc).

And the package classes would look like this.

public class BasicPackage extends Package{

@Override
protected void createPackage() {
channels.add(new BasicChannel1());
}
}
public class NewsPackage extends Package{

@Override
protected void createPackage() {
channels.add(new NewsChannel1());
}
}

As you can see the createpackage method is implemented by each of the packages.

public class SportsPackage extends Package{

@Override
protected void createPackage() {
channels.add(new SportChannel1());
channels.add(new SportsChannel2());
}
}
public class EntertainmentPackage extends Package{

@Override
protected void createPackage() {
channels.add(new MovieChannel());
channels.add(new MusicChannel());
}
}
public class PremiumPackage extends Package{

@Override
protected void createPackage() {
channels.add(new BasicChannel1());
channels.add(new NewsChannel1());
channels.add(new SportChannel1());
channels.add(new SportsChannel2());
channels.add(new MovieChannel());
channels.add(new MusicChannel());
}
}

Since the Sports, Entertainment and the premium packages have more than a single channel they add more than one instance to the list.
For example since the Sports package has 2 channels, the instances of both the channels are added to the list.

And then we have the Package factory class.

public class PackageFactory {

public static Package createPackage(Packages packageCode){

switch (packageCode){
case BASIC:
return new BasicPackage();
case NEWS:
return new NewsPackage();
case SPORTS:
return new SportsPackage();
case ENTERTAINMENT:
return new EntertainmentPackage();
case PREMIUM:
return new PremiumPackage();
default:
return null;
}
}
}

The packageFactory class has a static method that will return the package depending on the package code.

We can use this as shown below.

Package entertainmentPackage = PackageFactory.createPackage(Packages.PREMIUM);

This would give us the Premium package.

public static void main(String[] args){

Package entertainmentPackage = PackageFactory.createPackage(Packages.PREMIUM);
System.out.println(entertainmentPackage);

}

The output of the above code will look like this.

This package has these Channels : [Basic Channel 1, News Channel 1, Sports Channel 1, Sports Channel 2, Movie Channel, Music Channel]

As we can see in the output. We see that the Premium package will have all the channels that belong to the Premium package.

What happens in the Factory is that it returns the instances based on the parameters the factory gets, therefore it doesn't always return the same instance.

References

  1. https://www.youtube.com/watch?v=8W-BeJH1aO0&list=PLD-mYtebG3X86i3uyAXwZKfVtUy2gMDdo&index=4
  2. https://www.geeksforgeeks.org/factory-method-design-pattern-in-java/

--

--

--

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Cleaning up our spawns

Beyond Code: A Holistic Approach to Agile App Development

Postmortem: Deleting data from a Production database

The Definitive Guide to AWS EC2 Instance Types

Aspects to use while prioritizing features

Cors Issue. How to disable Cors in Chrome.

74th Monthly Technical Session

Add XAMPP PHP to Environment Variables in Windows 10

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Shashane Ranasinghe

Shashane Ranasinghe

More from Medium

How to avoid the telescopic constructors with builder pattern design pattern in JAVA

Singleton Design Pattern

Java virtual machine(JVM) Architecture (JVM Main Components)

Singleton Design Pattern in java