En el artículo anterior hablábamos un poco sobre el concepto de las factorías.

El porque new debe usarse con sabiduría ya que este crea una fuerte dependencia entre nuestros objetos. El código se acopla demasiado cuando no es necesario.

Factory Method

Ahora veamos el patrón que se conoce como factory method. La definición técnica de este patrón es:

Define una interface para crear objetos, pero deja que subclases decidan que clase crear.

Vamos a empezar un código sencillo para ir desglosando la utilidad del patrón.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
interface Document { 
   public void addText(String text); 
}

class PdfDocument implements Document{ 
   public void addText(String text){ 
      System.out.println("Texto en pdf..." + text); 
   } 
}

class XmlDocument implements Document{ 
   public void addText(String text){ 
      System.out.println("Texto en xml..." + text); 
   } 
}

class DocumentCreator { 
   public Document getDocument(String type){ 
      Document doc = null; 
      if(type.equals("pdf")){ 
         doc = new PdfDocument(); 
      }else if (type.equals("xml")){ 
         doc = new XmlDocument(); 
      } return doc; 
   } 
}

class TestDocument{ 
   public static void main(String[] args) { 
      DocumentCreator docCreator = new DocumentCreator(); 
      Document doc = docCreator.getDocument("xml"); 
      doc.addText("Hola mundo"); 
   } 
} 


El ejemplo muestra un cliente TestDocument usando un DocumentCreator y usa el metodo getDocument con el tipo de documento a crear. Este código esta acoplado por el if que pregunta el tipo e instancia la clase adecuada. Si quisiera crear un nuevo tipo digamos HtmlDocument hay que modificar a DocumentCreator.

Vamos a modificar el código para hacerlo mas flexible.

1. Eliminamos el if dentro de DocumentCreator y lo remplazamos(encapsulamos lo que varia) con otro método. En este caso createDocument(), que es abstracto. Hacemos la clase abstracta.

1
2
3
4
5
6
7
8
9
10
 
abstract class DocumentCreator { 
   public Document getDocument(){ 
      Document doc = null; 
      doc = createDocument(); 
      //reemplazamos el if 
      return doc; 
   } 
   protected abstract Document createDocument(); 
} 


2. Ahora creamos clases concretas que extiendan de DocumentCreator para crear documentos concretos.

1
2
3
4
5
6
7
8
9
10
11
class PdfCreator extends DocumentCreator{ 
   protected Document createDocument() { 
      return new PdfDocument(); 
   } 
}

class XmlCreator extends DocumentCreator{
   protected Document createDocument() { 
      return new XmlDocument(); 
   } 
} 


3. Ya estamos listo a usar nuestra clase creadora concreta en el cliente.

1
2
3
4
5
6
7
class TestDocument{ 
   public static void main(String[] args) { 
      DocumentCreator docCreator = new XmlCreator(); 
      Document doc = docCreator.getDocument(); 
      doc.addText("Hola mundo"); 
   } 
} 


Así hemos desacoplado del DocumentCreator la creación de los documentos y se lo hemos dado a clases concretas: PdfCreator y XmlCreator. Este es el objetivo de este patrón que las subclases creadoras, instancien el producto concreto.

Por último dejo una imagen del diseño UML de este patrón y otra del ejemplo para hacer match conceptual.

Factory Method 01

Factory Method 02


Franky Villadiego

Volando hacia el desarrollo productivo!