Abstract Factory

Паттерн "Абстрактная фабрика" (Abstract Factory) предоставляет интерфейс для создания семейств взаимосвязанных объектов с определенными интерфейсами без указания конкретных типов данных объектов.

Применение:
1) Когда система не должна зависеть от способа создания и компоновки новых объектов
2) Когда создаваемые объекты должны использоваться вместе и являются взаимосвязанными

Пример:

interface Product {
    public function getName();
}

abstract class AbstractFactory {

    public static function getFactory($factory_id) {
        switch ($factory_id) {
            case 1:
                return new FirstFactory();
            case 2:
                return new SecondFactory();
        }
        throw new Exception('Bad config');
    }

    abstract public function getProduct();
}

class FirstFactory extends AbstractFactory {
    public function getProduct() {
        return new FirstProduct();
    }
}
class FirstProduct implements Product {
    public function getName() {
        return 'The product from the first factory';
    }
}

class SecondFactory extends AbstractFactory {
    public function getProduct() {
        return new SecondProduct();
    }
}
class SecondProduct implements Product {
    public function getName() {
        return 'The product from second factory';
    }
}

$firstProduct = AbstractFactory::getFactory(1)->getProduct();
$secondProduct = AbstractFactory::getFactory(2)->getProduct();

print_r($firstProduct->getName()); // The first product from the first factory
print_r($secondProduct->getName()); // Second product from second factory