Fabrica (patrono de designo)

Le **fabrica** (*factory method*) es un patrono de designo creational usate in le programmation orientate a objectos. Illo permitte instantiar objectos del quales le typo es derivate de un typo abstracte. Le classe exacte del objecto non es dunque cognoscite per le appellante.

Plure fabricas pote esser regruppate in un fabrica abstracte permittente instantiar objectos derivante de plure typos abstracte differente.

Como, in general, le fabricas es unic in un programma, on usa sovente le patrono de designo singleton pro implementar los.

## Exemplos
### Base de datos
Nos considera un interfacie de base de datos que supporta numerose typos de campos. Le campos de un tabula es representate per un classe abstracte nominate *Campo*. Cata typo de campo es associate a un subclasse de *Campo*, dante per exemplo: *CampoTexto*, *CampoNumeric*, *CampoData*, o *CampoBoolean*.

Le classe *Campo* possede un methodo *display()* permittente de monstrar le contento de un campo in un interfacie usator. Un objecto de controlo es create pro cata campo, le natura de cata controlo dependente del typo del campo associate: le contento de *CampoTexto* essera monstrate in un campo de entrata texto, lo de *CampoBoolean* essera representate per un cassa a verification (*checkbox*).

Pro resolver iste problema, *Campo* contine un methodo de fabrica nominate *createControl()* e nominate postea *display()* pro crear le objecto adequate.

### Animales
In le exemplo sequente in Java un classe "fabrica" del objectos derivate del classe Animal in function del nomine del animal passate in parametro. Il es equalmente possibile de usar un interfacie como typo de retorno del function.


```java
public class FabricaAnimal 
{
  Animal getAnimal(String typoAnimal) throws ExceptionCreation 
  {
    Animal animal;
    if ("catto".equals(typoAnimal)) 
    {
      animal = new Catto();
    } 
    else if ("can".equals(typoAnimal)) 
    {
      animal = new Can();
    } 
    else 
    {
      throw new ExceptionCreation("Impossibile de crear un " + typoAnimal);
    }
    return animal;
  }
}
```


## Uso
* Le fabricas es usate in le *[[toolkit]]s* o le *[[framework]]s,* a causa que lor classes es sovente derivate per le applicationes que lo usa.
* Hierarchias de classes parallel pote haber besonio de instantiar classes del altere.

## Structura
Le fabrica corresponde al diagramma UML sequente (in francese):

## Altere avantages e variantes
Ben que le principal uso del Fabrica es de instantiar dynamicamente subclasses, illo possede altere avantages que non es ligate a le hereditage del classes. On pote dunque scriber fabricas que non appella al polymorphismo pro crear plure typos de objectos (alora on appella methodos static).

### Nomines descriptive
Le linguages orientate a objectos debe generalmente haber un nomine de constructor identic al nomine del classe, illo pote esser ambigue si il existe plure constructores (per supercargar). Le methodos de fabrication non ha iste obligation e pote haber un nomine que describe melio lor function. In le exemplo sequente, le numeros complexe es create a partir de duo numeros real que pote esser interpretate sia como coordinatas polar, sia como coordinatas cartesian; le uso de methodos de fabrication non lassa alcun ambiguitate:


```java
class Complex 
 {
   public static Complex fromCartesian(double real, double imag) 
   {
     return new Complex(real, imag);
   }

   public static Complex fromPolar(double rho, double theta) 
   {
     return new Complex(rho * cos(theta), rho * sin(theta));
   }

   private Complex(double a, double b) 
   {
     //...
   }
 }

 Complex c = Complex.fromPolar(1, pi); // Identic a fromCartesian(-1, 0)
```


Le constructor del classe es hic private, isto obliga a usar le methodos de fabrication que non da confusion.

### Encapsulation
Le methodos de fabrication permitte de encapsular le creation del objectos. Isto pote esser bon quando le processo de creation es multo complexe, si illo depende per exemplo de files de configuration o de entratas del usator.

Le exemplo in basso presenta un programma que crea icones a partir de files de imagines. Iste programma sape tractar plure formatos de imagines representate cata un per un classe:


```java
public interface ImageReader 
 {
   public DecodedImage getDecodedImage();
 }

 public class GifReader implements ImageReader 
 {
   public GifReader(InputStream in) 
   {
     // Verifica esque illo es un gif, jecta exception si illo non es, si illo es
     // decodifica lo.
   }
     
   public DecodedImage getDecodedImage() 
   {
     return decodedImage;
   }
 }

 public class JpegReader implements ImageReader 
 {
   //...
 }
```


Cata vice que le programma lege un imagine, illo debe crear le lector adaptate a partir de informationes trovate in le file. Iste parte pote esser encapsulate in un methodo de fabrication:


```java
public class ImageReaderFactory
 {
   public static ImageReader getImageReader(InputStream is) 
   {
     int imageType = figureOutImageType(is);
     switch(imageType) 
     {
       case ImageReaderFactory.GIF:
         return new GifReader(is);
       case ImageReaderFactory.JPEG:
         return new JpegReader(is);
       // etc.
     }
   }
 }
```


Le typo de imagine e le lector correspondente pote hic esser immagazinate in un vector associative, isto evita le structura *switch* e da un fabrica facilemente extensibile.

## Vide etiam
* Fabrica abstracte
* Montator
* Patrono de methodo

## Ligamines externe

*  Factory Method Pattern