Abstract Factory Pattern

SHARE & COMMENT :

What is Abstract Factory Pattern?

Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

Wikipedia says:
A software design pattern, the Abstract Factory Pattern provides a way to encapsulate a group of individual factories that have a common theme.

also read:

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

Motto: Hence depend on abstractions and not on concrete classes.Intent of Abstract Factory is to create families of related objects without having to depend on their concrete classes.A Simple Abstract Factory is a way to decouple our clients from concrete classes.Abstract Factory relies on Object Composition.Object creation is implemented in methods exposed in the factory interface.[GoF,162]

Purpose:
To create a contract for creating families of related or dependent objects without having to specify their concrete classes.

Introduction:
Suppose we plan to manage address and telephone information in our application(Example Personal Informational manager) system.We will initially produce classes to represent Address and Telephone number data.Code these classes so that they store the relavent information and enforce business rules about their format.Ex: In few indian cities all telephone numbers are limited to 7 digits.Shortly we get another requirement to manage this application for another city/country.So we modify our logic in the Address and PhoneNumber to satisfy rules for another city/country and all of a sudden after managing for many countries sees our classes get bloated with code and difficult to manage. With every country added, we need to modify and recompile the classes to manage contact information.

It’s better to flexibly add these paired classes to the system;to take the general rules that apply to address and phone number data,and allow any number of possible foreign variations to be “loaded” into a system.

The abstract factory solves this problem.Using this pattern,you define an AddressFactory- a generic framework for producing objects that follow the general pattern for an Address and PhoneNumber.At runtime,this factory is paired with any number of concrete factories for different countries,and each country has its own version of Address and PhoneNumber classes.

Instead of going through nightmare of adding functional logic to the classes,extend the Address to USAddress and PhoneNumber to USPhoneNumber for country US.Instances of both classes are created by USAddressFactory.This gives greater freedom to extend your code without having to make major structural modifications in the rest of the system.

Applicability:
Use the Abstract Factory Pattern when:

  • The client should be independent of how the products are created.
  • Application should be configured with one of multiple families of products.
  • Objects needs to be created as a set,in order to be compatible.
  • You want to provide a collection of classes and you want to reveal just their contracts and their relationships,not their implementations.

Description:
During runtime,ConcreteFactories and ConcreteProducts are created and used by the application.The concrete classes conform to the contract defined by the AbstractFactory and AbstractProducts so the concrete classes can be directly used,without being recoded or recompiled.

We typically use the following to implement the Abstract Factory Pattern:

  • AbstractFactory – An abstract class or interface that defines the create methods for abstract products.
  • AbstractProduct – An abstract class or interface that describing the general behavior of the resource that will be used by the application.
  • ConcreteFactory – A class derived from the abstract factory.It implements create methods for one or more concrete products.
  • ConcreteProduct – A class derived from the abstract product,providing an implementation for a specific resource or operating environment.

Benefits and Drawbacks

Abstract Factory helps to increase the overall flexibility of the application.Flexibility manifests itself both during runtime and design time.During design we donot have to predict all future uses of this application.Instead we create a generic framework,and develop implementations independently from the rest of the application.At runtime,application can easily integrate new features and resources.

A further benefit of this pattern is it simplifies testing the rest of the application.

As discussed,we can define the AbstractFactory and AbstractProduct as an interface or an abstract class depending on the needs of the application and your preference.

Depending on how the factory is to be used,some variations of this pattern allow multiple ConcreteFactory objects to be produced,resulting in an application that can simultaneously use multiple families of ConcreteProducts.

Related Patterns

  • Factory Method – Used to implement Abstract Factory.
  • Singleton – Often Used in Concrete Factory.
  • Data Access Object – The Data Access Object pattern can use the Abstract Factory Pattern to add flexibility in creating Database-specific factories.

Implementation Issues

How many instances of a particular concrete factory should there be?

  • An application typically only needs a single instance of a particular concrete factory
  • Use the Singleton pattern for this purpose

