No tienes acceso a esta clase

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

Abstract Factory: pros y contras

16/27
Recursos

Aportes 28

Preguntas 4

Ordenar por:

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

Les dejo mi codigo en TypeScript por si les es de ayuda:

// declaramos interfaces por cada producto base
interface Cpu {
  setSeries(series: string): void;
}

interface Memory {
  setCapacityInGb(gb: number): void;
}

interface Display {
  setResolution(): void;
}

// declaramos class por cada producto en concreto
class PhoneCpu implements Cpu {
  setSeries(series: string): void {
    console.log(`Phone ${series}`);
  }
}

class LaptopCpu implements Cpu {
  setSeries(series: string): void {
    console.log(`Laptop ${series}`);
  }
}

class TabletCpu implements Cpu {
  setSeries(series: string): void {
    console.log(`Tablet ${series}`);
  }
}

class PhoneMemory implements Memory {
  setCapacityInGb(gb: number): void {
    console.log(`Phone ${gb}gb`);
  }
}

class LaptopMemory implements Memory {
  setCapacityInGb(gb: number): void {
    console.log(`Laptop ${gb}gb`);
  }
}

class TabletMemory implements Memory {
  setCapacityInGb(gb: number): void {
    console.log(`Tablet ${gb}gb`);
  }
}

class PhoneDisplay implements Display {
  setResolution(): void {
    console.log("Phone resolution...");
  }
}

class LaptopDisplay implements Display {
  setResolution(): void {
    console.log("Laptop resolution...");
  }
}

class TabletDisplay implements Display {
  setResolution(): void {
    console.log("Tablet resolution...");
  }
}

// declaramos interface para abstract factory
interface AFactory {
  createCpu(): Cpu;
  createMemory(): Memory;
  createDisplay(): Display;
}

// declaramos class para fabricas concretas de productos
class PhoneFactory implements AFactory {
  createCpu(): Cpu {
    return new PhoneCpu();
  }
  createMemory(): Memory {
    return new PhoneMemory();
  }
  createDisplay(): Display {
    return new PhoneDisplay();
  }
}

class LaptopFactory implements AFactory {
  createCpu(): Cpu {
    return new LaptopCpu();
  }
  createMemory(): Memory {
    return new LaptopMemory();
  }
  createDisplay(): Display {
    return new LaptopDisplay();
  }
}

class TabletFactory implements AFactory {
  createCpu(): Cpu {
    return new TabletCpu();
  }
  createMemory(): Memory {
    return new TabletMemory();
  }
  createDisplay(): Display {
    return new TabletDisplay();
  }
}

// funciones de implementacion
const appFactoryNew = (factory: AFactory) => {
  const cpu = factory.createCpu();
  const memory = factory.createMemory();
  const display = factory.createDisplay();

  cpu.setSeries("i5");
  memory.setCapacityInGb(512);
  display.setResolution();
};

type FactoryTypeNew = "phone" | "laptop" | "tablet";

const createFactoryNew = (type: FactoryTypeNew) => {
  const factories = { phone: PhoneFactory, laptop: LaptopFactory, tablet: TabletFactory };
  const Factory = factories[type];
  return new Factory();
};

appFactoryNew(createFactoryNew("phone"));
appFactoryNew(createFactoryNew("laptop"));
appFactoryNew(createFactoryNew("tablet"));

Les comparto mi codigo

// Paso 1
interface CPU {
    setSeries(serie: string): void
}

interface Memory {
    setCapacityInGB(capacity: number): void
}

interface Display {
    setResolution(resolution: '1920' | '720' | '480'): void
}

// Paso 2
// CPU
// Phone
class CPUPhone implements CPU {
    serie: string

    public setSeries(serie: string): void {
        this.serie = serie
    }
}

// Laptop
class CPULaptop implements CPU {
    serie: string

    public setSeries(serie: string): void {
        this.serie = serie
    }
}

// Tablet
class CPUTablet implements CPU {
    serie: string

    public setSeries(serie: string): void {
        this.serie = serie
    }
}

// Memory
// Phone
class MemoryPhone implements Memory {
    capacityInGB: number

    public setCapacityInGB(capacity: number): void {
        this.capacityInGB = capacity
    }
}

// Laptop
class MemoryLaptop implements Memory {
    capacityInGB: number

    public setCapacityInGB(capacity: number): void {
        this.capacityInGB = capacity
    }
}

// Tablet
class MemoryTablet implements Memory {
    capacityInGB: number

    public setCapacityInGB(capacity: number): void {
        this.capacityInGB = capacity
    }
}

// Display
// Phone
class DisplayPhone implements Display {
    resolution: string

    public setResolution(resolution: "1920" | "720" | "480"): void {
        this.resolution = resolution
    }
}

// Laptop
class DisplayLaptop implements Display {
    resolution: string

    public setResolution(resolution: "1920" | "720" | "480"): void {
        this.resolution = resolution
    }
}

// Tablet
class DisplayTablet implements Display {
    resolution: string

    public setResolution(resolution: "1920" | "720" | "480"): void {
        this.resolution = resolution
    }
}

// Paso 3
interface ComponentAbstractFactory {
    createCPU(): CPU
    createMemory(): Memory
    createDisplay(): Display
}

// Paso 4
// Phone
class PhoneFactory implements ComponentAbstractFactory {
    public createCPU(): CPU {
        return new CPUPhone()
    }

    public createDisplay(): Display {
        return new DisplayPhone()
    }

    public createMemory(): Memory {
        return new MemoryPhone()
    }
}

// Laptop
class LaptopFactory implements ComponentAbstractFactory {
    public createCPU(): CPU {
        return new CPULaptop()
    }

    public createDisplay(): Display {
        return new DisplayLaptop()
    }

    public createMemory(): Memory {
        return new MemoryLaptop()
    }
}

// Tablet
class TabletFactory implements ComponentAbstractFactory {
    public createCPU(): CPU {
        return new CPUTablet()
    }

    public createDisplay(): Display {
        return new DisplayTablet()
    }

    public createMemory(): Memory {
        return new MemoryTablet()
    }
}

function appAbstractFactory(factory: ComponentAbstractFactory): void {
    const cpu = factory.createCPU()
    const memory = factory.createMemory()
    const display = factory.createDisplay()
}

function createFactory(type: 'phone' | 'laptop' | 'tablet'): ComponentAbstractFactory {
    const factories = {
        phone: PhoneFactory,
        laptop: LaptopFactory,
        tablet: TabletFactory
    }

    const Factory = new factories[type]
    return Factory
}

appAbstractFactory(createFactory('phone'))
appAbstractFactory(createFactory('laptop'))
appAbstractFactory(createFactory('tablet'))


// BASE PRODUCTS
interface CPUBase {
    setSeries(_series: string): void
}

interface MemoryBase {
    setCapacityInGB(_gbs: number): void
}

interface DisplayBase {
    setResolution(): void
}


// CONCRETE PRODUCTS
class CPU implements CPUBase {
    setSeries(_series: string): void {
        console.log(`CPU: ${_series}`)
    }
}

class Memory implements MemoryBase {
    setCapacityInGB(_gbs: number): void {
        console.log(`Memory: ${_gbs} Gigabytes`)
    }
}

class Display implements DisplayBase {
    setResolution(): void {
        console.log(`FHD`)
    }
}

// CREATION FOR EACH BASE PRODUCT
interface ProductsAbstractFactory {
    createCPU(): CPUBase
    createMemory(): MemoryBase
    createDisplay(): DisplayBase
}


// CONCRETE FACTORIES
class PhoneDeviceFactory implements ProductsAbstractFactory {
    createCPU(): CPUBase {
        return new CPU()
    }

    createMemory(): MemoryBase {
        return new Memory()
    }

    createDisplay(): DisplayBase {
        return new Display()
    }

}

class LaptopDeviceFactory implements ProductsAbstractFactory {
    createCPU(): CPUBase {
        return new CPU()
    }

    createMemory(): MemoryBase {
        return new Memory()
    }

    createDisplay(): DisplayBase {
        return new Display()
    }

}

class TabletDeviceFactory implements ProductsAbstractFactory {
    createCPU(): CPUBase {
        return new CPU()
    }

    createMemory(): MemoryBase {
        return new Memory()
    }

    createDisplay(): DisplayBase {
        return new Display()
    }

}

// APP EJECUTION
const appDevicesFactory = (factory: ProductsAbstractFactory) => {

    const cpu = factory.createCPU()
    const memory = factory.createMemory()
    const display = factory.createDisplay()

    cpu.setSeries('[CPU]')
    memory.setCapacityInGB(1000)
    display.setResolution()
}


type FactoryType = 'phone' | 'laptop' | 'tablet'
type FactoriesTypes = {
    phone: typeof PhoneDeviceFactory;
    laptop: typeof LaptopDeviceFactory;
    tablet: typeof TabletDeviceFactory
}

const createFactory = (type: FactoryType): ProductsAbstractFactory => {
    const factories: FactoriesTypes = {
        phone: PhoneDeviceFactory,
        laptop: LaptopDeviceFactory,
        tablet: TabletDeviceFactory
    }

    const Factory = factories[type]
    return new Factory()
}

appDevicesFactory(createFactory('phone'))
appDevicesFactory(createFactory('tablet'))
appDevicesFactory(createFactory('laptop')) 

Mi solución al reto:

// STEP 1
interface Cpu {
    setSeries(serie: string): void;
}

interface Memory {
    setCapacityInGB(gigaBytes: number): void;
}

interface Display {
    setResolution(): void;
}

// STEP 2
class PhoneCpu implements Cpu {
    public setSeries(serie: string): void {
        console.log(`The CPU of the phone is from the ${serie} series`);
    }
}
class LaptopCpu implements Cpu {
    public setSeries(serie: string): void {
        console.log(`The CPU of the laptop is from the ${serie} series`);
    }
}
class TabletCpu implements Cpu {
    public setSeries(serie: string): void {
        console.log(`The CPU of the tablet is from the ${serie} series`);
    }
}

class PhoneMemory implements Memory {
    public setCapacityInGB(gigaBytes: number): void {
        console.log(`The memory of the phone is ${gigaBytes}GB`);
    }
}
class LaptopMemory implements Memory {
    public setCapacityInGB(gigaBytes: number): void {
        console.log(`The memory of the laptop is ${gigaBytes}GB`);
    }
}
class TabletMemory implements Memory {
    public setCapacityInGB(gigaBytes: number): void {
        console.log(`The memory of the tablet is ${gigaBytes}GB`);
    }
}

class PhoneDisplay implements Display {
    public setResolution(): void {
        console.log(`The phone display is small`);
    }
}
class LaptopDisplay implements Display {
    public setResolution(): void {
        console.log(`The laptop display is big`);
    }
}
class TabletDisplay implements Display {
    public setResolution(): void {
        console.log(`The tablet display is medium`);
    }
}

// STEP 3
interface DevicesAbstractFactory {
    createCpu(): Cpu;
    createMemory(): Memory;
    createDisplay(): Display;
}

// STEP 4
class PhoneFactory implements DevicesAbstractFactory {
    createCpu(): Cpu {
        return new PhoneCpu();
    }
    createMemory(): Memory {
        return new PhoneMemory();
    }
    createDisplay(): Display {
        return new PhoneDisplay();
    }
}
class TabletFactory implements DevicesAbstractFactory {
    createCpu(): Cpu {
        return new TabletCpu();
    }
    createMemory(): Memory {
        return new TabletMemory();
    }
    createDisplay(): Display {
        return new TabletDisplay();
    }
}
class LaptopFactory implements DevicesAbstractFactory {
    createCpu(): Cpu {
        return new LaptopCpu();
    }
    createMemory(): Memory {
        return new LaptopMemory();
    }
    createDisplay(): Display {
        return new LaptopDisplay();
    }
}

function appDeviceFactory(factory: DevicesAbstractFactory) {
    const cpu: Cpu = factory.createCpu();
    const memory: Memory = factory.createMemory();
    const display: Display = factory.createDisplay();

    cpu.setSeries('X');
    memory.setCapacityInGB(128);
    display.setResolution();
}

appDeviceFactory(new LaptopFactory());
appDeviceFactory(new PhoneFactory());
appDeviceFactory(new TabletFactory());

Me di cuenta que en la mayoria de estudiantes que publicaron su codigo lo hicieron de una forma que siempre cuando se instancie alguna familia siempre le seteara los mismos valores, asi que modifique el ejercicio un poco, usando constructores para que quede dinamico y poder crear cada familia con sus valores correspondientes

