Abstract Factory Design pattern comes under the creational patterns and it shows many similarities to the Factory Pattern. The abstract factory works as a factory of factories which generates other factories by providing an extra abstraction layer.

The generated factory from an abstract factory pattern always generates the object as per the factory design pattern. In other words, We can also say that the abstract factory is a factory of related objects. In which a common interface is implemented throughout the abstract factory and its factories.

The Abstract Factory is rarely being used in java library, From the XML API, there is one example of DocumentBuilder. Mostly, To create the related objects this pattern is used.

Example of DocumentBuilder in java.

The DocumentBuilderFactory is an abstract factory, a factory that is created as a new instance of DocumentBuilderFactory and the Document is an interface that is implemented by the factory to return the response.

import java.io.ByteArrayInputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;

public class DocumentBuilderExample {
  public static void main(String[] args) throws Exception {
    String testXml = "<note><to>Receiver</to><from>Sender</from><heading>SubjectHeading</heading><body>Body text under the body tag.</body></note>";
    ByteArrayInputStream ba = new ByteArrayInputStream(testXml.getBytes());
    DocumentBuilderFactory absFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder factory = absFactory.newDocumentBuilder();
    Document doc = factory.parse(ba);
    doc.getDocumentElement().normalize();
    System.out.println("Root Node Name is ::: " + doc.getDocumentElement().getNodeName());
    System.out.println("get abstract factory class name is ::: " + absFactory.getClass());
    System.out.println("get abstract factory class name is ::: " + factory.getClass());
  }
}

The reason why DocumentBuilderFactory is because we do not know the logic and where this interface is getting implemented internally, to know this, the sysout code absFactory.getClass() gives the output as class com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl .This shows that object DocumentBuilderFactory is getting implemented by the DocumentBuilderFactoryImpl concrete class from apache xerces.

When to use the abstract factory design pattern.

  • Generate a system that is independent of creating and managing the objects.
  • When to use the collection of the relatable objects.
  • To achieve the uniformity in the object creation methods.
  • Hiding or abstracting the object creation methods and Base code. will be exposed only via the interfaces.
  • To generate a modular system that will separate the functionalitiesStandard class diagram.

Example and Use-case of Abstract Factory Design Pattern.

Now the point is, where can we use the abstract factory and in what situations we should go with this design pattern. Let’s look into the basic practical example to understand this.

Suppose the requirement is to send a newsletter to the users in multiple platforms like through email, or mobile with into the different accounts like official or personal.

So for every condition, we need to create an object for the corresponding platforms and accounts.

By implementing the abstract factory design pattern on the above requirement we will be creating factory objects of email and SMS as per the condition provided. And as per the created factory object, We will create the concrete objects from the factory class.

Client.java – The class shown below is the main class acting as a client, which will pass the condition to send the newsletter.

public class Client {
  public static void main(String[] args) {
    // Can provede sms or email parameter which will be the condition.
    Notificationtype nfType = NotificationFactoryBuilder.getNotificationType("sms");
    // code for push email notification
    // Notification emailnotify = nfType.getEmail("personal");
    // tring notificationResponse = emailnotify.
    //code for sms notification
    Notification smsnotify = nfType.getSMS("office");
    String notificationResponse = smsnotify.pushNotification();
    System.out.println(notificationResponse);
  }
}

NotificationFactoryBuilder.java — Below is the abstract factory class. It is returning the objects of factory classes to the main class as per the condition of email or SMS.

//Abstract factory class
public class NotificationFactoryBuilder {
  public static Notificationtype getNotificationType(String notification) {
    if (notification.equalsIgnoreCase("Email")) {
      return new EmailFactory();
    } else if (notification.equalsIgnoreCase("SMS")) {
      return new SMSFactory();
    }
    return null;
  }
}

EmailFactory.java – Responsible for creating concrete class objects for email communication. For personal or official types of accounts as per the condition provided. This class is acting as a factory class.

//Factory class responsible to generate the concrete classes
public class EmailFactory implements Notificationtype {
  public Notification getEmail(String email) {
    if (email == null) {
      return null; 
  }
   if (email.equalsIgnoreCase("personal")) {
      return new PersonalEmail();
    } else if (email.equalsIgnoreCase("office")) {
      return new OfficeEmail();
    }
    return null;
  }
  public Notification getSMS(String sms) {
    return null;
  }
}

SMSFactory.java — Responsible for creating the concrete class objects for SMS communication. For the personal or official type of account as per the condition provided. This class is acting as a factory class for SMS communications.

public class SMSFactory implements Notificationtype {
  public SMSFactory() {}
  public Notification getSMS(String sms) {
    if (sms == null) {
      return null;
    }
    if (sms.equalsIgnoreCase("personal")) {
      return new PersonalMpbile();
    } else if (sms.equalsIgnoreCase("office")) {
      return new OfficeMpbile();
    }
    return null;
  }
  public Notification getEmail(String str) {
    // TODO Auto-generated method stub
    return null;
  }
}

The code example is also available on GitHub. It consists of the interfaces and other concrete classes that are required to achieve this design pattern. Please share your feedback on this article.

By |Last Updated: May 9th, 2020|Categories: Java™|

Table of Contents