No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Factory

17/26
Recursos

El patron Factory es creacional, se utiliza para ayudar a la creación de nuevas instancias de objetos.

Aportes 36

Preguntas 3

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Con este se evita cambiar cada año el año de los autos del año actual:

<?php 

class Automobile {

    private $vehicleMake;
    private $vehicleModel;

    public function __construct($make, $model) {
        $this->vehicleMake = $make;
        $this->vehicleModel = $model;
    }

    public function getMakeAndModel() {
        return $this->vehicleMake.' - '.$this->vehicleModel;
    }
}


class AutomobileFactory {

    private static $model;

    public static function create($make) {
        self::$model = date('Y');
        return new Automobile($make, self::$model);
    }
}

$renault = new Automobile("Renault", 2019);
$toyota = AutomobileFactory::create("Toyota");


echo $renault->getMakeAndModel().PHP_EOL;
echo $toyota->getMakeAndModel().PHP_EOL;

Factory


Se trata de un patrón creacional, o sea, que nos ayuda a crear nuevas instancias de objetos.

El patrón factory consiste en utilizar una clase constructora abstracta con unos cuantos métodos definidos y otro(s) abstracto(s).

El patrón factory plantea simplificar una instancia, y eso lo podemos hacer por medio de otra clase que se encargue de obtener la instancia haciendo los procesos complejos requeridos, así ante cualquier cambio solo modificamos esa clase factory y no nos preocupamos por modificar cada una de las instancias.

Acá un buen ejemplo de patrón de diseño Factory 😎:

https://www.youtube.com/watch?v=lLvYAzXO7Ek&ab_channel=BettaTech

Nota: es un patrón creacional es decir nos ayuda a la creación de nuevos objetos. El patrón se utiliza cuando la creación del objeto es un proceso muy completo, es decir recibe muchos parámetros o realiza funciones complejas al realización de la creación del objeto, con todo estamos logrando un código un poco más abstracto, reutilizable y sobre todo que podemos cambiar las formas en que creamos los modelos y a través de factoty no nos afectan estos cambios estamos ganando mas logita y la otra cosa que podría afectar es que si cambiamos una clase con el factory no nos afecta.

Este es el codigo de las laminas:

class Automobile
{
    private $vehicleMake;
    private $vehicleModel;

    public function __contruct($make, $model) {
        $this->vehicleMake = $make;
        $this->vehicleModel = $model;
    }

    public function getMakeAndModel() {
        return $this->vehivle.Make.' '.$this->vehicleModel;
    }
}

class AutomobileFactory
{
    private static $model = 2019;

    public static function create($make)
    {
        return new Automobile($make, self::$model);
    }
}

$a = new Automobile('Renault', 2019);
$b = AutomobileFactory::create('Toyota');

Acrode con lo que entendí, implementas una clase que te ayuda a hacer mas facil la creacion de instancias de otras clases.

Pregunta ¿el colocar el año ahí no sería harcoding o en qué casos algo se llama harcoding?

Factory

Tambien llamado: Método fabrica o Constructor virtual

Qué es?

Factory method es un patrón de diseño creacional que resuelve el problema de crear objetos de producto sin especificar sus clases concretas, define un método que debe utilizarse para crear objetos, en lugar de una llamada directa al constructor (operador new). Las subclases pueden sobrescribir este método para cambiar las clases de los objetos que se crearán.

Para que sirve?

Cuando la creación de un objeto es algo muy complejo.

El patrón Factory Method separa el código de construcción de producto del código que hace uso del producto. Por ello, es más fácil extender el código de construcción de producto de forma independiente al resto del código.

Como se logra en código?

  1. Cree la interfaz del producto, esta declara las operaciones que todos los productos deben implementar, esta interfaz deberá declarar métodos que tengan sentido en todos los productos.
interface Product {
    operation(): string;
}
  1. El patrón factory consiste en utilizar una clase constructora abstracta con unos cuantos métodos definidos y otros abstractos.

La responsabilidad de esta clase no es crear productos, por lo general contiene alguna lógica de negocio, las subclases pueden cambiar indirectamente esa lógica.

Añada un patrón Factory Method vacío dentro de la clase creadora.

El tipo de retorno del método deberá coincidir con la interfaz común de los productos.

abstract class Creator {
    
    public abstract factoryMethod(): Product;

    public someOperation(): string {
        // Llame al método de fábrica para crear un objeto Producto.
        const product = this.factoryMethod();
        // Ahora, usa el producto.
        return `Creator: The same creator's code has just worked with ${product.operation()}`;
    }
}
  1. Haga que todos los productos sigan la misma interfaz esto proporciona varias implementaciones de la interfaz del producto