// STEP 1
interface CPU {
    getSeries(): string
}

interface Memory{
    getCapacityInGB(): void;
}

interface Display{
    getResolution():void;
}

// STEP 2

class CPUPhone implements CPU{
    series:string;
    constructor(series:string){
        this.series = series;
    }
    getSeries(): string {
        return this.series
    }
}

class CPULaptop implements CPU{
    getSeries(): string {
        throw new Error("Method not implemented.");
    }
    setSeries(series: string): void {
        console.log("Series CPU Laptop ->", series)
    }   
}

class CPUTablet implements CPU{
    getSeries(): string {
        throw new Error("Method not implemented.");
    }
    setSeries(series: string): void {
        console.log("Series CPU Tablet ->", series)
    }   
}

class MemoryPhone implements Memory{
    memory:number;
    constructor(memory:number){
        this.memory = memory;
    }
    getCapacityInGB(): number {
        return this.memory
    }
}

class MemoryLaptop implements Memory{
    memory:number;
    constructor(memory:number){
        this.memory = memory;
    }
    getCapacityInGB(): number {
        return this.memory
    }
}

class MemoryTablet implements Memory{
    memory:number;
    constructor(memory:number){
        this.memory = memory;
    }
    getCapacityInGB(): number {
        return this.memory
    }
}

class DisplayPhone implements Display{
    resolution:number;
    constructor(resolution:number){
        this.resolution = resolution;
    }
    getResolution(): number {
        return this.resolution;
    }
}

class DisplayLaptop implements Display{
    resolution:number;
    constructor(resolution:number){
        this.resolution = resolution;
    }
    getResolution(): number {
        return this.resolution;
    }
}

class DisplayTablet implements Display{
    resolution:number;
    constructor(resolution:number){
        this.resolution = resolution;
    }
    getResolution(): number {
        return this.resolution;
    }
}

//Step 3

interface abstractFactory{
    cpu:string,
    memory: number,
    display: number,
    createCPU(): CPU,
    createMemory(): Memory,
    createDisplay(): Display
}

class Phone implements abstractFactory{
    cpu:string;
    memory: number;
    display: number;
    constructor(cpu: string,memory: number,display: number){
        this.cpu = cpu;
        this.memory = memory;
        this.display = display;
    }

    createCPU(): CPU {
        return new CPUPhone(this.cpu)
    }
    createMemory(): Memory {
        return new MemoryPhone(this.memory);
    }
    createDisplay(): Display {
        return new DisplayPhone(this.display);
    } 
}

class Tablet implements abstractFactory{
    cpu:string;
    memory: number;
    display: number;
    constructor(cpu: string,memory: number,display: number){
        this.cpu = cpu;
        this.memory = memory;
        this.display = display;
    }

    createCPU(): CPU {
        return new CPUPhone(this.cpu)
    }
    createMemory(): Memory {
        return new MemoryPhone(this.memory);
    }
    createDisplay(): Display {
        return new DisplayPhone(this.display);
    } 
}

function app(factory:abstractFactory){
    const cpu = factory.createCPU()
    console.log("Cpu ",cpu.getSeries())

    const memory = factory.createMemory()
    console.log("Memory ", memory.getCapacityInGB())

    const display = factory.createDisplay()
    console.log("Display ", display.getResolution())
}

app(new Phone("m1", 128, 1200))
app(new Tablet("m2",512, 2200))

Existe otro patrón de diseño que podría resolver la necesidad de crear múltiples productos y tipos de productos teniendo en cuenta su jerarquía, se conoce como Composite, comparto un enlace para que lo revisen.

Tuve que leer la respuesta para entender un poco, estaba confundido por donde empezar

// Step 1
class CPU {
    setSeries(series) {
        throw new Error("Not implemented");
    }
}
class Memory {    
    setCapacityInGB(capacity) {
        throw new Error("Not implemented");
    }
}
class Display {    
    setResolution(resolution) {
        throw new Error("Not implemented");
    }
}

// Step 2
//CP
class PhoneCPU extends CPU {
    setSeries(series) {
        console.log(`[PHONE] ${series}`);
    }    
}
class LaptopCPU extends CPU {
    setSeries(series) {
        console.log(`[LAPTOP] ${series}`);
    }    
}
class TabletCPU extends CPU {
    setSeries(series) {
        console.log(`[TABLET] ${series}`);
    }    
}
//Memory
class PhoneMemory extends Memory {
    setCapacityInGB(capacity) {
        console.log(`[PHONE] ${capacity}`);
    }    
}
class LaptopMemory extends Memory {
    setCapacityInGB(capacity) {
        console.log(`[LAPTOP] ${capacity}`);
    }    
}
class TabletMemory extends Memory {
    setCapacityInGB(capacity) {
        console.log(`[TABLET] ${capacity}`);
    }    
}
// Resolution
class PhoneResolution extends Display{
    setResolution(resolution) {
        console.log(`[PHONE] ${resolution}`);
    }    
}
class LaptopResolution extends Display{
    setResolution(resolution) {
        console.log(`[LAPTOP] ${resolution}`);
    }    
}
class TabletResolution extends Display{
    setResolution(resolution) {
        console.log(`[TABLET] ${resolution}`);
    }    
}

//Step 3
class DeviceFactory {
    createCPU() {
        throw new Error('Method not implemented!');
    }
    createMemory() {
        throw new Error('Method not implemented!');
    }
    createDisplay() {
        throw new Error('Method not implemented!');
    }
}

class PhoneDeviceFactory extends DeviceFactory {
    createCPU() {
        return new PhoneCPU();
    }
    createMemory() {
        return new PhoneMemory();
    }
    createDisplay() {
        return new PhoneResolution();
    }
}
class LaptopDeviceFactory extends DeviceFactory {
    createCPU() {
        return new LaptopCPU();
    }
    createMemory() {
        return new LaptopMemory();
    }
    createDisplay() {
        return new LaptopResolution();
    }
}
class TabletDeviceFactory extends DeviceFactory {
    createCPU() {
        return new TabletCPU();
    }
    createMemory() {
        return new TabletMemory();
    }
    createDisplay() {
        return new TabletResolution();
    }
}

function appAbstractFactory({factory, cpuSeries, capacity, resolution}) {    
    if (!factory) {
        console.log('---No factory provided ---');
        return '---No factory provided ---'
    }

    const cpu = factory.createCPU();
    const memory = factory.createMemory();
    const display = factory.createDisplay();

    cpu.setSeries(cpuSeries);
    memory.setCapacityInGB(capacity);
    display.setResolution(resolution)
}

function createFactory(deviceTyoe) {
    const devices = {
        'phone': PhoneDeviceFactory,
        'laptop': LaptopDeviceFactory,
        'tablet': TabletDeviceFactory
    }
    const Devices = devices[deviceTyoe];
    return new Devices();
}

appAbstractFactory({
    factory: createFactory('phone'),
    cpuSeries: 'Snapdragon 690',
    capacity: 16,
    resolution: '2560x1440',
})
appAbstractFactory({
    factory: createFactory('laptop'),
    cpuSeries: 'Intel Core i9',
    capacity: 500,
    resolution: '1920x1080',
})
appAbstractFactory({
    factory: createFactory('tablet'),
    cpuSeries: 'ARM Cortex-A53',
    capacity: 64,
    resolution: '1280x720',
})```

Solución 😄…

.
.
.
.

interface Cpu {
  setSeries(series: string): void;
}

interface Memory {
  setCapacityInGB(capacity: number): void;
}

interface Display {
  setResolution(): void;
}

class PhoneCpu implements Cpu {
  setSeries(series: string): void {
    console.log(`[Phone] CPU's series: ${series}`);
  }
}

class LaptopCpu implements Cpu {
  setSeries(series: string): void {
    console.log(`[Laptop] CPU's series: ${series}`);
  }
}

class TabletCpu implements Cpu {
  setSeries(series: string): void {
    console.log(`[Tablet] CPU series: ${series}`);
  }
}

class PhoneMemory implements Memory {
  setCapacityInGB(capacity: number): void {
    console.log(`[Phone] Memory capacity: ${capacity}`);
  }
}

class LaptopMemory implements Memory {
  setCapacityInGB(capacity: number): void {
    console.log(`[Laptop] Memory capacity: ${capacity}`);
  }
}

class TabletMemory implements Memory {
  setCapacityInGB(capacity: number): void {
    console.log(`[Tablet] Memory capacity: ${capacity}`);
  }
}

class PhoneDisplay implements Display {
  setResolution(): void {
    console.log(`[Phone] Display`);
  }
}

class LaptopDisplay implements Display {
  setResolution(): void {
    console.log(`[Laptop] Display`);
  }
}

class TabletDisplay implements Display {
  setResolution(): void {
    console.log(`[Tablet] Display`);
  }
}

interface componentAbstractFactory {
  createCpu(): Cpu;
  createMemory(): Memory;
  createDisplay(): Display;
}

class PhoneComponentFactory implements componentAbstractFactory {
  createCpu(): Cpu {
    return new PhoneCpu();
  }

  createMemory(): Memory {
    return new PhoneMemory();
  }

  createDisplay(): Display {
    return new PhoneDisplay();
  }
}

class LaptopComponentFactory implements componentAbstractFactory {
  createCpu(): Cpu {
    return new LaptopCpu();
  }

  createMemory(): Memory {
    return new LaptopMemory();
  }

  createDisplay(): Display {
    return new LaptopDisplay();
  }
}

class TabletComponentFactory implements componentAbstractFactory {
  createCpu(): Cpu {
    return new TabletCpu();
  }

  createMemory(): Memory {
    return new TabletMemory();
  }

  createDisplay(): Display {
    return new TabletDisplay();
  }
}

function appComponentFactory(
  factory: componentAbstractFactory,
  series: string,
  capacity: number
) {
  const cpu: Cpu = factory.createCpu();
  const memory: Memory = factory.createMemory();
  const display: Display = factory.createDisplay();

  cpu.setSeries(series);
  memory.setCapacityInGB(capacity);
  display.setResolution();
}

// appComponentFactory(new PhoneComponentFactory(), "X-Phone-Series", 15);
// appComponentFactory(new LaptopComponentFactory(), "Y-Laptop-Series", 23);
// appComponentFactory(new TabletComponentFactory(), "Z-Tablet-Series", 39);

type FactoryType = "phone" | "laptop" | "tablet";
function createFactory(type: FactoryType): componentAbstractFactory {
  const factories = {
    phone: PhoneComponentFactory,
    laptop: LaptopComponentFactory,
    tablet: TabletComponentFactory,
  };
  const Factory = factories[type];
  return new Factory();
}

appComponentFactory(createFactory("phone"), "X-Phone-Series", 15);
appComponentFactory(createFactory("laptop"), "Y-Laptop-Series", 23);
appComponentFactory(createFactory("tablet"), "Z-Tablet-Series", 39);

Los patrones de diseño creacionales, como el patrón Factory (fábrica) y Abstract Factory (fábrica abstracta), están estrechamente relacionados con los principios SOLID, especialmente con el principio de Inversión de Dependencias (Dependency Inversion Principle - DIP).
.
El principio de Inversión de Dependencias establece que:
.

  1. Los módulos de alto nivel no deben depender de los módulos de bajo nivel. Ambos deben depender de abstracciones.
    .

  2. Las abstracciones no deben depender de detalles. Los detalles deben depender de abstracciones.

.
Los patrones Factory y Abstract Factory están diseñados para ayudar a aplicar este principio, ya que introducen una capa de abstracción entre el código que necesita objetos y las clases concretas que los crean.
.

  • Factory Method Pattern (Patrón de Método de Fábrica): Permite definir una interfaz para crear un objeto, pero delega la decisión de qué clase concreta implementar al subclase. Así, los objetos se crean a través de un método común pero las subclases pueden proporcionar la implementación específica.
    .

  • Abstract Factory Pattern (Patrón de Fábrica Abstracta): Proporciona una interfaz para crear familias de objetos relacionados o dependientes sin especificar sus clases concretas. Esto permite la creación de objetos relacionados sin exponer las implementaciones concretas al código que los utiliza.

.
Ambos patrones promueven la idea de trabajar con abstracciones en lugar de clases concretas, lo que facilita la adhesión al principio de Inversión de Dependencias de SOLID. Al utilizar estos patrones, el código de alto nivel puede interactuar con interfaces o clases abstractas, evitando depender directamente de implementaciones concretas. Esto facilita la flexibilidad, el mantenimiento y la extensión del código, ya que los cambios en las implementaciones concretas no afectarán al código que depende de las abstracciones.