Below example describes implementation of Abstract Factory.


package patterns;

interface AddressFactory {

 public Address createAddress();
 public PhoneNumber createPhoneNumber();
}

abstract class Address {
 private String street;
 private String city;
 private String region;
 private String postalCode;

 public static final String EOL_STRING =System.getProperty("line.separator");
 public static final String SPACE = " ";

 public String getStreet() {
  return street;
 }
 public String getCity() {
  return city;
 }
 public String getPostalCode() {
  return postalCode;
 }
 public String getRegion() {
  return region;
 }
 public abstract String getCountry();

 public String getFullAddress() {
  return street + EOL_STRING + city + SPACE + postalCode + EOL_STRING;
 }
}

abstract class PhoneNumber {
 private String phoneNumber;
 abstract String getCountryCode();

 public String getPhoneNumber() {
  return phoneNumber;
 }
 public void setPhoneNumber(String phoneNumber) {
  this.phoneNumber = phoneNumber;
 }
}

class USAddressFactory implements AddressFactory{
 public Address createAddress(){
  return new USAddress();
 }

 public PhoneNumber createPhoneNumber(){
  return new USPhoneNumber();
 }
}

class USAddress extends Address{
 private static final String COUNTRY = "UNITED STATES";
 private static final String COMMA = ",";

 public String getCountry(){ return COUNTRY; }

 public String getFullAddress(){
  return getStreet() + EOL_STRING +
  getCity() + COMMA + SPACE + getRegion() +
  SPACE + getPostalCode() + EOL_STRING +
  COUNTRY + EOL_STRING;
 }
}

class USPhoneNumber extends PhoneNumber{
 private static final String COUNTRY_CODE = "01";
 private static final int NUMBER_LENGTH = 10;

 public String getCountryCode(){ return COUNTRY_CODE; }

 public void setPhoneNumber(String newNumber){
  if (newNumber.length() == NUMBER_LENGTH){
   super.setPhoneNumber(newNumber);
  }
 }
}

class FrenchAddressFactory implements AddressFactory{
 public Address createAddress(){
  return new FrenchAddress();
 }

 public PhoneNumber createPhoneNumber(){
  return new FrenchPhoneNumber();
 }
}

class FrenchAddress extends Address{
 private static final String COUNTRY = "FRANCE";

 public String getCountry(){ return COUNTRY; }

 public String getFullAddress(){
  return getStreet() + EOL_STRING + getPostalCode() + SPACE + getCity() + EOL_STRING + COUNTRY + EOL_STRING;
 }
}

class FrenchPhoneNumber extends PhoneNumber{
 private static final String COUNTRY_CODE = "33";
 private static final int NUMBER_LENGTH = 9;

 public String getCountryCode(){ return COUNTRY_CODE; }

 public void setPhoneNumber(String newNumber){
  if (newNumber.length() == NUMBER_LENGTH){
   super.setPhoneNumber(newNumber);
  }
 }
}

public class AbstractFactoryPattern {

 public static void main(String[] args) {
  Address fd=new FrenchAddressFactory().createAddress();
  System.out.println("French Address:" + fd.getFullAddress());
 }
}

Comments

comments

About Krishna Srinivasan

He is Founder and Chief Editor of JavaBeat. He has more than 8+ years of experience on developing Web applications. He writes about Spring, DOJO, JSF, Hibernate and many other emerging technologies in this blog.

Trackbacks

  1. […] Abstract Factory Pattern […]

  2. […] Abstract Factory : Allows you to draw an interface for creating families of related objects or interdependent, not specifying their concrete classes. These standards can be created using concrete factories, which are responsible for the creation of new objects to meet customer needs. Therefore, this practice helps to exclude the dependency between the client and the class of objects used by the client. […]

Speak Your Mind

*

Close
Please support the site
By clicking any of these buttons you help our site to get better