---
title: "Comparación de factorías"
type: "design-pattern"
slug: "factory-comparison"
url: "http://localhost:3000/es/design-patterns/factory-comparison.md"
---
# Comparación de factorías

Este artículo mostrará la diferencia entre:

1. Factoría
2. Método de creación
3. Método de creación (o de factoría) estático
4. Factoría simple
5. El patrón [Factory Method](/es/design-patterns/factory-method)
6. El patrón [Abstract Factory](/es/design-patterns/abstract-factory)

Puedes encontrar referencias a estos términos por toda la web. Aunque puedan parecer similares, todos tienen significados diferentes. Mucha gente no se da cuenta de ello, lo que genera confusión y malentendidos.

Así que intentemos descifrar la diferencia y resolver este problema de una vez por todas.

## 1\. Factoría

El término **factoría** es ambiguo: designa una función, un método o una clase que se supone que produce algo. Lo más habitual es que las factorías produzcan objetos. Pero también pueden producir archivos, registros en bases de datos, etc.

Por ejemplo, cualquiera de estas cosas podría llamarse informalmente «factoría»:

* una función o método que crea la GUI de un programa;
* una clase que crea usuarios;
* un método estático que llama al constructor de una clase de una determinada manera;
* uno de los patrones de diseño creacionales.

Normalmente, cuando alguien dice la palabra «factoría», se supone que el significado exacto queda claro por el contexto. Pero si tienes dudas, simplemente pregunta. Existe la posibilidad de que el propio autor no lo sepa.

## 2\. Método de creación

