Abstract Factory

Abstract Factory is a design pattern for software development . Provides an interface to create families of related or dependent objects between them without specifying a specific class.

Summary

[ hide ]

  • 1 Context and problem
  • 2 Static appearance
  • 3 Typical structure
  • 4 An example
  • 5 See also
  • 6 External links
  • 7 Sources

Context and problem

Context: We must create different objects, all belonging to the same family. For example: the libraries to create graphical interfaces usually use this pattern and each family would be a different operating system. So, the user declares a Button, but more internally what he is creating is a Windows Button or a Linux Button, for example.

The problem this pattern is trying to solve is creating different families of objects.

The Abstract Factory pattern is recommended when the inclusion of new product families is foreseen, but it can be counterproductive when new products are added or existing ones are changed, since it would affect all the families created.

Static appearance

Typical structure

  • Customer: The class that will call the appropriate factory since it needs to create one of the objects that the factory provides, that is, Customer wants to obtain an instance of one of the products (ProductA, ProductB).
  • AbstractFactory: It is a definition of the factory interfaces. You must provide a method for obtaining each object you can create. (“createProductA ()” and “createProductB ()”)
  • Concrete factories: These are the different families of products. It provides the specific instance of which it is in charge of creating. In this way we can have a factory that creates the graphic elements for Windows and another that creates them for Linux , being able to easily put (creating a new one) another one that creates them for MacOS , for example.
  • Abstract product: Definition of the interfaces for the generic product family . In the diagram they are “ProductA” and “ProductB”. In an example of graphic interfaces, it could be all the elements: Button , Window , Text Box , Combo … The client will work directly on this interface, which will be implemented by the different specific products.
  • Concrete product: Implementation of the different products. It could be for example “ButtonWindows” and “ButtonLinux”. As both implement “Button” the client will not know if it is on Windows or Linux, since it will work directly on the superclass or interface.

An example

To show the concept of the Abstract Factory we are going to make a simple clock that shows us the current time. As we know, the time can be displayed in 24Hrs format or it can be displayed in AM / PM format. Remembering that it is by way of example, we are going to use the Date class in a way that it should not, and probably the clock would do it in a simpler way, but for our example its use is perfect. As in the case of the dictionary, we will make an abstract Clock class and two implementations for each of the formats, and a class that contains the Factory Method method. The thing would look something like this:

The Clock class:

 

public  abstract  class  Clock  {

 

abstract  String  dameLaHora ();

}

The class that is given the time in AM / PM format:

 

public  class  ClockAmPm  extends  Clock {

 

public  ClockAmPm () {

 

}

 

public  String  dameLaHora ()  {

Date  d  =  new  Date ();

int  hour  =  d . getHours ();

int  minutes  =  d . getMinutes ();

int  seconds  =  d . getSeconds ();

String  tr ;

if  ( time & lt ; = 12 ) {

tr = “Are” + Time + “:” + min +”:” + seconds + “AM” ;

}  else  {

tr = “They are the” + ( hour – 12 ) + “:” + minutes + “:” + seconds + “PM” ;

}

 

return  tr ;

}

 

}

The one that gives us the time in 24-hour format:

 

public  class  Clock24Hrs  extends  Clock  {

 

public  String  dameLaHora ()  {

Date  d  =  new  Date ();

int  hour  =  d . getHours ();

int  minutes  =  d . getMinutes ();

int  seconds  =  d . getSeconds ();

String  tr ;

tr  =  “It is the”  +  hour  +  “:”  +  minutes  +  “:”  +  seconds  +  “” ;

 

return  tr ;

}

}

Our class that contains the method that the instances choose. Unlike the previous post, the parameter that the method receives is now an integer, which accepts the integers specified as static constants in the class. This is used a lot to avoid guessing the parameters that the method accepts:

 

public  class  ClockFactory  {

public  static  final  int  CLOCK_AM_PM = 0 ;

public  static  final  int  CLOCK_24_HRS = 1 ;

 

public  ClockFactory () {

 

}

 

public  static  Clock  createReloj ( int  tipoDeReloj ) {

if  ( tipoDeReloj == RelojFactory . RELOJ_24_HRS ) {

return  new  Reloj24Hrs ();

}

if  ( clockType == ClockFactory . CLOCK_AM_PM ) {

return  new  ClockAmPm ();

}

 

return  null ;

}

 

}

And finally the client class, which will be the end user:

 

public  class  MainClient  {

 

public  static  void  main ( String []  args )  {

Clock  r  =  ClockFactory . createReloj ( RelojFactory . CLOCK_24_HRS );

System . out . println ( r . dameLaHora ());

}

}

Up to here we have two factories: one of words, and the one that we have just made that gives us the time.

 

Leave a Comment