Factory Method (Фабричный метод)

Паттерн проектирования Factory Method

Паттерн проектирования Factory Method

Описание Factory Method

Фабричный метод (англ. Factory Method также известен как Виртуальный конструктор (англ. Virtual Constructor)) — порождающий шаблон проектирования, предоставляющий подклассам интерфейс для создания экземпляров некоторого класса. В момент создания наследники могут определить, какой класс создавать. Иными словами, Фабрика делегирует создание объектов наследникам родительского класса. Это позволяет использовать в коде программы не специфические классы, а манипулировать абстрактными объектами на более высоком уровне.

Определяет интерфейс для создания объекта, но оставляет подклассам решение о том, какой класс инстанцировать. Фабричный метод позволяет классу делегировать создание подклассов. Используется, когда:

Структура

Примеры реализации

// Factory Method Pattern in JavaScript
class Product {
    operation() {
        throw new Error('Method must be implemented');
    }
}

class ConcreteProductA extends Product {
    operation() {
        return 'ConcreteProductA operation';
    }
}

class ConcreteProductB extends Product {
    operation() {
        return 'ConcreteProductB operation';
    }
}

class Creator {
    factoryMethod() {
        throw new Error('Method must be implemented');
    }
    
    someOperation() {
        const product = this.factoryMethod();
        return product.operation();
    }
}

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

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

// Usage
const creatorA = new ConcreteCreatorA();
const creatorB = new ConcreteCreatorB();

console.log(creatorA.someOperation());
console.log(creatorB.someOperation());
// Factory Method Pattern in C++
#include <iostream>
#include <memory>

class Product {
public:
    virtual ~Product() = default;
    virtual std::string operation() = 0;
};

class ConcreteProductA : public Product {
public:
    std::string operation() override {
        return "ConcreteProductA operation";
    }
};

class ConcreteProductB : public Product {
public:
    std::string operation() override {
        return "ConcreteProductB operation";
    }
};

class Creator {
public:
    virtual ~Creator() = default;
    virtual std::unique_ptr<Product> factoryMethod() = 0;
    
    std::string someOperation() {
        auto product = factoryMethod();
        return product->operation();
    }
};

class ConcreteCreatorA : public Creator {
public:
    std::unique_ptr<Product> factoryMethod() override {
        return std::make_unique<ConcreteProductA>();
    }
};

class ConcreteCreatorB : public Creator {
public:
    std::unique_ptr<Product> factoryMethod() override {
        return std::make_unique<ConcreteProductB>();
    }
};
// Factory Method Pattern in Go
package main

import "fmt"

type Product interface {
    Operation() string
}

type ConcreteProductA struct{}

func (p *ConcreteProductA) Operation() string {
    return "ConcreteProductA operation"
}

type ConcreteProductB struct{}

func (p *ConcreteProductB) Operation() string {
    return "ConcreteProductB operation"
}

type Creator interface {
    FactoryMethod() Product
    SomeOperation() string
}

type ConcreteCreatorA struct{}

func (c *ConcreteCreatorA) FactoryMethod() Product {
    return &ConcreteProductA{}
}

func (c *ConcreteCreatorA) SomeOperation() string {
    product := c.FactoryMethod()
    return product.Operation()
}

type ConcreteCreatorB struct{}

func (c *ConcreteCreatorB) FactoryMethod() Product {
    return &ConcreteProductB{}
}

func (c *ConcreteCreatorB) SomeOperation() string {
    product := c.FactoryMethod()
    return product.Operation()
}

// Usage
func main() {
    creatorA := &ConcreteCreatorA{}
    creatorB := &ConcreteCreatorB{}
    
    fmt.Println(creatorA.SomeOperation())
    fmt.Println(creatorB.SomeOperation())
}
# Factory Method Pattern in Python
from abc import ABC, abstractmethod

class Product(ABC):
    @abstractmethod
    def operation(self):
        pass

class ConcreteProductA(Product):
    def operation(self):
        return "ConcreteProductA operation"

class ConcreteProductB(Product):
    def operation(self):
        return "ConcreteProductB operation"

class Creator(ABC):
    @abstractmethod
    def factory_method(self):
        pass
    
    def some_operation(self):
        product = self.factory_method()
        return product.operation()

class ConcreteCreatorA(Creator):
    def factory_method(self):
        return ConcreteProductA()

class ConcreteCreatorB(Creator):
    def factory_method(self):
        return ConcreteProductB()

# Usage
if __name__ == "__main__":
    creator_a = ConcreteCreatorA()
    creator_b = ConcreteCreatorB()
    
    print(creator_a.some_operation())
    print(creator_b.some_operation())
<?php
// Factory Method Pattern in PHP
abstract class Product {
    abstract public function operation(): string;
}

class ConcreteProductA extends Product {
    public function operation(): string {
        return "ConcreteProductA operation";
    }
}

class ConcreteProductB extends Product {
    public function operation(): string {
        return "ConcreteProductB operation";
    }
}

abstract class Creator {
    abstract public function factoryMethod(): Product;
    
    public function someOperation(): string {
        $product = $this->factoryMethod();
        return $product->operation();
    }
}

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

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

// Usage
$creatorA = new ConcreteCreatorA();
$creatorB = new ConcreteCreatorB();

echo $creatorA->someOperation() . "\n";
echo $creatorB->someOperation() . "\n";
?>