TS code.

// Base interface Products
interface CPU {
    setSeries(string:string): void;
}

interface Memory {
    setCapacityInGB(number:number): void;
}

interface Display {
    setResoltion(): void;
}

// Concrete CPU Class Products for each family
class CPUforPhone implements CPU {
    setSeries(string: string): void {
        console.log(`Cpu serie ${string} for Phone`);
    }
}

class CPUforLaptop implements CPU {
    setSeries(string: string): void {
        console.log(`Cpu serie ${string} for Laptop`);
    }
}

class CPUforTablet implements CPU {
    setSeries(string: string): void {
        console.log(`Cpu serie ${string} for Tablet`);
    }
}


// Concrete Memory Class Products for each family
class MemoryForPhone implements Memory{
    setCapacityInGB(number: number): void {
        console.log(`Phone memory is ${number} GB`);  
    }
}

class MemoryForLaptop implements Memory{
    setCapacityInGB(number: number): void {
        console.log(`Laptop memory is ${number} GB`);  
    }
}

class MemoryForTablet implements Memory{
    setCapacityInGB(number: number): void {
        console.log(`Tablet memory is ${number} GB`);
    }
}


// Concrete Display Class Products for each family
class DisplayForPhone implements Display {
    setResoltion(): void {
        console.log(`Resolution for Phone`);
    }
}

class DisplayForLaptop implements Display {
    setResoltion(): void {
        console.log(`Resolution for Laptop`);
    }
}

class DisplayForTablet implements Display {
    setResoltion(): void {
        console.log(`Resolution for Tablet`);
    }
}


// Create abstract factory
interface TechFactory {
    createCpu(): CPU; 
    createMemory(): Memory; 
    createDisplay(): Display;
}


// Factory of phones
class PhoneFactory implements TechFactory {
    createCpu(): CPU {
        return new CPUforPhone; 
    }

    createMemory(): Memory {
        return new MemoryForPhone;
    }

    createDisplay(): Display {
        return new DisplayForPhone;
    }
}

// Factory of Laptops
class LaptopFactory implements TechFactory {
    createCpu(): CPU {
        return new CPUforLaptop; 
    }

    createMemory(): Memory {
        return new MemoryForLaptop;
    }

    createDisplay(): Display {
        return new DisplayForLaptop;
    }
}

// Factory of tablets
class TabletFactory implements TechFactory {
    createCpu(): CPU {
        return new CPUforTablet; 
    }

    createMemory(): Memory {
        return new MemoryForTablet;
    }

    createDisplay(): Display {
        return new DisplayForTablet;
    }
}

// implementation
type factoryType = 'phone' | 'laptop' | 'tablet';

function createFactory(factory: factoryType): TechFactory {
    const factories = {
        'phone': PhoneFactory,
        'laptop': LaptopFactory,
        'tablet': TabletFactory
    };

    const Factory = new factories[factory];

    return Factory;
};

function createProduct(factory: TechFactory) {
    const CPU: CPU = factory.createCpu();
    const memory: Memory = factory.createMemory();
    const display: Display = factory.createDisplay();

    CPU.setSeries('V1');
    memory.setCapacityInGB(16);
    display.setResoltion();
};

createProduct(createFactory('phone'));
createProduct(createFactory('laptop'));
createProduct(createFactory('tablet'));

Hice el reto aprovechando los módulos es ESM. Los invito a que le echen un ojo para tomar ideas o dar feedback 🤘
https://github.com/realDiegoR/ts-design-patterns/tree/main/abstract-factory
(Denle a la tecla (.) para abrir GitHub Codespaces para visualizar mejor mejor)

¡Hola! Con respecto a la contra de que si se realiza un cambio al elemento base, todos los productos concretos deben de implementar el cambio, hay que tener en cuenta que si se desean seguir los principios SOLID, podría no aplicarse del todo ante algún cambio, especificamente con el principio I de segregación de interfaces, ejemplo, la clase base MastodonCar se le implementará un nuevo método que es “Auto-conducción”, al ser una interfaz o una clase base, este método debería de ir tanto en MastodonSedanCar y MastodonHatchbackCar, ¡Pero hey! Tenemos un lío y es que el Hatchback no cuenta con esta funcionalidad, por lo que le estaríamos aplicando un método que NO necesita tener implementado, por lo que sería necesario quizás refactorizar el código ya que el principio I dice que no debemos de implementar métodos que una clase no necesita, dividiendo la interfaz en dos interfaces como “MastodonCarWithIA” y “MastodonCarWithoutIA” podríamos ya estar empezando a salirnos del patrón de diseño, así que sería necesario crear una nueva clase base y por ende, más código genérico.

De solo pensar como ese pequeño cambio podría afectar el programa, me dio dolor de cabeza 😅

