Patrón Factory Method — demo visual

¿Qué es Factory Method?

creación

Factory Method define un método (la “fábrica”) para crear objetos, pero deja a las subclases decidir qué clase concreta instanciar. El cliente trabaja contra la interfaz Product, sin conocer ConcreteProduct.

Diagrama: flujo del Factory Method

Client usa Creator, y el Creator crea un Product (A o B)
Creator: A idle

Demo (Factory Method)

createProduct()

Cambia el Creator (A o B). Luego ejecuta someOperation() y mira qué Product creó.

Producto creado

Ejemplo del patrón (Factory Method)

código

Creator define <b>factoryMethod()</b> y decide qué <b>Product</b> instanciar.

// factory-method.ts

// Product
interface Product {
  operation(): string;
}

class ConcreteProductA implements Product {
  operation() {
    return "ConcreteProductA";
  }
}

class ConcreteProductB implements Product {
  operation() {
    return "ConcreteProductB";
  }
}

// Creator
abstract class Creator {
  // Factory Method
  protected abstract factoryMethod(): Product;

  // Logic that uses the product
  public someOperation(): string {
    const product = this.factoryMethod();
    return "Creator uses " + product.operation();
  }
}

class ConcreteCreatorA extends Creator {
  protected factoryMethod(): Product {
    return new ConcreteProductA();
  }
}

class ConcreteCreatorB extends Creator {
  protected factoryMethod(): Product {
    return new ConcreteProductB();
  }
}

// Client
function clientCode(creator: Creator) {
  console.log(creator.someOperation());
}

clientCode(new ConcreteCreatorA());
clientCode(new ConcreteCreatorB());
// factory-method.js

class ProductA {
  operation() {
    return "ProductA";
  }
}

class ProductB {
  operation() {
    return "ProductB";
  }
}

class CreatorA {
  factoryMethod() {
    return new ProductA();
  }

  someOperation() {
    const product = this.factoryMethod();
    return "Creator uses " + product.operation();
  }
}

class CreatorB {
  factoryMethod() {
    return new ProductB();
  }

  someOperation() {
    const product = this.factoryMethod();
    return "Creator uses " + product.operation();
  }
}

function clientCode(creator) {
  console.log(creator.someOperation());
}

clientCode(new CreatorA());
clientCode(new CreatorB());
La idea: el <code>Client</code> llama <code>someOperation()</code> y el <code>Creator</code> crea el <code>Product</code> (A o B) sin condicionar al cliente.