class ConcreteProduct1 implements Product {
    public operation(): string {
        return '{Result of the ConcreteProduct1}';
    }
}

class ConcreteProduct2 implements Product {
    public operation(): string {
        return '{Result of the ConcreteProduct2}';
    }
}
  1. Las subclases anulan el método de fábrica para cambiar el tipo de producto resultante

El método usa el tipo de producto abstracto, aunque el tipo de producto en realidad se devuelve en este método. De esta manera, el Creador puede permanecer independiente de las clases de productos concretas.

class ConcreteCreator1 extends Creator {

    public factoryMethod(): Product {
        return new ConcreteProduct1();
    }
}

class ConcreteCreator2 extends Creator {
    public factoryMethod(): Product {
        return new ConcreteProduct2();
    }
}
  1. El código del cliente funciona con una instancia de un creador concreto, aunque a través de su interfaz base. Siempre que el cliente siga trabajando con el creador a través de la interfaz base, puede pasarla a la subclase de cualquier creador.
function clientCode(creator: Creator) {
    // ...
    console.log('Client: I\'m not aware of the creator\'s class, but it still works.');
    console.log(creator.someOperation());
    // ...
}

La aplicación elige el tipo de creador según la configuración o variables de entorno.

console.log('App: Launched with the ConcreteCreator1.');
clientCode(new ConcreteCreator1());
console.log('');

console.log('App: Launched with the ConcreteCreator2.');
clientCode(new ConcreteCreator2());
  1. La salida de este código seria:
[LOG]: "App: Launched with the ConcreteCreator1." 
[LOG]: "Client: I'm not aware of the creator's class, but it still works." 
[LOG]: "Creator: The same creator's code has just worked with {Result of the ConcreteProduct1}" 
[LOG]: "" 
[LOG]: "App: Launched with the ConcreteCreator2." 
[LOG]: "Client: I'm not aware of the creator's class, but it still works." 
[LOG]: "Creator: The same creator's code has just worked with {Result of the ConcreteProduct2}"

Pros

  • Evitar acoplamiento entre el creador y los productos concretos.
  • Principio de responsabilidad Unica: Se puede mover todo el código de creación de productos a un solo lugar, logrando que el código sea mas fácil de mantener.
  • Principio abierto cerrado: Se pueden agregar o quitar productos sin afectar el código cliente.

Contra

  • Puede hacer que el código se complique ya que se deben incorporar nuevas clases para implementar el patron. Lo ideal seria introducir el patrón en una jerarquia existente de clases creadoras.

En javascript sería algo así…

class Automovil {
    constructor(make, year) {
        this.make = make
        this.year = year
    }
    getAutomovil() {
        return console.log(`This Automovil is make ${this.make} and year ${this.year}`);
    }
}

class AutomovilFactory {
    constructor(make) {
        this.make = make
    }
    create() {
        const year = 2019;
        return console.log(new Automovil(this.make, year));
    }
}

const automovil = new Automovil('Renault', 2018);
automovil.getAutomovil();
const autoRefactory = new AutomovilFactory('Toyota');
autoRefactory.create();

Se podría usar este mismo patrón sin la necesidad de una nueva clase? Es decir agregar la función create dentro de la misma clase Automobile, O no sería recomendable?

Según lo investigado y anotado de otras fuentes, estás son mis notas: El patrón de diseño Factory, también conocido como Factory Method, es un patrón creacional que se utiliza para delegar la lógica de creación de objetos a clases específicas, permitiendo de esta forma flexibilizar y centralizar la creación de objetos en una aplicación. El objetivo principal de este patrón es separar la construcción de objetos de su representación, haciendo que el código sea más modular y fácil de mantener. El patrón Factory se implementa típicamente de la siguiente manera: 1\. \*\*Interfaz de producto\*\*: Define la interfaz de los objetos que el método fábrica creará.2. \*\*Implementaciones concretas del producto\*\*: Estas son clases que implementan la interfaz de producto y definen objetos específicos que serán creados por la fábrica.3. \*\*Creador (o Factory)\*\*: Esta es una clase que declara el método fábrica, el cual retorna objetos de tipo producto. Este método puede ser diseñado como abstracto, obligando a las subclases a definir cómo se crean los objetos, o puede retornar un tipo de producto predeterminado.4. \*\*Creadores concretos\*\*: Son subclases del creador que implementan el método fábrica para crear y retornar productos específicos. El uso del patrón Factory tiene varias ventajas: \- \*\*Flexibilidad\*\*: Los clientes trabajan con interfaces para instancias de objetos, lo que permite cambiar las clases concretas de productos sin cambiar el código que usa los productos.- \*\*Desacoplamiento\*\*: Los clientes no necesitan saber cómo se crean y ensamblan los objetos; solo necesitan saber cómo interactuar con ellos a través de sus interfaces.- \*\*Consolidación del código de creación\*\*: Toda la lógica relacionada con la creación de los objetos se mantiene en un lugar, lo que facilita las actualizaciones y el mantenimiento. El patrón Factory es especialmente útil cuando hay un conjunto complejo de criterios para crear diferentes objetos, lo que puede incluir la elección de la clase de objeto a crear en tiempo de ejecución en base a ciertos parámetros. También es útil cuando el proceso de creación debe estar aislado del código principal para facilitar la futura expansión o mantenimiento sin modificar el código que utiliza los objetos.