Mi impletacion en js: ```js // STEP 1 - Abstract classes class CPU { setSeries(series) { throw new Error("Method not implemented."); } } class Memory { setCapacityInGB(number) { throw new Error("Method not implemented."); } } class Display { setResolution(resolution) { throw new Error("Method not implemented."); } } // STEP 2 - Concrete classes class PhoneCPU extends CPU { setSeries(series) { console.log(`[PHONE] Setting CPU series: ${series}`); } } class LaptopCPU extends CPU { setSeries(series) { console.log(`[LAPTOP] Setting CPU serie: ${series}`); } } class TabletCPU extends CPU { setSeries(series) { console.log(`[Tablet] Setting CPU serie: ${series}`); } } class PhoneMemory extends Memory { setCapacityInGB(capacity) { console.log(`[PHONE] Setting memory capacity: ${capacity} GB`); } } class LaptopMemory extends Memory { setCapacityInGB(capacity) { console.log(`[LAPTOP] Setting memory capacity: ${capacity} GB`); } } class TabletMemory extends Memory { setCapacityInGB(capacity) { console.log(`[TABLET] Setting memory capacity: ${capacity} GB`); } } class PhoneDisplay extends Display { setResolution(resolution) { console.log(`[PHONE] Setting display resolution: ${resolution}`); } } class LaptopDisplay extends Display { setResolution(resolution) { console.log(`[LAPTOP] Setting display resolution: ${resolution}`); } } class TabletDisplay extends Display { setResolution(resolution) { console.log(`[TABLET] Setting display resolution: ${resolution}`); } } // STEP 3 - Abstract Factory class class DeviceAbstractFactory { makeCPU() { throw new Error('Method not implemented!'); } makeMemory() { throw new Error('Method not implemented!'); } makeDisplay() { throw new Error('Method not implemented!'); } } // STEP 4 - Concrete factories class PhoneFactory extends DeviceAbstractFactory { makeCPU() { return new PhoneCPU(); } makeMemory() { return new PhoneMemory(); } makeDisplay() { return new PhoneDisplay(); } } class LaptopFactory extends DeviceAbstractFactory { makeCPU() { return new LaptopCPU(); } makeMemory() { return new LaptopMemory(); } makeDisplay() { return new LaptopDisplay(); } } class TabletFactory extends DeviceAbstractFactory { makeCPU() { return new TabletCPU(); } makeMemory() { return new TabletMemory(); } makeDisplay() { return new TabletDisplay(); } } // USE function appAbstractFactory({factory, cpuSeries, capacity, resolution}) { if (!factory) { console.log('---No factory provided ---'); return '---No factory provided ---' } const cpu = factory.makeCPU(); const memory = factory.makeMemory(); const display = factory.makeDisplay(); cpu.setSeries(cpuSeries); memory.setCapacityInGB(capacity); display.setResolution(resolution); } function makeFactory(deviceType) { const devices = { 'phone': PhoneFactory, 'laptop': LaptopFactory, 'tablet': TabletFactory, } const Devices = devices[deviceType]; return new Devices(); } // USE appAbstractFactory({ factory: makeFactory('phone'), cpuSeries: 'Snapdragon 690', capacity: 16, resolution: '2560x1440', }); appAbstractFactory({ factory: makeFactory('laptop'), cpuSeries: 'Intel Core i9', capacity: 500, resolution: '1920x1080', }); appAbstractFactory({ factory: makeFactory('tablet'), cpuSeries: 'ARM Cortex-A53', capacity: 64, resolution: '1280x720', }); ```
```js // Productos Abstractos abstract class Cpu { abstract setSeries(serie: string): void; } abstract class Memory { abstract setCapacityInGB(gb: number): void; } abstract class Display { abstract setResolution(): void; } // Interfaz de fábrica abstracta interface DeviceFactory { createCpu(): Cpu; createMemory(): Memory; createDisplay(): Display; } // Productos concretos para Phone class PhoneCpu extends Cpu { private readonly type = "Phone"; private serie: string = ""; public setSeries(serie: string): void { this.serie = serie; console.log(`${this.type} Cpu serie set to ${this.serie}`); } } class PhoneMemory extends Memory { private readonly type = "Phone"; private capacityInGB: number = 0; public setCapacityInGB(gb: number): void { this.capacityInGB = gb; console.log(`${this.type} memory capacity set to ${this.capacityInGB}`); } } class PhoneDisplay extends Display { private readonly type = "Phone"; public setResolution(): void { console.log(`${this.type} display resolution set`); } } // Fábrica concreta para Phone class PhoneFactory implements DeviceFactory { createCpu(): Cpu { return new PhoneCpu(); } createMemory(): Memory { return new PhoneMemory(); } createDisplay(): Display { return new PhoneDisplay(); } } // Productos concretos para Laptop class LaptopCpu extends Cpu { private readonly type = "Laptop"; private serie: string = ""; public setSeries(serie: string): void { this.serie = serie; console.log(`${this.type} Cpu series set to ${this.serie}`); } } class LaptopMemory extends Memory { private readonly type = "Laptop"; private capacityInGB: number = 0; public setCapacityInGB(gb: number): void { this.capacityInGB = gb; console.log(`${this.type} memory capacity set to ${this.capacityInGB}`); } } class LaptopDisplay extends Display { private readonly type = "Laptop"; public setResolution(): void { console.log(`${this.type} display resolution set`); } } // Fábrica concreta para Laptop class LaptopFactory implements DeviceFactory { createCpu(): Cpu { return new LaptopCpu(); } createMemory(): Memory { return new LaptopMemory(); } createDisplay(): Display { return new LaptopDisplay(); } } // Productos concretos para Tablet class TabletCpu extends Cpu { private readonly type = "Tablet"; private serie: string = ""; public setSeries(serie: string): void { this.serie = serie; console.log(`${this.type} Cpu series set to ${this.serie}`); } } class TabletMemory extends Memory { private readonly type = "Tablet"; private capacityInGB: number = 0; public setCapacityInGB(gb: number): void { this.capacityInGB = gb; console.log(`${this.type} memory capacity set to ${this.capacityInGB}`); } } class TabletDisplay extends Display { private readonly type = "Tablet"; public setResolution(): void { console.log(`${this.type} display resolution set`); } } // Fábrica concreta para Tablet class TabletFactory implements DeviceFactory { createCpu(): Cpu { return new TabletCpu(); } createMemory(): Memory { return new TabletMemory(); } createDisplay(): Display { return new TabletDisplay(); } } // Creador de fabricas enum DeviceType { Phone = "phone", Laptop = "laptop", Tablet = "tablet", } class DeviceFactoryCreator { static createDevice(type: DeviceType): DeviceFactory { switch (type) { case DeviceType.Phone: return new PhoneFactory(); case DeviceType.Laptop: return new LaptopFactory(); case DeviceType.Tablet: return new TabletFactory(); default: throw new Error(`${type} not found in the factory...`); } } } // example const phoneFactory = DeviceFactoryCreator.createDevice(DeviceType.Phone); const phoneCpu = phoneFactory.createCpu(); phoneCpu.setSeries("Snapdragon 888"); const laptopFactory = DeviceFactoryCreator.createDevice(DeviceType.Laptop); const laptopMemory = laptopFactory.createMemory(); laptopMemory.setCapacityInGB(32); ```
¡Hola! Dejo por acá mi solución usando Typescript: ```ts interface CPU { setSeries(series: string): void; } interface Memory { setCapacityInGB(capacity: number): void; } interface Display { setResolution(): void; } /** Concrete product classes */ class CPUPhone implements CPU { setSeries(series: string): void { console.log("PHONE CPU series:" + series); } } class CPULaptop implements CPU { setSeries(series: string): void { console.log("LAPTOP CPU series:" + series); } } class CPUTablet implements CPU { setSeries(series: string): void { console.log("TABLET CPU series: " + series); } } class MemoryPhone implements Memory { setCapacityInGB(capacity: number): void { console.log("PHONE MEMORY capacity: " + capacity + "GB"); } } class MemoryLaptop implements Memory { setCapacityInGB(capacity: number): void { console.log("LAPTOP MEMORY capacity: " + capacity + "GB"); } } class MemoryTablet implements Memory { setCapacityInGB(capacity: number): void { console.log("TABLET MEMORY capacity: " + capacity + "GB"); } } class DisplayPhone implements Display { setResolution(): void { console.log("PHONE DISPLAY resolution has been set"); } } class DisplayLaptop implements Display { setResolution(): void { console.log("LAPTOP DISPLAY resolution has been set"); } } class DisplayTablet implements Display { setResolution(): void { console.log("TABLET DISPLAY resolution has been set"); } } /** Abstract factory */ interface AbstractPiecesFactory { makeCPU(): CPU; makeMemory(): Memory; makeDisplay(): Display; } /** Concrete factories */ class PhonePiecesFactory implements AbstractPiecesFactory { makeCPU(): CPU { return new CPUPhone(); } makeMemory(): Memory { return new MemoryPhone(); } makeDisplay(): Display { return new DisplayPhone(); } } class LaptopPiecesFactory implements AbstractPiecesFactory { makeCPU(): CPU { return new CPULaptop(); } makeMemory(): Memory { return new MemoryLaptop(); } makeDisplay(): Display { return new DisplayLaptop(); } } class TabletPiecesFactory implements AbstractPiecesFactory { makeCPU(): CPU { return new CPUTablet(); } makeMemory(): Memory { return new MemoryTablet(); } makeDisplay(): Display { return new DisplayTablet(); } } function appPiecesFactory(factory: AbstractPiecesFactory) { const cpu = factory.makeCPU(); const memory = factory.makeMemory(); const display = factory.makeDisplay(); cpu.setSeries("i5"); memory.setCapacityInGB(8); display.setResolution(); } appPiecesFactory(new PhonePiecesFactory()); appPiecesFactory(new LaptopPiecesFactory()); appPiecesFactory(new TabletPiecesFactory()); ```interface CPU {  setSeries(series: string): void;} interface Memory {  setCapacityInGB(capacity: number): void;} interface Display {  setResolution(): void;} /\*\* Concrete product classes \*/ class CPUPhone implements CPU {  setSeries(series: string): void {    console.log("PHONE CPU series:" + series);    }} class CPULaptop implements CPU {  setSeries(series: string): void {    console.log("LAPTOP CPU series:" + series);   }} class CPUTablet implements CPU {  setSeries(series: string): void {    console.log("TABLET CPU series: " + series);    }} class MemoryPhone implements Memory {  setCapacityInGB(capacity: number): void {    console.log("PHONE MEMORY capacity: " + capacity + "GB");  }} class MemoryLaptop implements Memory {  setCapacityInGB(capacity: number): void {    console.log("LAPTOP MEMORY capacity: " + capacity + "GB");  }} class MemoryTablet implements Memory {  setCapacityInGB(capacity: number): void {    console.log("TABLET MEMORY capacity: " + capacity + "GB");  }} class DisplayPhone implements Display {  setResolution(): void {    console.log("PHONE DISPLAY resolution has been set");  }} class DisplayLaptop implements Display {  setResolution(): void {    console.log("LAPTOP DISPLAY resolution has been set");  }} class DisplayTablet implements Display {  setResolution(): void {    console.log("TABLET DISPLAY resolution has been set");  }} /\*\* Abstract factory \*/ interface AbstractPiecesFactory {  makeCPU(): CPU;  makeMemory(): Memory;  makeDisplay(): Display;} /\*\* Concrete factories \*/ class PhonePiecesFactory implements AbstractPiecesFactory {  makeCPU(): CPU {    return new CPUPhone();  }  makeMemory(): Memory {    return new MemoryPhone();  }  makeDisplay(): Display {    return new DisplayPhone();  }} class LaptopPiecesFactory implements AbstractPiecesFactory {  makeCPU(): CPU {    return new CPULaptop();  }  makeMemory(): Memory {    return new MemoryLaptop();  }  makeDisplay(): Display {    return new DisplayLaptop();  }} class TabletPiecesFactory implements AbstractPiecesFactory {  makeCPU(): CPU {    return new CPUTablet();  }  makeMemory(): Memory {    return new MemoryTablet();  }  makeDisplay(): Display {    return new DisplayTablet();  }} function appPiecesFactory(factory: AbstractPiecesFactory) {  const cpu = factory.makeCPU();  const memory = factory.makeMemory();  const display = factory.makeDisplay();   cpu.setSeries("i5");  memory.setCapacityInGB(8);  display.setResolution();} appPiecesFactory(new PhonePiecesFactory());appPiecesFactory(new LaptopPiecesFactory());appPiecesFactory(new TabletPiecesFactory());
```ts interface BaseCPU { setSeries(serie: string): void; } interface BaseMemory { setCapacityInGB(memory: number): void; } interface Display { setResolution(): void } // Phone class PhoneCPU implements BaseCPU { setSeries(serie: string): void { console.log(`Phone CPU serie ${serie}`); } } class PhoneMemory implements BaseMemory { setCapacityInGB(memory: number): void { console.log(`Phone memory ${memory}GB`); } } class PhoneDisplay implements Display { setResolution(): void { console.log('Phone display resolution'); } } //Tablet class TabletCPU implements BaseCPU { setSeries(serie: string): void { console.log(`Tablet CPU serie ${serie}`); } } class TabletMemory implements BaseMemory { setCapacityInGB(memory: number): void { console.log(`Tablet memory ${memory}GB`); } } class TabletDisplay implements Display { setResolution(): void { console.log('Tablet display resolution'); } } // Laptop class LaptopCPU implements BaseCPU { setSeries(serie: string): void { console.log(`Laptop CPU serie ${serie}`); } } class LaptopMemory implements BaseMemory { setCapacityInGB(memory: number): void { console.log(`Laptop memory ${memory}GB`); } } class LaptopDisplay implements Display { setResolution(): void { console.log('Laptop display resolution'); } } interface ProductFactory { createCPU(): BaseCPU; createMemory(): BaseMemory; createDisplay(): Display; } class PhoneFactory implements ProductFactory { createCPU(): BaseCPU { return new PhoneCPU(); } createMemory(): BaseMemory { return new PhoneMemory(); } createDisplay(): Display { return new PhoneDisplay(); } } class LaptopFactory implements ProductFactory { createCPU(): BaseCPU { return new LaptopCPU(); } createMemory(): BaseMemory { return new LaptopMemory(); } createDisplay(): Display { return new LaptopDisplay(); } } class TabletFactory implements ProductFactory { createCPU(): BaseCPU { return new TabletCPU(); } createMemory(): BaseMemory { return new TabletMemory(); } createDisplay(): Display { return new TabletDisplay(); } } function appFactory(factory: ProductFactory, cpu: string, memory: number): void { const factoryCPU = factory.createCPU(); const factoryMemory = factory.createMemory(); const factoryDisplay = factory.createDisplay(); factoryCPU.setSeries(cpu); factoryMemory.setCapacityInGB(memory); factoryDisplay.setResolution(); } type FactoryType = 'phone' | 'laptop' | 'tablet'; function createFactory(factoryType: FactoryType): ProductFactory { const factories = { phone: PhoneFactory, laptop: LaptopFactory, tablet: TabletFactory } console.log(`---Creating a new product: ${factoryType}----`); return new factories[factoryType](); } appFactory(createFactory('phone'), 'A1', 16); appFactory(createFactory('tablet'), 'A5', 32); appFactory(createFactory('laptop'), 'i7', 64); export {}; ```interface BaseCPU { setSeries(serie: string): void; } interface BaseMemory { setCapacityInGB(memory: number): void; } interface Display { setResolution(): void } // Phone class PhoneCPU implements BaseCPU { setSeries(serie: string): void { console.log(`Phone CPU serie ${serie}`); } } class PhoneMemory implements BaseMemory { setCapacityInGB(memory: number): void { console.log(`Phone memory ${memory}GB`); } } class PhoneDisplay implements Display { setResolution(): void { console.log('Phone display resolution'); } } //Tablet class TabletCPU implements BaseCPU { setSeries(serie: string): void { console.log(`Tablet CPU serie ${serie}`); } } class TabletMemory implements BaseMemory { setCapacityInGB(memory: number): void { console.log(`Tablet memory ${memory}GB`); } } class TabletDisplay implements Display { setResolution(): void { console.log('Tablet display resolution'); } } // Laptop class LaptopCPU implements BaseCPU { setSeries(serie: string): void { console.log(`Laptop CPU serie ${serie}`); } } class LaptopMemory implements BaseMemory { setCapacityInGB(memory: number): void { console.log(`Laptop memory ${memory}GB`); } } class LaptopDisplay implements Display { setResolution(): void { console.log('Laptop display resolution'); } } interface ProductFactory { createCPU(): BaseCPU; createMemory(): BaseMemory; createDisplay(): Display; } class PhoneFactory implements ProductFactory { createCPU(): BaseCPU { return new PhoneCPU(); } createMemory(): BaseMemory { return new PhoneMemory(); } createDisplay(): Display { return new PhoneDisplay(); } } class LaptopFactory implements ProductFactory { createCPU(): BaseCPU { return new LaptopCPU(); } createMemory(): BaseMemory { return new LaptopMemory(); } createDisplay(): Display { return new LaptopDisplay(); } } class TabletFactory implements ProductFactory { createCPU(): BaseCPU { return new TabletCPU(); } createMemory(): BaseMemory { return new TabletMemory(); } createDisplay(): Display { return new TabletDisplay(); } } function appFactory(factory: ProductFactory, cpu: string, memory: number): void { const factoryCPU = factory.createCPU(); const factoryMemory = factory.createMemory(); const factoryDisplay = factory.createDisplay(); factoryCPU.setSeries(cpu); factoryMemory.setCapacityInGB(memory); factoryDisplay.setResolution(); } type FactoryType = 'phone' | 'laptop' | 'tablet'; function createFactory(factoryType: FactoryType): ProductFactory { const factories = { phone: PhoneFactory, laptop: LaptopFactory, tablet: TabletFactory } console.log(`---Creating a new product: ${factoryType}----`); return new factories\[factoryType]\(); } appFactory(createFactory('phone'), 'A1', 16); appFactory(createFactory('tablet'), 'A5', 32); appFactory(createFactory('laptop'), 'i7', 64); export {};
mmm... por si le sirve a alguien: *class CPU {* *setSeries(series) {* *console.log("CPU", series);* *}* *}* *class Memory {* *setCapacityInGB(capacity) {* *console.log("Memory", capacity);* *}* *}* *class Display {* *setResolution(resolution) {* *console.log("Display", resolution);* *}* *}* *class PhoneCPU extends CPU {* *setSeries(series) {* *console.log('Phone CPU:', series);* *}* *}* *class PhoneMemory extends Memory {* *setCapacityInGB(capacity) {* *console.log('Phone Memory:', capacity);* *}* *}* *class PhoneDisplay extends Display {* *setResolution(resolution) {* *console.log('Phone Display:', resolution);* *}* *}* *class LaptopCPU extends CPU {* *setSeries(series) {* *console.log('Laptop CPU:', series);* *}* *}* *class LaptopMemory extends Memory {* *setCapacityInGB(capacity) {* *console.log('Laptop Memory:', capacity);* *}* *}* *class LaptopDisplay extends Display {* *setResolution(resolution) {* *console.log('Laptop Display:', resolution);* *}* *}* *class TabletCPU extends CPU {* *setSeries(series) {* *console.log('Tablet CPU:', series);* *}* *}* *class TabletMemory extends Memory {* *setCapacityInGB(capacity) {* *console.log('Tablet Memory:', capacity);* *}* *}* *class TabletDisplay extends Display {* *setResolution(resolution) {* *console.log('Tablet Display:', resolution);* *}* *}* *class DeviceFactory {* *createCPU() {* *throw new Error("Método no implementado!");* *}* *createMemory() {* *throw new Error("Método no implementado!");* *}* *createDisplay() {* *throw new Error("Método no implementado!");* *}* *}* *class PhoneDeviceFactory extends DeviceFactory {* *createCPU() {* *return new PhoneCPU();* *}* ** *createMemory() {* *return new PhoneMemory();* *}* *createDisplay() {* *return new PhoneDisplay();* *}* *}* *class LaptopDeviceFactory extends DeviceFactory {* *createCPU() {* *return new LaptopCPU();* *}* ** *createMemory() {* *return new LaptopMemory();* *}* *createDisplay() {* *return new LaptopDisplay();* *}* *}* *class TabletDeviceFactory extends DeviceFactory {* *createCPU() {* *return new TabletCPU();* *}* ** *createMemory() {* *return new TabletMemory();* *}* *createDisplay() {* *return new TabletDisplay();* *}* *}* *function createFactory(deviceType) {* *const devices = {* *'phone': PhoneDeviceFactory,* *'laptop': LaptopDeviceFactory,* *'tablet': TabletDeviceFactory* *};* *const Devices = devices\[deviceType];* *return new Devices();* *}* *function appAbstractFactory({factory, serie, capacity, resolucion}) {* *if (!factory) {* *console.log('-- No factory provided --');* *return '-- No factory provided --';* *}* *const cpu = factory.createCPU();* *const memory = factory.createMemory();* *const display = factory.createDisplay();* *cpu.setSeries(serie);* *memory.setCapacityInGB(capacity);* *display.setResolution(resolucion);* *}* *function appInit() {* *appAbstractFactory({* *factory: createFactory('phone'),* *serie: 'SnapDragon 2500',* *capacity: 100,* *resolucion: '2500X2550'* *});* *}* *appInit();*
```js import { table } from "console" interface CPU { setSeries(series: string): void } interface Memory { setCapacityInGB(gb: number): void } interface Display { setResolution(): void } class CPUPhone implements CPU { setSeries(series: string): void { console.log('Series: ', series) } } class MemoryPhone implements Memory { setCapacityInGB(gb: number): void { console.log('GB capacity: ', gb) } } class DisplayPhone implements Display { setResolution(): void { console.log('Phone display') } } class CPULaptop implements CPU { setSeries(series: string): void { console.log('Series: ', series) } } class MemoryLaptop implements Memory { setCapacityInGB(gb: number): void { console.log('GB capacity: ', gb) } } class DisplayLaptop implements Display { setResolution(): void { console.log('Phone display') } } class CPUTablet implements CPU { setSeries(series: string): void { console.log('Series: ', series) } } class MemoryTablet implements Memory { setCapacityInGB(gb: number): void { console.log('GB capacity: ', gb) } } class DisplayTablet implements Display { setResolution(): void { console.log('Phone display') } } interface ProductsFactory { createCPU(): CPU createMemory(): Memory createDisplay(): Display } class PhoneFactory implements ProductsFactory { createCPU(): CPU { return new CPUPhone() } createMemory(): Memory { return new MemoryPhone() } createDisplay(): Display { return new DisplayPhone() } } class LaptopFactory implements ProductsFactory { createCPU(): CPU { return new CPULaptop() } createMemory(): Memory { return new MemoryLaptop() } createDisplay(): Display { return new DisplayLaptop() } } class TabletFactory implements ProductsFactory { createCPU(): CPU { return new CPUTablet() } createMemory(): Memory { return new MemoryTablet() } createDisplay(): Display { return new DisplayTablet() } } function appProductsFactory(factory: ProductsFactory){ const cpu = factory.createCPU() const memory = factory.createMemory() const display = factory.createDisplay() cpu.setSeries('xlr8') memory.setCapacityInGB(32) display.setResolution() } type FactoryType = 'phone' | 'laptop' | 'tablet' function createFactory(type: FactoryType): ProductsFactory { const factories = { phone: PhoneFactory, laptop: LaptopFactory, tablet: TabletFactory, } const Factory = factories[type] return new Factory() } appProductsFactory(createFactory('phone')) appProductsFactory(createFactory('laptop')) appProductsFactory(createFactory('tablet')) ```import { table } from "console" *interface* <u>CPU</u> {  setSeries(*series*: *string*): *void*} *interface* <u>Memory</u> {  setCapacityInGB(*gb*: *number*): *void*} *interface* <u>Display</u> {  setResolution(): *void*} *class* <u>CPUPhone</u> implements *<u>CPU</u>* {  setSeries(*series*: *string*): *void* {      console.log('Series: ', series)  }} *class* <u>MemoryPhone</u> implements *<u>Memory</u>* {  setCapacityInGB(*gb*: *number*): *void* {      console.log('GB capacity: ', gb)  }} *class* <u>DisplayPhone</u> implements *<u>Display</u>* {  setResolution(): *void* {      console.log('Phone display')  }} *class* <u>CPULaptop</u> implements *<u>CPU</u>* {  setSeries(*series*: *string*): *void* {      console.log('Series: ', series)  }} *class* <u>MemoryLaptop</u> implements *<u>Memory</u>* {  setCapacityInGB(*gb*: *number*): *void* {      console.log('GB capacity: ', gb)  }} *class* <u>DisplayLaptop</u> implements *<u>Display</u>* {  setResolution(): *void* {      console.log('Phone display')  }} *class* <u>CPUTablet</u> implements *<u>CPU</u>* {  setSeries(*series*: *string*): *void* {      console.log('Series: ', series)  }} *class* <u>MemoryTablet</u> implements *<u>Memory</u>* {  setCapacityInGB(*gb*: *number*): *void* {      console.log('GB capacity: ', gb)  }} *class* <u>DisplayTablet</u> implements *<u>Display</u>* {  setResolution(): *void* {      console.log('Phone display')  }} *interface* <u>ProductsFactory</u> {  createCPU(): <u>CPU</u>  createMemory(): <u>Memory</u>  createDisplay(): <u>Display</u>} *class* <u>PhoneFactory</u> implements *<u>ProductsFactory</u>* {  createCPU(): <u>CPU</u> {      return new CPUPhone()  }   createMemory(): <u>Memory</u> {      return new MemoryPhone()  }   createDisplay(): <u>Display</u> {      return new DisplayPhone()  }} *class* <u>LaptopFactory</u> implements *<u>ProductsFactory</u>* {  createCPU(): <u>CPU</u> {      return new CPULaptop()  }   createMemory(): <u>Memory</u> {      return new MemoryLaptop()  }   createDisplay(): <u>Display</u> {      return new DisplayLaptop()  }} *class* <u>TabletFactory</u> implements *<u>ProductsFactory</u>* {  createCPU(): <u>CPU</u> {      return new CPUTablet()  }   createMemory(): <u>Memory</u> {      return new MemoryTablet()  }   createDisplay(): <u>Display</u> {      return new DisplayTablet()  }} *function* appProductsFactory(*factory*: <u>ProductsFactory</u>){  *const* cpu = factory.createCPU()  *const* memory = factory.createMemory()  *const* display = factory.createDisplay()   cpu.setSeries('xlr8')  memory.setCapacityInGB(32)  display.setResolution()} *type* <u>FactoryType</u> = 'phone' | 'laptop' | 'tablet' *function* createFactory(*type*: <u>FactoryType</u>): <u>ProductsFactory</u> {  *const* factories = {    phone: PhoneFactory,    laptop: LaptopFactory,    tablet: TabletFactory,  }   *const* Factory = factories\[type]   return new Factory()} appProductsFactory(createFactory('phone'))appProductsFactory(createFactory('laptop'))appProductsFactory(createFactory('tablet'))
aqui mi solucion en python: ```js from __future__ import annotations from abc import ABC, abstractmethod class DeviceFactory(ABC): @abstractmethod def create_cpu(self) -> Cpu: pass @abstractmethod def create_memory(self) -> Memory: pass @abstractmethod def create_display(self) -> Display: pass class PhoneFactory(DeviceFactory): def create_cpu(self) -> Cpu: return MyCpu1() def create_memory(self) -> Memory: return MyMemory1() def create_display(self) -> Display: return MyDisplay1() class LaptopFactory(DeviceFactory): def create_cpu(self) -> Cpu: return MyCpu2() def create_memory(self) -> Memory: return MyMemory2() def create_display(self) -> Display: return MyDisplay2() class TabletFactory(DeviceFactory): def create_cpu(self) -> Cpu: return MyCpu3() def create_memory(self) -> Memory: return MyMemory3() def create_display(self) -> Display: return MyDisplay3() class Cpu(ABC): @abstractmethod def set_series(self, series: str) -> None: pass class MyCpu1(Cpu): def set_series(self, series: str) -> None: print('MyCpu1 series:', series) class MyCpu2(Cpu): def set_series(self, series: str) -> None: print('MyCpu2 series:', series) class MyCpu3(Cpu): def set_series(self, series: str) -> None: print('MyCpu3 series:', series) class Memory(ABC): @abstractmethod def set_capacity_in_gb(self, capacity: int) -> None: pass class MyMemory1(Memory): def set_capacity_in_gb(self, capacity: int) -> None: print('MyMemory1 capacity:', capacity) class MyMemory2(Memory): def set_capacity_in_gb(self, capacity: int) -> None: print('MyMemory2 capacity:', capacity) class MyMemory3(Memory): def set_capacity_in_gb(self, capacity: int) -> None: print('MyMemory3 capacity:', capacity) class Display(ABC): @abstractmethod def set_resolution(self, resolution: str) -> None: pass class MyDisplay1(Display): def set_resolution(self, resolution: str) -> None: print('MyDisplay1 resolution:', resolution) class MyDisplay2(Display): def set_resolution(self, resolution: str) -> None: print('MyDisplay3 resolution:', resolution) class MyDisplay3(Display): def set_resolution(self, resolution: str) -> None: print('MyDisplay4 resolution:', resolution) def create_device(factory: DeviceFactory, cpu_eries: str, display_res: str, memory_size: int) -> None: """ Creates all components of a device """ print('creating components...') cpu = factory.create_cpu() cpu.set_series(cpu_eries) display = factory.create_display() display.set_resolution(display_res) memory = factory.create_memory() memory.set_capacity_in_gb(memory_size) print('building...') print('Device created!') if __name__ == "__main__": print("Creating a phone:") create_device(PhoneFactory(), 'Snapdragon-3600', '2800 * 1200', 6) print("\n") print("Creating a tablet:") create_device(TabletFactory(), 'Mediatek-880', '3840 * 2200', 8) print("\n") print("Creating a laptop:") create_device(LaptopFactory(), 'Intel-12800k', '1920 * 1080', 16) ```
🟢 Mi solución usando el patron :), en este caso la función appFactory(factory, series, capacity) usa tres parámetros para escribir tanto la serie y capacidad del producto. ```ts interface CPU { setSeries(series:string):void; } interface Memory { setCapacityInGB(capacity:number):void; } interface Display { setResolution():void; } class PhoneCPU implements CPU{ setSeries(series:string): void { return console.log('Phone CPU series: ' + series); } } class LaptopCPU implements CPU{ setSeries(series:string): void { return console.log('Laptop CPU series: ' + series); } } class TabletCPU implements CPU{ setSeries(series:string): void { return console.log('Tablet CPU series: ' + series); } } class PhoneMemory implements Memory{ setCapacityInGB(capacity:number): void { return console.log('Phone memory: ' + capacity + ' GB'); } } class LaptopMemory implements Memory{ setCapacityInGB(capacity:number): void { return console.log('Laptop memory: ' + capacity + ' GB'); } } class TabletMemory implements Memory{ setCapacityInGB(capacity:number): void { return console.log('Tablet memory: ' + capacity + ' GB'); } } class PhoneDisplay implements Display{ setResolution(): void { return console.log('Standard phone resolution : 360×640 a 414×896'); } } class LaptopDisplay implements Display{ setResolution(): void { return console.log('Standard laptop resolution: 3840 x 2160'); } } class TabletDisplay implements Display{ setResolution(): void { return console.log('Standard tablet resolution: 601×962 a 1280×800'); } } interface techAbstractFactory { createCPU(): CPU; createMemory(): Memory; createDisplay(): Display; } class PhoneFactory implements techAbstractFactory { createCPU(): CPU { return new PhoneCPU() } createMemory(): Memory { return new PhoneMemory() } createDisplay(): Display { return new PhoneDisplay() } } class LaptopFactory implements techAbstractFactory{ createCPU(): CPU { return new LaptopCPU() } createMemory(): Memory { return new LaptopMemory() } createDisplay(): Display { return new LaptopDisplay() } } class TabletFactory implements techAbstractFactory{ createCPU(): CPU { return new TabletCPU() } createMemory(): Memory { return new TabletMemory() } createDisplay(): Display { return new TabletDisplay() } } function appFactory(factory, series, capacity) { const cpu = factory.createCPU(); const memory = factory.createMemory(); const display = factory.createDisplay(); cpu.setSeries(series); memory.setCapacityInGB(capacity); display.setResolution(); } /** * Abstract the creation of factories * @param type type of tech family * @returns A tech family factory instance */ type TechFactoryType = 'phone' | 'laptop'| 'tablet'; function createFactory(type: TechFactoryType){ const factories = { phone: PhoneFactory, laptop: LaptopFactory, tablet: TabletFactory, } const Factory = factories[type]; return new Factory(); } appFactory(createFactory('phone'), 'Qualcomm Snapdragon 8 Gen 3', 60); console.log('................................'); appFactory(createFactory('laptop'), 'Lenovo 53912T', 250); ```
Excelente clase y desafio, les comparto mi solución en JS: ```js // step 1 > Base products class CPUBase { setSeries(){ return new Error ('Method CPUBase not implemented.'); } }; class DisplayBase { setResolution(resolution){ return new Error ('Method CPUBase not implemented.'); } } class MemoryBase { setCapacityInGb(gb){ return new Error ('Method CPUBase not implemented.'); } } //step 2 > Concrete products class CPU extends CPUBase { setSeries(numberSeries) { console.log(`CPU: ${numberSeries}`); } } class Display extends DisplayBase { setResolution(resolution) { console.log(`Display: ${resolution}`); } } class Memory extends MemoryBase { setCapacityInGb(gb) { console.log(`GB: ${gb}`); } } //step 3 > Concrete factory class DeviceAbstractFactory { makeCPU() { throw new Error('Method makeCPU not implemented.'); } makeDisplay(){ throw new Error('Method makeDisplay not implemented.'); } makeMemory(){ throw new Error('Method makeMemory not implemented.'); } } //step 4 > Concrete factories class PhoneFactory extends DeviceAbstractFactory { makeCPU() { return new CPU(); } makeDisplay() { return new Display(); } makeMemory() { return new Memory(); } } class LaptopFactory extends DeviceAbstractFactory { makeCPU() { return new CPU(); } makeDisplay() { return new Display(); } makeMemory() { return new Memory(); } } class TabletFactory extends DeviceAbstractFactory { makeCPU() { return new CPU(); } makeDisplay() { return new Display(); } makeMemory() { return new Memory(); } } //step 5: use function appFactory(factory, cpu, ram, resolution){ const makeCpu = factory.makeCPU(); const makeDisplay = factory.makeDisplay(); const makeMemory = factory.makeMemory(); makeCpu.setSeries(cpu); makeDisplay.setResolution(resolution); makeMemory.setCapacityInGb(ram); } function createFactory(type) { const factories = { laptop: LaptopFactory, phone: PhoneFactory, tablet: TabletFactory, }; const Factory = factories[type]; return new Factory; }; appFactory(createFactory('laptop'), 'Intel i3', 4, '4k'); appFactory(createFactory('phone'), 'AMD 7', 8, '2k'); appFactory(createFactory('tablet'), 'SnapDragon', 16, '8k'); ```// step 1 > Base productsclass CPUBase { setSeries(){ return new Error ('Method CPUBase not implemented.'); }}; class DisplayBase { setResolution(resolution){ return new Error ('Method CPUBase not implemented.'); }} class MemoryBase { setCapacityInGb(gb){ return new Error ('Method CPUBase not implemented.'); }} //step 2 > Concrete productsclass CPU extends CPUBase { setSeries(numberSeries) { console.log(`CPU: ${numberSeries}`); }} class Display extends DisplayBase { setResolution(resolution) { console.log(`Display: ${resolution}`); }} class Memory extends MemoryBase { setCapacityInGb(gb) { console.log(`GB: ${gb}`); }} //step 3 > Concrete factoryclass DeviceAbstractFactory { makeCPU() { throw new Error('Method makeCPU not implemented.'); } makeDisplay(){ throw new Error('Method makeDisplay not implemented.'); } makeMemory(){ throw new Error('Method makeMemory not implemented.'); } } //step 4 > Concrete factoriesclass PhoneFactory extends DeviceAbstractFactory { makeCPU() { return new CPU(); } makeDisplay() { return new Display(); } makeMemory() { return new Memory(); }} class LaptopFactory extends DeviceAbstractFactory { makeCPU() { return new CPU(); } makeDisplay() { return new Display(); } makeMemory() { return new Memory(); }} class TabletFactory extends DeviceAbstractFactory { makeCPU() { return new CPU(); } makeDisplay() { return new Display(); } makeMemory() { return new Memory(); }} //step 5: usefunction appFactory(factory, cpu, ram, resolution){ const makeCpu = factory.makeCPU(); const makeDisplay = factory.makeDisplay(); const makeMemory = factory.makeMemory(); makeCpu.setSeries(cpu); makeDisplay.setResolution(resolution); makeMemory.setCapacityInGb(ram);} function createFactory(type) { const factories = { laptop: LaptopFactory, phone: PhoneFactory, tablet: TabletFactory, }; const Factory = factories\[type]; return new Factory;}; appFactory(createFactory('laptop'), 'Intel i3', 4, '4k');appFactory(createFactory('phone'), 'AMD 7', 8, '2k');appFactory(createFactory('tablet'), 'SnapDragon', 16, '8k');
Adjunto resultado del reto en JS ````js // Step 1 class CPU { setSeries(series) { throw new Error("Not implemented"); } } class Memory { setCapacityInGB(capacity) { throw new Error("Not implemented"); } } class Display { setResolution(resolution) { throw new Error("Not implemented"); } } // Step 2 //CP class PhoneCPU extends CPU { setSeries(series) { console.log(`[PHONE] ${series}`); } } class LaptopCPU extends CPU { setSeries(series) { console.log(`[LAPTOP] ${series}`); } } class TabletCPU extends CPU { setSeries(series) { console.log(`[TABLET] ${series}`); } } //Memory class PhoneMemory extends Memory { setCapacityInGB(capacity) { console.log(`[PHONE] ${capacity}`); } } class LaptopMemory extends Memory { setCapacityInGB(capacity) { console.log(`[LAPTOP] ${capacity}`); } } class TabletMemory extends Memory { setCapacityInGB(capacity) { console.log(`[TABLET] ${capacity}`); } } // Resolution class PhoneResolution extends Display{ setResolution(resolution) { console.log(`[PHONE] ${resolution}`); } } class LaptopResolution extends Display{ setResolution(resolution) { console.log(`[LAPTOP] ${resolution}`); } } class TabletResolution extends Display{ setResolution(resolution) { console.log(`[TABLET] ${resolution}`); } } //Step 3 class DeviceFactory { createCPU() { throw new Error('Method not implemented!'); } createMemory() { throw new Error('Method not implemented!'); } createDisplay() { throw new Error('Method not implemented!'); } } class PhoneDeviceFactory extends DeviceFactory {a createCPU() { return new PhoneCPU(); } createMemory() { return new PhoneMemory(); } createDisplay() { return new PhoneResolution(); } } class LaptopDeviceFactory extends DeviceFactory { createCPU() { return new LaptopCPU(); } createMemory() { return new LaptopMemory(); } createDisplay() { return new LaptopResolution(); } } class TabletDeviceFactory extends DeviceFactory { createCPU() { return new TabletCPU(); } createMemory() { return new TabletMemory(); } createDisplay() { return new TabletResolution(); } } function appAbstractFactory({factory, cpuSeries, capacity, resolution}) { if (!factory) { console.log('---No factory provided ---'); return '---No factory provided ---' } const cpu = factory.createCPU(); const memory = factory.createMemory(); const display = factory.createDisplay(); cpu.setSeries(cpuSeries); memory.setCapacityInGB(capacity); display.setResolution(resolution) } function createFactory(deviceTyoe) { const devices = { 'phone': PhoneDeviceFactory, 'laptop': LaptopDeviceFactory, 'tablet': TabletDeviceFactory } const Devices = devices[deviceTyoe]; return new Devices(); } appAbstractFactory({ factory: createFactory('phone'), cpuSeries: 'Snapdragon 690', capacity: 16, resolution: '2560x1440', }) appAbstractFactory({ factory: createFactory('laptop'), cpuSeries: 'Intel Core i9', capacity: 500, resolution: '1920x1080', }) appAbstractFactory({ factory: createFactory('tablet'), cpuSeries: 'ARM Cortex-A53', capacity: 64, resolution: '1280x720', }) ```// Step 1class CPU { setSeries(series) { throw new Error("Not implemented"); }}class Memory { setCapacityInGB(capacity) { throw new Error("Not implemented"); }}class Display { setResolution(resolution) { throw new Error("Not implemented"); }} // Step 2//CPclass PhoneCPU extends CPU { setSeries(series) { console.log(`\[PHONE] ${series}`); } }class LaptopCPU extends CPU { setSeries(series) { console.log(`\[LAPTOP] ${series}`); } }class TabletCPU extends CPU { setSeries(series) { console.log(`\[TABLET] ${series}`); } }//Memoryclass PhoneMemory extends Memory { setCapacityInGB(capacity) { console.log(`\[PHONE] ${capacity}`); } }class LaptopMemory extends Memory { setCapacityInGB(capacity) { console.log(`\[LAPTOP] ${capacity}`); } }class TabletMemory extends Memory { setCapacityInGB(capacity) { console.log(`\[TABLET] ${capacity}`); } }// Resolutionclass PhoneResolution extends Display{ setResolution(resolution) { console.log(`\[PHONE] ${resolution}`); } }class LaptopResolution extends Display{ setResolution(resolution) { console.log(`\[LAPTOP] ${resolution}`); } }class TabletResolution extends Display{ setResolution(resolution) { console.log(`\[TABLET] ${resolution}`); } } //Step 3class DeviceFactory { createCPU() { throw new Error('Method not implemented!'); } createMemory() { throw new Error('Method not implemented!'); } createDisplay() { throw new Error('Method not implemented!'); }} class PhoneDeviceFactory extends DeviceFactory {a createCPU() { return new PhoneCPU(); } createMemory() { return new PhoneMemory(); } createDisplay() { return new PhoneResolution(); }}class LaptopDeviceFactory extends DeviceFactory { createCPU() { return new LaptopCPU(); } createMemory() { return new LaptopMemory(); } createDisplay() { return new LaptopResolution(); }}class TabletDeviceFactory extends DeviceFactory { createCPU() { return new TabletCPU(); } createMemory() { return new TabletMemory(); } createDisplay() { return new TabletResolution(); }} function appAbstractFactory({factory, cpuSeries, capacity, resolution}) { if (!factory) { console.log('---No factory provided ---'); return '---No factory provided ---' } const cpu = factory.createCPU(); const memory = factory.createMemory(); const display = factory.createDisplay(); cpu.setSeries(cpuSeries); memory.setCapacityInGB(capacity); display.setResolution(resolution)} function createFactory(deviceTyoe) { const devices = { 'phone': PhoneDeviceFactory, 'laptop': LaptopDeviceFactory, 'tablet': TabletDeviceFactory } const Devices = devices\[deviceTyoe]; return new Devices();} appAbstractFactory({ factory: createFactory('phone'), cpuSeries: 'Snapdragon 690', capacity: 16, resolution: '2560x1440',})appAbstractFactory({ factory: createFactory('laptop'), cpuSeries: 'Intel Core i9', capacity: 500, resolution: '1920x1080',})appAbstractFactory({ factory: createFactory('tablet'), cpuSeries: 'ARM Cortex-A53', capacity: 64, resolution: '1280x720',}) ````
```js class CPU { setSeries(serie){ console.log(`CPU series is set to ${serie}`); } } class Memory { setCapacityInGB(capacity){ console.log(`Memory capacity is set to ${capacity} GB`); } } class Display { setResolution(resolution){ console.log(`Display resolution is set to ${resolution}`); } } class AbstractFactory { createCPU() {} createMemory() {} createDisplay() {} } class PhoneFactory extends AbstractFactory { createCPU() { return new CPU(); } createMemory() { return new Memory(); } createDisplay() { return new Display(); } } class LaptopFactory extends AbstractFactory { createCPU() { return new CPU(); } createMemory() { return new Memory(); } createDisplay() { return new Display(); } } class TabletFactory extends AbstractFactory { createCPU() { return new CPU(); } createMemory() { return new Memory(); } createDisplay() { return new Display(); } } function clientCode(factory, cpuValue, memoryValue, displayValue) { const cpu = factory.createCPU(); cpu.setSeries(cpuValue); const memory = factory.createMemory(); memory.setCapacityInGB(memoryValue); const display = factory.createDisplay(); display.setResolution(displayValue); } const phoneFactory = new PhoneFactory(); clientCode(phoneFactory, 'Snapdragon', 8, '1080x1920'); const laptopFactory = new LaptopFactory(); clientCode(laptopFactory, 'Intel', 16, '1920x1080'); const tabletFactory = new TabletFactory(); clientCode(tabletFactory, 'Snapdragon', 4, '800x1280'); ```class CPU {    setSeries(serie){        console.log(`CPU series is set to ${serie}`);    }} class Memory {    setCapacityInGB(capacity){        console.log(`Memory capacity is set to ${capacity} GB`);    }} class Display {    setResolution(resolution){        console.log(`Display resolution is set to ${resolution}`);    }} class AbstractFactory {    createCPU() {}    createMemory() {}    createDisplay() {}} class PhoneFactory extends AbstractFactory {    createCPU() {        return new CPU();    }     createMemory() {        return new Memory();    }     createDisplay() {        return new Display();    }} class LaptopFactory extends AbstractFactory {    createCPU() {        return new CPU();    }     createMemory() {        return new Memory();    }     createDisplay() {        return new Display();    }} class TabletFactory extends AbstractFactory {    createCPU() {        return new CPU();    }     createMemory() {        return new Memory();    }     createDisplay() {        return new Display();    }} function clientCode(factory, cpuValue, memoryValue, displayValue) {    const cpu = factory.createCPU();    cpu.setSeries(cpuValue);     const memory = factory.createMemory();    memory.setCapacityInGB(memoryValue);     const display = factory.createDisplay();    display.setResolution(displayValue);} const phoneFactory = new PhoneFactory();clientCode(phoneFactory, 'Snapdragon', 8, '1080x1920'); const laptopFactory = new LaptopFactory();clientCode(laptopFactory, 'Intel', 16, '1920x1080'); const tabletFactory = new TabletFactory();clientCode(tabletFactory, 'Snapdragon', 4, '800x1280');
class CPU {    setSeries(serie){        console.log(`CPU series is set to ${serie}`);    }} class Memory {    setCapacityInGB(capacity){        console.log(`Memory capacity is set to ${capacity} GB`);    }} class Display {    setResolution(resolution){        console.log(`Display resolution is set to ${resolution}`);    }} class AbstractFactory {    createCPU() {}    createMemory() {}    createDisplay() {}} class PhoneFactory extends AbstractFactory {    createCPU() {        return new CPU();    }     createMemory() {        return new Memory();    }     createDisplay() {        return new Display();    }} class LaptopFactory extends AbstractFactory {    createCPU() {        return new CPU();    }     createMemory() {        return new Memory();    }     createDisplay() {        return new Display();    }} class TabletFactory extends AbstractFactory {    createCPU() {        return new CPU();    }     createMemory() {        return new Memory();    }     createDisplay() {        return new Display();    }} function clientCode(factory, cpuValue, memoryValue, displayValue) {    const cpu = factory.createCPU();    cpu.setSeries(cpuValue);     const memory = factory.createMemory();    memory.setCapacityInGB(memoryValue);     const display = factory.createDisplay();    display.setResolution(displayValue);} const phoneFactory = new PhoneFactory();clientCode(phoneFactory, 'Snapdragon', 8, '1080x1920'); const laptopFactory = new LaptopFactory();clientCode(laptopFactory, 'Intel', 16, '1920x1080'); const tabletFactory = new TabletFactory();clientCode(tabletFactory, 'Snapdragon', 4, '800x1280');
XD Yo hice un ejemplo de zombies XDDDDDDDDDDDD \------------------------- ```js // BASE class HeadZombie { useRenderHeads() { throw new Error('Method not implemented') } } class ArmsZombie { useRenderArms() { throw new Error('Method not implemented') } } class ShirtZombie { useRenderShirt() { throw new Error('Method not implemented') } } class ShoesZombie { useRenderShoes(){ throw new Error('Method not implemented') } } class TypeZombie { setTypeZombie(){ throw new Error('Method not implemented') } } // COMPORTAMIENTOS INDIVIDUALES // HEAD class HeadZombieDestroyed extends HeadZombie { useRenderHeads() { return 'HeadZombieDestroyed' } } class HeadZombieNew extends HeadZombie { useRenderHeads() { return 'HeadZombieNew' } } class HeadZombiePartial extends HeadZombie { useRenderHeads() { return 'HeadZombiePartial' } } // ARMS class ArmsZombieIntact extends ArmsZombie { useRenderArms() { return 'ArmsZombieIntact'; } } class ArmsZombieBroken extends ArmsZombie { useRenderArms() { return 'ArmsZombieBroken'; } } class ArmsZombieMissing extends ArmsZombie { useRenderArms() { return 'ArmsZombieMissing'; } } // SHIRT class ShirtZombieTattered extends ShirtZombie { useRenderShirt() { return 'ShirtZombieTattered'; } } class ShirtZombieBloody extends ShirtZombie { useRenderShirt() { return 'ShirtZombieBloody'; } } class ShirtZombieClean extends ShirtZombie { useRenderShirt() { return 'ShirtZombieClean'; } } // SHOES class ShoesZombieOld extends ShoesZombie { useRenderShoes() { return 'ShoesZombieOld'; } } class ShoesZombieTorn extends ShoesZombie { useRenderShoes() { return 'ShoesZombieTorn'; } } class ShoesZombieMissing extends ShoesZombie { useRenderShoes() { return 'ShoesZombieMissing'; } } // TYPE class TypeZombieWalker extends TypeZombie { setTypeZombie() { return 'TypeZombieWalker'; } } class TypeZombieRunner extends TypeZombie { setTypeZombie() { return 'TypeZombieRunner'; } } class TypeZombieCrawler extends TypeZombie { setTypeZombie() { return 'TypeZombieCrawler'; } } // FACTORY class ZombieAbstractFactory { createHead(){ throw new Error('Method not implemented') } createArms(){ throw new Error('Method not implemented') } createShirt(){ throw new Error('Method not implemented') } createShoes(){ throw new Error('Method not implemented') } createType(){ throw new Error('Method not implemented') } } // NEW ZOMBIES class ZombieRunnerWornOut extends ZombieAbstractFactory{ createHead() { return new HeadZombieDestroyed()} createArms() { return new ArmsZombieBroken()} createShirt() { return new ShirtZombieTattered()} createShoes() { return new ShoesZombieOld()} createType() { return new TypeZombieRunner()} } class ZombieWalkerNew extends ZombieAbstractFactory { createHead() { return new HeadZombieNew(); } createArms() { return new ArmsZombieIntact(); } createShirt() { return new ShirtZombieClean(); } createShoes() { return new ShoesZombieNew(); } createType() { return new TypeZombieWalker(); } } class ZombieCrawlerTattered extends ZombieAbstractFactory { createHead() { return new HeadZombiePartial(); } createArms() { return new ArmsZombieMissing(); } createShirt() { return new ShirtZombieBloody(); } createShoes() { return new ShoesZombieTorn(); } createType() { return new TypeZombieCrawler(); } } class ZombieRunnerIntact extends ZombieAbstractFactory { createHead() { return new HeadZombieNew(); } createArms() { return new ArmsZombieIntact(); } createShirt() { return new ShirtZombieClean(); } createShoes() { return new ShoesZombieNew(); } createType() { return new TypeZombieRunner(); } } class ZombieWalkerDestroyed extends ZombieAbstractFactory { createHead() { return new HeadZombieDestroyed(); } createArms() { return new ArmsZombieBroken(); } createShirt() { return new ShirtZombieTattered(); } createShoes() { return new ShoesZombieOld(); } createType() { return new TypeZombieWalker(); } } class ZombieCrawlerNew extends ZombieAbstractFactory { createHead() { return new HeadZombieNew(); } createArms() { return new ArmsZombieIntact(); } createShirt() { return new ShirtZombieClean(); } createShoes() { return new ShoesZombieNew(); } createType() { return new TypeZombieCrawler(); } } class ZombieRunnerBloody extends ZombieAbstractFactory { createHead() { return new HeadZombiePartial(); } createArms() { return new ArmsZombieMissing(); } createShirt() { return new ShirtZombieBloody(); } createShoes() { return new ShoesZombieTorn(); } createType() { return new TypeZombieRunner(); } } class ZombieWalkerPartial extends ZombieAbstractFactory { createHead() { return new HeadZombiePartial(); } createArms() { return new ArmsZombieBroken(); } createShirt() { return new ShirtZombieBloody(); } createShoes() { return new ShoesZombieTorn(); } createType() { return new TypeZombieWalker(); } } class ZombieCrawlerOld extends ZombieAbstractFactory { createHead() { return new HeadZombieDestroyed(); } createArms() { return new ArmsZombieMissing(); } createShirt() { return new ShirtZombieTattered(); } createShoes() { return new ShoesZombieOld(); } createType() { return new TypeZombieCrawler(); } } class ZombieRunnerTattered extends ZombieAbstractFactory { createHead() { return new HeadZombiePartial(); } createArms() { return new ArmsZombieBroken(); } createShirt() { return new ShirtZombieTattered(); } createShoes() { return new ShoesZombieTorn(); } createType() { return new TypeZombieRunner(); } } class ZombieWalkerBloody extends ZombieAbstractFactory { createHead() { return new HeadZombieNew(); } createArms() { return new ArmsZombieIntact(); } createShirt() { return new ShirtZombieBloody(); } createShoes() { return new ShoesZombieNew(); } createType() { return new TypeZombieWalker(); } } class ZombieCrawlerBroken extends ZombieAbstractFactory { createHead() { return new HeadZombieDestroyed(); } createArms() { return new ArmsZombieBroken(); } createShirt() { return new ShirtZombieTattered(); } createShoes() { return new ShoesZombieOld(); } createType() { return new TypeZombieCrawler(); } } class ZombieRunnerClean extends ZombieAbstractFactory { createHead() { return new HeadZombieNew(); } createArms() { return new ArmsZombieIntact(); } createShirt() { return new ShirtZombieClean(); } createShoes() { return new ShoesZombieNew(); } createType() { return new TypeZombieRunner(); } } class ZombieWalkerMissing extends ZombieAbstractFactory { createHead() { return new HeadZombiePartial(); } createArms() { return new ArmsZombieMissing(); } createShirt() { return new ShirtZombieBloody(); } createShoes() { return new ShoesZombieTorn(); } createType() { return new TypeZombieWalker(); } } class ZombieCrawlerIntact extends ZombieAbstractFactory { createHead() { return new HeadZombieNew(); } createArms() { return new ArmsZombieIntact(); } createShirt() { return new ShirtZombieClean(); } createShoes() { return new ShoesZombieNew(); } createType() { return new TypeZombieCrawler(); } } // FACTORY function appZombieRenderFactory(factory){ const renderZombie = { head: factory.createHead(), arms: factory.createArms(), shirt: factory.createShirt(), shoes: factory.createShoes(), type: factory.createType(), } return renderZombie } // POSIBILITY_ZOMBIES function renderZombie(type) { const zombiesList = { runnerWornOut : ZombieRunnerWornOut , walkerNew : ZombieWalkerNew , crawlerTattered : ZombieCrawlerTattered , runnerIntact : ZombieRunnerIntact , walkerDestroyed : ZombieWalkerDestroyed , crawlerNew : ZombieCrawlerNew , runnerBloody : ZombieRunnerBloody , walkerPartial : ZombieWalkerPartial , crawlerOld : ZombieCrawlerOld , runnerTattered : ZombieRunnerTattered , walkerBloody : ZombieWalkerBloody , crawlerBroken : ZombieCrawlerBroken , runnerClean : ZombieRunnerClean , walkerMissing : ZombieWalkerMissing , crawlerIntact : ZombieCrawlerIntact , } const Zombie = zombiesList[type] if (!Zombie) { throw new Error(`This zombie '${type}' is not recognized`); } return new Zombie() } console.log(appZombieRenderFactory(renderZombie('runnerWornOut'))) console.log(appZombieRenderFactory(renderZombie('walkerPartial'))) console.log(appZombieRenderFactory(renderZombie('walkerMissing'))) console.log(appZombieRenderFactory(renderZombie('crawlerTattered'))) ```
Les dejo mi código en Typescript por si alguién le interesa y quiera pasarle diferentes valores a la cpu y memory: ```js interface CPU { setSeries(series: string): void; } interface Memory { setCapacityInGB(gb: number): void; } interface Display { setResolution(): void; } interface AbstractFactoryDevice { createCPU(): CPU; createMemory(): Memory; createDisplay(): Display; } /* CPU */ class PhoneCPU implements CPU { setSeries(series: string): void { console.log(`Phone ${series}`); } } class LaptopCPU implements CPU { setSeries(series: string): void { console.log(`Laptop ${series}`); } } class TabletCPU implements CPU { setSeries(series: string): void { console.log(`Tablet ${series}`); } } /* Memory */ class PhoneMemory implements Memory { setCapacityInGB(gb: number): void { console.log(`Phone ${gb} gb`); } } class LaptopMemory implements Memory { setCapacityInGB(gb: number): void { console.log(`Laptop ${gb} gb`); } } class TabletMemory implements Memory { setCapacityInGB(gb: number): void { console.log(`Tablet ${gb} gb`); } } /* Display */ class PhoneDisplay implements Display { setResolution(): void { console.log(`Phone resolution`); } } class LaptopDisplay implements Display { setResolution(): void { console.log(`Laptop resolution`); } } class TabletDisplay implements Display { setResolution(): void { console.log(`Tablet resolution`); } } /* Phone */ class PhoneFactory implements AbstractFactoryDevice { createCPU(): CPU { return new PhoneCPU(); } createDisplay(): Display { return new PhoneDisplay(); } createMemory(): Memory { return new PhoneMemory(); } } /* Laptop */ class LaptopFactory implements AbstractFactoryDevice { createCPU(): CPU { return new LaptopCPU(); } createDisplay(): Display { return new LaptopDisplay(); } createMemory(): Memory { return new LaptopMemory(); } } /* Tablet */ class TabletFactory implements AbstractFactoryDevice { createCPU(): CPU { return new TabletCPU(); } createDisplay(): Display { return new TabletDisplay(); } createMemory(): Memory { return new TabletMemory(); } } interface appDeviceFactoryProps { factory: AbstractFactoryDevice; cpuDevice: string; memoryDevice: number; } function appDeviceFactory({ factory, cpuDevice, memoryDevice, }: appDeviceFactoryProps) { const cpu = factory.createCPU(); const memory = factory.createMemory(); const display = factory.createDisplay(); cpu.setSeries(cpuDevice); memory.setCapacityInGB(memoryDevice); display.setResolution(); } type typeDevice = "phone" | "laptop" | "tablet"; function createDeviceFactory(type: typeDevice) { const devices = { phone: PhoneFactory, laptop: LaptopFactory, tablet: TabletFactory, }; const Factory = devices[type]; return new Factory(); } appDeviceFactory({ factory: createDeviceFactory("phone"), cpuDevice: "i7", memoryDevice: 512, }); appDeviceFactory({ factory: createDeviceFactory("laptop"), cpuDevice: "i3", memoryDevice: 1024, }); appDeviceFactory({ factory: createDeviceFactory("tablet"), cpuDevice: "i6", memoryDevice: 920, }); ```
```js /** * 1. Declare base products classes/interfaces for each product * in the catalog. * * Base products: * - CPU * - Memory * - Display * * 2. Implement concrete products classes that inherits/implements * base products classes/interfaces, the number of concrete products * will depend on the number of families. * * Concrete products: * - PhoneCPU * - PhoneMemory * - PhoneDisplay * - LaptopCPU * - LaptopMemory * - LaptopDisplay * - TabletCPU * - TabletMemory * - TabletDisplay * * 3. Declare abstract factory class/interface that declare creation * methods for each base product. The return value could be the base * products types or concrete products types. * * Abstract Factory: * - AccessoryFactory * * createCPUAccessory(): CPU * * createMemoryAccessory(): Memory * * createDisplayAccessory(): Display * * 4. Create concrete factories that implements/inherits from the * abstract factory behavior and implements all the products creation * methods. The number of concrete factories will depend of the number * of product families. * * Concrete Factories: * - PhoneFactory * - LaptopFactory * - TabletFactory * */ // Step 1 interface CPU { setSeries(series: string): void; } interface Memory { setCapacityInGB(capacity: number): void; } interface Display { setResolution(): void; } //Step 2 class PhoneCPU implements CPU { setSeries(series) { console.log(`[CPU] ${series} phone series`); } } class PhoneMemory implements Memory { setCapacityInGB(capacity) { console.log(`[MEMORY] ${capacity} phone capacity in GB`); } } class PhoneDisplay implements Display { setResolution() { console.log(`[DISPLAY] phone resolution`); } } class LaptopCPU implements CPU { setSeries(series) { console.log(`[CPU] ${series} Laptop series`); } } class LaptopMemory implements Memory { setCapacityInGB(capacity) { console.log(`[MEMORY] ${capacity} Laptop capacity in GB`); } } class LaptopDisplay implements Display { setResolution() { console.log(`[DISPLAY] Laptop resolution`); } } class TabletCPU implements CPU { setSeries(series) { console.log(`[CPU] ${series} Tablet series`); } } class TabletMemory implements Memory { setCapacityInGB(capacity) { console.log(`[MEMORY] ${capacity} Tablet capacity in GB`); } } class TabletDisplay implements Display { setResolution() { console.log(`[DISPLAY] Tablet resolution`); } } // Step 3 interface AccessoryFactory { createCPUAccessory(): CPU; createMemoryAccessory(): Memory; createDisplayAccessory(): Display; } // Step 4 class PhoneFactory implements AccessoryFactory { createCPUAccessory(): CPU { return new PhoneCPU(); } createMemoryAccessory(): Memory { return new PhoneMemory(); } createDisplayAccessory(): Display { return new PhoneDisplay(); } } class LaptopFactory implements AccessoryFactory { createCPUAccessory(): CPU { return new LaptopCPU(); } createMemoryAccessory(): Memory { return new LaptopMemory(); } createDisplayAccessory(): Display { return new LaptopDisplay(); } } class TabletFactory implements AccessoryFactory { createCPUAccessory(): CPU { return new TabletCPU(); } createMemoryAccessory(): Memory { return new TabletMemory(); } createDisplayAccessory(): Display { return new TabletDisplay(); } } function appAccessoryFactory(factory: AccessoryFactory) { console.log('--- [TS] Calling appAbstractFactory ---\n'); if (!factory) { console.log('--- No factory provided ---'); return; } const cpu: CPU = factory.createCPUAccessory(); const memory: Memory = factory.createMemoryAccessory(); const display: Display = factory.createDisplayAccessory(); cpu.setSeries('12345'); memory.setCapacityInGB(64); display.setResolution(); } appAccessoryFactory(new PhoneFactory()); appAccessoryFactory(new LaptopFactory()); appAccessoryFactory(new TabletFactory()); ```
Debo confesar que tuve bastante confusión respecto a cómo hacer las distintas clases de los productos, pero hice el esfuerzo honesto de entender y armar las líneas. Consulté inteligencia artificial y los trabajos de los compañeros que me guiaron con sus proyectos./\*PASO 1\*/class BaseCPU {    setSeries() {        throw new Error('This method has not been implemented')    } }class BaseMemory {    setCapacityInGB() {        throw new Error('This method has not been implemented')    } }class BaseDisplay {    setResolution() {        throw new Error('This method has not been implemented')    } } /\*PASO 2\*/ //CPUclass PhoneCPU extends BaseCPU {    setSeries() {        console.log('\[Phone]: La serie es XXX')    } } class LaptopCPU extends BaseCPU {    setSeries() {        console.log('\[Laptop]: La serie es XXX')    } } class TabletCPU extends BaseCPU {    setSeries() {        console.log('\[Display]: La serie es XXX')    } } //Memoryclass PhoneMemory extends BaseMemory {    setCapacityInGB() {        console.log('\[Phone]: La capacidad es de 18 GB')    } } class LaptopMemory extends BaseMemory {    setCapacityInGB() {        console.log('\[Laptop]: La capacidad es de 18 GB')    } } class TabletMemory extends BaseMemory {    setCapacityInGB() {        console.log('\[Display]: La capacidad es de 18 GB')    } } //Displayclass PhoneDisplay extends BaseDisplay {    setResolution() {        console.log('\[Phone]: La resolución es fantástica')    } } class LaptopDisplay extends BaseDisplay {    setResolution() {        console.log('\[Laptop]: La resolución es fantástica')    } } class TabletDisplay extends BaseDisplay {    setResolution() {        console.log('\[Tablet]: La resolución es fantástica')    } } /\*PASO 3\*//\*Declare abstract factory class that declares creation methods for each base product.\*/ class PieceAbstractFactory {    createCPU(){        throw new Error('Method not implemented')    }    createMemory(){        throw new Error('Method not implemented')    }    createDisplay(){        throw new Error('Method not implemented')    }}/\*4. Create concrete factories that implement all of the defined creation methods in the abstract factory.\*/ class PhoneFactory extends PieceAbstractFactory{    createCPU() {        return new PhoneCPU();    }    createMemory() {        return new PhoneMemory();    }    createDisplay() {        return new PhoneDisplay();    } } class LaptopFactory extends PieceAbstractFactory{    createCPU() {        return new LaptopCPU();    }    createMemory() {        return new LaptopMemory();    }    createDisplay() {        return new LaptopDisplay();    } } class TabletFactory extends PieceAbstractFactory{    createCPU() {        return new TabletCPU();    }    createMemory() {        return new TabletMemory();    }    createDisplay() {        return new TabletDisplay();    } }  function buildDevice(factory) {    const cpu = factory.createCPU();    const memory = factory.createMemory();    const display = factory.createDisplay();     cpu.setSeries();    memory.setCapacityInGB();    display.setResolution();}const phoneFactory = new PhoneFactory();console.log('Building Phone:');buildDevice(phoneFactory); const laptopFactory = new LaptopFactory();console.log('\nBuilding Laptop:');buildDevice(laptopFactory); const tabletFactory = new TabletFactory();console.log('\nBuilding Tablet:');buildDevice(tabletFactory);```js /*PASO 1*/ class BaseCPU { setSeries() { throw new Error('This method has not been implemented') } } class BaseMemory { setCapacityInGB() { throw new Error('This method has not been implemented') } } class BaseDisplay { setResolution() { throw new Error('This method has not been implemented') } } /*PASO 2*/ //CPU class PhoneCPU extends BaseCPU { setSeries() { console.log('[Phone]: La serie es XXX') } } class LaptopCPU extends BaseCPU { setSeries() { console.log('[Laptop]: La serie es XXX') } } class TabletCPU extends BaseCPU { setSeries() { console.log('[Display]: La serie es XXX') } } //Memory class PhoneMemory extends BaseMemory { setCapacityInGB() { console.log('[Phone]: La capacidad es de 18 GB') } } class LaptopMemory extends BaseMemory { setCapacityInGB() { console.log('[Laptop]: La capacidad es de 18 GB') } } class TabletMemory extends BaseMemory { setCapacityInGB() { console.log('[Display]: La capacidad es de 18 GB') } } //Display class PhoneDisplay extends BaseDisplay { setResolution() { console.log('[Phone]: La resolución es fantástica') } } class LaptopDisplay extends BaseDisplay { setResolution() { console.log('[Laptop]: La resolución es fantástica') } } class TabletDisplay extends BaseDisplay { setResolution() { console.log('[Tablet]: La resolución es fantástica') } } /*PASO 3*/ /*Declare abstract factory class that declares creation methods for each base product.*/ class PieceAbstractFactory { createCPU(){ throw new Error('Method not implemented') } createMemory(){ throw new Error('Method not implemented') } createDisplay(){ throw new Error('Method not implemented') } } /*4. Create concrete factories that implement all of the defined creation methods in the abstract factory. */ class PhoneFactory extends PieceAbstractFactory{ createCPU() { return new PhoneCPU(); } createMemory() { return new PhoneMemory(); } createDisplay() { return new PhoneDisplay(); } } class LaptopFactory extends PieceAbstractFactory{ createCPU() { return new LaptopCPU(); } createMemory() { return new LaptopMemory(); } createDisplay() { return new LaptopDisplay(); } } class TabletFactory extends PieceAbstractFactory{ createCPU() { return new TabletCPU(); } createMemory() { return new TabletMemory(); } createDisplay() { return new TabletDisplay(); } } function buildDevice(factory) { const cpu = factory.createCPU(); const memory = factory.createMemory(); const display = factory.createDisplay(); cpu.setSeries(); memory.setCapacityInGB(); display.setResolution(); } const phoneFactory = new PhoneFactory(); console.log('Building Phone:'); buildDevice(phoneFactory); const laptopFactory = new LaptopFactory(); console.log('\nBuilding Laptop:'); buildDevice(laptopFactory); const tabletFactory = new TabletFactory(); console.log('\nBuilding Tablet:'); buildDevice(tabletFactory); ```