Need of Factory Method Design Pattern in Frameworks Explained

In a framework we deal mainly with abstract classes. Application that is going to use our framework provides the derived classes these abstract classes.

Let’s understand by an example of Thread pooling Framework,

A thread pooling framework provides the facility to execute Tasks in pooled environment by worker threads. It’s doesn’t know what actually the Task is, it just provides the facility to run this Task.

So, Task here is an abstract class.

Framework also uses an abstract class TaskFactory to create the Task objects. In application, Task objects can be created based on any xml file, json file or through any other input channel. But that framework doesn’t need to know that, because that completely depends on application that is using this framework.

Framework deals only with an abstract class TaskFactory to create Task objects.

[showads ad=inside_post]

Remember frameworks main responsibility is,

  • Storing Tasks in waiting queue.
  • Executing Tasks through worker Threads.
  • Providing the output of executed Tasks.

Framework is not interested in,

  • What exactly is the Task
  • How to create Task Objects

Therefore, Framework will use two Abstract classes,

1.) Task

It’s an abstract class that contains an abstract function execute(). Framework will use this abstract class to deal with all types of Tasks.

/*
 * Part of Framework
 */
class Task
{
public:
  virtual void execute() = 0;
  virtual ~Task(){}
};

 

2.) TaskFactory

It’s an abstract class that is used by framework to generate different Task objects. Which actual Task should be generated is decided by classes derived from TaskFactory.

/*
 * Part of Framework
 */
class TaskFactory
{
public:
  virtual Task * getTaskObject() = 0;
  virtual ~TaskFactory(){}
};

Classes derived from Task and TaskFactory classes are provided by application that is using this framework.

Factory Method Design Pattern

This is the perfect case to use Factory Method Design Pattern.

Intent of Factory Method Design Pattern

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

A factory method design pattern should be used when,

  • A class is assigned with responsibility to create an object of an Abstract class but it doesn’t know the actual derived class of objects it must create.
  • A class wants its subclasses to specify the objects it creates.

Now in our application i.e. using this framework, have two types of Tasks i.e.

EMailTask :

  • Derived from Task.
  • This will send the mail to a specified user.

/*
* Part of Application i.e. using this framework
*/

class EMailTask : public Task
{
public:
void execute()
{
std::cout<<"Executing EMailTask "<<std::endl;
}
};

SMSTask :

  • Derived from Task.
  • This will send the SMS to a specified user.

/*
* Part of Application i.e. using this framework
*/
class SMSTask : public Task
{
public:
void execute()
{
std::cout<<"Executing SMSTask "<<std::endl;
}
};

Now two create the objects of these two types of Tasks we have to Two factory classes,

EMailTaskFactory :

  • Derived from TaskFactory
  • It overrides the factory method to return an instance of a EMailTask object.

/*
* Part of Application i.e. using this framework
*/
class EMailTaskFactory : public TaskFactory
{
public:
Task * getTaskObject()
{
return (new EMailTask);
}
};

SMSTaskFactory :

  • Derived from TaskFactory
  • It overrides the factory method to return an instance of a SMSTask object

/*
* Part of Application i.e. using this framework
*/
class SMSTaskFactory : public TaskFactory
{
public:
Task * getTaskObject()
{
return (new SMSTask);
}
};

Here getTaskObject is the factory method.

Now consider this is a dummy code of our framework,

/*
 * Some Framework Code
 * As, it’s a framework code it doesn’t know which Derived TaskFactory
 * class object was inside this TaskFactory pointer and which Task was
 * actually created.
 */

void someFrameworkCode(TaskFactory * taskFactory)
{
  Task * ptr = taskFactory->getTaskObject();
  ptr->execute();
  delete ptr;
}

Here this framework function is accepting a TaskFactory pointer. From this TaskFactory pointer it is creating a Task object and calling the execute function.

As, it’s a framework code it doesn’t know which Derived TaskFactory class object was inside this TaskFactory pointer and which Task was actually created.  Both of this was managed by the code of our application i.e.

int main()
{

 /*
 * Code of our application i.e. using framework
 * It's creating the actual TaskFactory and passing
 * it to framework code for action.
 */
 TaskFactory * taskFactory = new SMSTaskFactory();
 someFrameworkCode(taskFactory);

 delete taskFactory;

 return 0;
}

Advantage of using Factory Method Design Pattern:

Frameworks don’t need to use application-specific classes, its code deals with the interfaces of Products only. Therefore it can work with any user-defined Derived / concrete classes.

Disadvantage of using Factory Method Design Pattern:

For every concrete class of Product application needs to provide a Factory class like, although this can be prevented by using templates i.e.

/*
 * Part of Application i.e. using this framework
 */
template <typename T>
class GenericFactory : public TaskFactory
{
public:
  Task * getTaskObject()
  {
   return (new T);
  }
};

int main()
{

 /*
 * Code of our application i.e. using framework
 * It's creating the actual TaskFactory and passing
 * it to framework code for action.
 */

 TaskFactory * taskFactory_generic = new GenericFactory<EMailTask>();
 someFrameworkCode(taskFactory_generic);

 delete taskFactory_generic;
 return 0;
}

Keep looking for more on Design Patterns.

1 thought on “Need of Factory Method Design Pattern in Frameworks Explained”

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top