como asi que el patron factory no es una cancion de la factoria?

<?php

class Book {
private $info;
private $edition;

public function __construct($info, $edition) {
    $this->info = $info;
    $this->edition = $edition;
}

}

class BookFactory {
private static $edition = ‘2022’;

public static function create($info) {
    return new Book($info, self::$edition);
}

}

$book2 = BookFactory::create(‘book info’);

un poco malo el ejemplo…ni siquiera está formateada ni resaltada la sintaxis y encima usa nombres poco semanticos en algunos casos de este y otros videos ($a, $vel, etc…)

Factory Method es un patrón de diseño creacional que proporciona una interfaz para crear objetos en una superclase, mientras permite a las subclases alterar el tipo de objetos que se crearán.

Muy buen capitulo…

Creo que se relaciona mucho con: Dependency Inversion Principle

Este patrón vendría a ser cuando se hace build de DTOs por ejemplo?

Entonces se puede utilizar un Factory para que este se encargue de proveer las dependencias a la clase a instanciar?

Creo que el patron Factory podría ser útil también para los casos en donde se deban crear objetos utilizados dentro de los unit tests.

Factory, se utiliza para ayudar a creacion de nuevas instancias.
codigo mas abastracto mas utilizable.

Me gusto mucho ese ejemplo

  1. Patron Factory - Creacional
    Ayuda a crear objetos no sobrecargando informacion irrelevante u obvia

Factory = se utiliza para ayudar a la creación de nuevas instancias de objetos.(su objetivo es devolver instancias de una clase en particular por medio de un identificador)

El conocimiento para utilizar patrones de diseño, crea un codigo mas profesional, en esta enlace por si aun no te queda puedes encontrar mas ejemplos de varios patrones de diseño.
https://github.com/kamranahmedse/design-patterns-for-humans

La explicación está bien, pero no taaaaaaaaaaaaan detallado. Les dejo un vídeo donde lo explican con un ejemplo más extendido.
https://www.youtube.com/watch?v=lLvYAzXO7Ek

En conclusión este patrón sirve para crear objetos y sobre todo objetos que heredan de otros asi pudiendo modificarlos como queramos añadiendo diferentes implementaciones de lo mismo…
Un ejemplo
Este sería la clase conocida como Product
interface Vehicule { public funcion SendToDealer() {} }
Este conjunto representa las clases conocida como Concrete Product
class Motorbike { public funcion SendToDealer() {} } class Plane { public funcion SendToDealer() {} } class Car { public funcion SendToDealer() {} }
Creadores de los Concrete Product Conocido como Concrete Creator que implementan una instancia Creator
`class MotorbikeFactory implements VehiculeFactory {
public function makeVehicule() {}
}

class PlaneFactory implements VehiculeFactory {
public function makeVehicule() {}
}

class CarFactory implements VehiculeFactory {
public function makeVehicule() {}
}`

Esta instancia es conocida como el Creator
interface VehiculeFactory { public function makeVehicule() {} }

Perfecta explicación. Gracias

Siento que al explicar los patrones de diseño siempre se busca un ejemplo simple para explicarlo pero se pierde scope de dónde se podría utilizar. Yo al menos entiendo la idea, pero no logro ver un caso real de uso.

Esta seccion de patrones de diseño esta muy buena y he aprendido… pero se me quedan muy cortos estos ejemplos!!! Demasiados básicos

nota importante , para quienes quieran profundizar mas en este tema de patrones de diseño , existen dos tipos factory , el normal osea solo factory y el abstract factory que va mas enfocado en el uso de interfaces

Factory Method: Proporciona una interfaz para crear objetos en una superclase, pero permite que las subclases alteren el tipo de objetos que se crearán. Proporciona instanciación de objetos implícita a través de interfaces comunes.

Ahora entiendo mucho mejor las Factories de Laravel xDDDD