Abstract Factory (Абстрактная фабрика)

Паттерн проектирования Active Record

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

Описание Abstract Factory

Абстрактная фабрика (англ. Abstract factory) — порождающий шаблон проектирования, предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, не специфицируя их конкретных классов. Шаблон реализуется созданием абстрактного класса Factory, который представляет собой интерфейс для создания компонентов системы (например, для оконного интерфейса он может создавать окна и кнопки). Затем пишутся классы, реализующие этот интерфейс.

Предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, не специфицируя их конкретных классов.

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

// Abstract Factory Pattern in JavaScript
class AbstractFactory {
    createProductA() {
        throw new Error('Method must be implemented');
    }
    
    createProductB() {
        throw new Error('Method must be implemented');
    }
}

class ConcreteFactory1 extends AbstractFactory {
    createProductA() {
        return new ConcreteProductA1();
    }
    
    createProductB() {
        return new ConcreteProductB1();
    }
}

class ConcreteProductA1 {
    operation() {
        return 'Product A1 operation';
    }
}

class ConcreteProductB1 {
    operation() {
        return 'Product B1 operation';
    }
}

// Usage
const factory = new ConcreteFactory1();
const productA = factory.createProductA();
const productB = factory.createProductB();
// Abstract Factory Pattern in C++
#include <iostream>
#include <memory>

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

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

// Abstract Factory
class AbstractFactory {
public:
    virtual ~AbstractFactory() = default;
    virtual std::unique_ptr<AbstractProductA> createProductA() = 0;
    virtual std::unique_ptr<AbstractProductB> createProductB() = 0;
};

// Concrete Products
class ConcreteProductA1 : public AbstractProductA {
public:
    std::string operation() override {
        return "Product A1 operation";
    }
};

class ConcreteProductB1 : public AbstractProductB {
public:
    std::string operation() override {
        return "Product B1 operation";
    }
};

// Concrete Factory
class ConcreteFactory1 : public AbstractFactory {
public:
    std::unique_ptr<AbstractProductA> createProductA() override {
        return std::make_unique<ConcreteProductA1>();
    }
    
    std::unique_ptr<AbstractProductB> createProductB() override {
        return std::make_unique<ConcreteProductB1>();
    }
};
// Abstract Factory Pattern in Go
package main

import "fmt"

// Abstract Product interfaces
type ProductA interface {
    Operation() string
}

type ProductB interface {
    Operation() string
}

// Abstract Factory interface
type AbstractFactory interface {
    CreateProductA() ProductA
    CreateProductB() ProductB
}

// Concrete Products
type ConcreteProductA1 struct{}

func (p *ConcreteProductA1) Operation() string {
    return "Product A1 operation"
}

type ConcreteProductB1 struct{}

func (p *ConcreteProductB1) Operation() string {
    return "Product B1 operation"
}

// Concrete Factory
type ConcreteFactory1 struct{}

func (f *ConcreteFactory1) CreateProductA() ProductA {
    return &ConcreteProductA1{}
}

func (f *ConcreteFactory1) CreateProductB() ProductB {
    return &ConcreteProductB1{}
}

// Usage
func main() {
    factory := &ConcreteFactory1{}
    productA := factory.CreateProductA()
    productB := factory.CreateProductB()
    
    fmt.Println(productA.Operation())
    fmt.Println(productB.Operation())
}
# Abstract Factory Pattern in Python
from abc import ABC, abstractmethod

# Abstract Products
class AbstractProductA(ABC):
    @abstractmethod
    def operation(self):
        pass

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

# Abstract Factory
class AbstractFactory(ABC):
    @abstractmethod
    def create_product_a(self):
        pass
    
    @abstractmethod
    def create_product_b(self):
        pass

# Concrete Products
class ConcreteProductA1(AbstractProductA):
    def operation(self):
        return "Product A1 operation"

class ConcreteProductB1(AbstractProductB):
    def operation(self):
        return "Product B1 operation"

# Concrete Factory
class ConcreteFactory1(AbstractFactory):
    def create_product_a(self):
        return ConcreteProductA1()
    
    def create_product_b(self):
        return ConcreteProductB1()

# Usage
if __name__ == "__main__":
    factory = ConcreteFactory1()
    product_a = factory.create_product_a()
    product_b = factory.create_product_b()
    
    print(product_a.operation())
    print(product_b.operation())
<?php
// Abstract Factory Pattern in PHP

// Abstract Products
abstract class AbstractProductA {
    abstract public function operation(): string;
}

abstract class AbstractProductB {
    abstract public function operation(): string;
}

// Abstract Factory
abstract class AbstractFactory {
    abstract public function createProductA(): AbstractProductA;
    abstract public function createProductB(): AbstractProductB;
}

// Concrete Products
class ConcreteProductA1 extends AbstractProductA {
    public function operation(): string {
        return "Product A1 operation";
    }
}

class ConcreteProductB1 extends AbstractProductB {
    public function operation(): string {
        return "Product B1 operation";
    }
}

// Concrete Factory
class ConcreteFactory1 extends AbstractFactory {
    public function createProductA(): AbstractProductA {
        return new ConcreteProductA1();
    }
    
    public function createProductB(): AbstractProductB {
        return new ConcreteProductB1();
    }
}

// Usage
$factory = new ConcreteFactory1();
$productA = $factory->createProductA();
$productB = $factory->createProductB();

echo $productA->operation() . "\n";
echo $productB->operation() . "\n";
?>

Применение:

Источник

Паттерн описан Андреем Болониным.