El **método de creación** se define en el libro [Refactoring To Patterns](https://refactoring.guru/ref-to-patterns-book) como «un método que crea objetos». Esto significa que todo resultado del patrón Factory Method es un «método de creación», pero no necesariamente a la inversa. También significa que puedes sustituir el término «método de creación» allí donde Martin Fowler emplea el término «factory method» en [Refactoring](https://refactoring.guru/ref-book) y allí donde Joshua Bloch emplea el término «static factory method» en [Effective Java](https://refactoring.guru/effective-java-book).

En realidad, el método de creación no es más que una envoltura alrededor de una llamada al constructor. Puede que simplemente tenga un nombre que exprese mejor tus intenciones. Por otro lado, puede ayudar a aislar tu código de los cambios en el constructor. Incluso podría contener cierta lógica que devolviera objetos existentes en lugar de crear nuevos.

Mucha gente llamaría a esos métodos «factory method» solo porque producen objetos nuevos: la lógica es sencilla: el método crea objetos y, dado que todas las _factorías_ crean objetos, este método debería ser claramente un _factory method_. Naturalmente, hay mucha confusión cuando se trata del verdadero patrón [Factory Method](/es/design-patterns/factory-method).

En el siguiente ejemplo, `next` es un método de creación:

class Number {
    private $value;

    public function __construct($value) {
        $this->value = $value;
    }

    public function next() {
        return new Number ($this->value + 1);
    }
}

## 3\. Método de creación estático

Un **método de creación estático** es un método de creación declarado como `static`. En otras palabras, se puede invocar sobre una clase y no requiere que se haya creado un objeto.

No te confundas cuando alguien llame a métodos como este «static factory method». No es más que una mala costumbre. El patrón [Factory Method](/es/design-patterns/factory-method) es un patrón de diseño que se basa en la herencia. Si lo haces `static`, ya no podrás extenderlo en subclases, lo que echa por tierra el propósito del patrón.

Cuando un método de creación estático devuelve objetos nuevos, se convierte en un constructor alternativo.

Puede resultar útil cuando:

* Necesitas tener varios constructores distintos con propósitos diferentes pero cuyas firmas coinciden. Por ejemplo, tener a la vez `Random(int max)` y `Random(int min)` es imposible en Java, C++, C# y muchos otros lenguajes. Y la solución más popular es crear varios métodos estáticos que llamen al constructor por defecto y asignen después los valores adecuados.
* Quieres reutilizar objetos existentes en lugar de instanciar otros nuevos (consulta el patrón [Singleton](/es/design-patterns/singleton)). En la mayoría de los lenguajes de programación, los constructores tienen que devolver instancias nuevas de la clase. El método de creación estático es una solución alternativa a esta limitación. Dentro de un método estático, tu código puede decidir si crear una instancia nueva llamando al constructor o devolver un objeto existente desde alguna caché.

En el siguiente ejemplo, el método `load` es un método de creación estático. Proporciona una forma cómoda de recuperar usuarios de una base de datos.

class User {
    private $id, $name, $email, $phone;

    public function __construct($id, $name, $email, $phone) {
        $this->id = $id;
        $this->name = $name;
        $this->email = $email;
        $this->phone = $phone;
    }

    public static function load($id) {
        list($id, $name, $email, $phone) = DB::load_data('users', 'id', 'name', 'email', 'phone');
        $user = new User($id, $name, $email, $phone);
        return $user;
    }
}

## 4\. El patrón _factoría simple_

El patrón de **factoría simple** Definido en el libro [Head First Design Patterns](https://refactoring.guru/head-first-book). describe una clase que tiene un único método de creación con un gran condicional que, según los parámetros del método, elige qué clase de producto instanciar y luego devolverla.

La gente suele confundir las _factorías simples_ con las _factorías_ en general o con alguno de los patrones de diseño creacionales. En la mayoría de los casos, una factoría simple es un paso intermedio para introducir los patrones [Factory Method](/es/design-patterns/factory-method) o [Abstract Factory](/es/design-patterns/abstract-factory).

Una factoría simple suele estar representada por un único método dentro de una única clase. Con el tiempo, este método puede volverse demasiado grande, así que podrías decidir extraer partes del método a subclases. Una vez que lo hagas varias veces, podrías descubrir que todo el conjunto se ha convertido en el clásico patrón _factory method_.

Por cierto, si declaras una factoría simple como `abstract`, no se convierte mágicamente en el patrón _abstract factory_.

Aquí tienes un ejemplo de _factoría simple_:

class UserFactory {
    public static function create($type) {
        switch ($type) {
            case 'user': return new User();
            case 'customer': return new Customer();
            case 'admin': return new Admin();
            default:
                throw new Exception('Wrong user type passed.');
        }
    }
}

## 5\. El patrón _Factory Method_

El patrón **Factory Method** Definido en el libro de la GoF [Design Patterns: Elements of Reusable Object-Oriented Software](https://refactoring.guru/gof-book). es un patrón de diseño creacional que proporciona una interfaz para crear objetos, pero permite que las subclases alteren el tipo de objeto que se creará.

Si tienes un método de creación en una clase base y subclases que la extienden, puede que estés ante el patrón factory method.

abstract class Department {
    public abstract function createEmployee($id);

    public function fire($id) {
        $employee = $this->createEmployee($id);
        $employee->paySalary();
        $employee->dismiss();
    }
}

class ITDepartment extends Department {
    public function createEmployee($id) {
        return new Programmer($id);
    }
}

class AccountingDepartment extends Department {
    public function createEmployee($id) {
        return new Accountant($id);
    }
}

## 6\. El patrón _Abstract Factory_

El patrón **Abstract Factory** También definido en el [libro de la GoF](https://refactoring.guru/gof-book). es un patrón de diseño creacional que permite producir familias de objetos relacionados o dependientes sin especificar sus clases concretas.

¿Qué son las «familias de objetos»? Por ejemplo, tomemos este conjunto de clases: `Transport` \+ `Engine` \+ `Controls`. Podría haber varias variantes de estas:

1. `Car` \+ `CombustionEngine` \+ `SteeringWheel`
2. `Plane` \+ `JetEngine` \+ `Yoke`

Si tu programa no trabaja con familias de productos, entonces no necesitas una abstract factory.

Y, una vez más, mucha gente confunde el patrón _abstract factory_ con una clase de factoría simple declarada como `abstract`. ¡No hagas eso!

### Epílogo

Ahora que conoces la diferencia, echa un nuevo vistazo a los patrones de diseño:

* [Factory Method](/es/design-patterns/factory-method)
* [Abstract Factory](/es/design-patterns/abstract-factory)
