Дисциплины - Объектно-ориентированное программирование

Шаблоны проектирования практических задач - Порождающие шаблоны проектирования - Абстрактная фабрика

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

Абстрактную фабрику можно определить по методам, возвращающим фабрику, которая, в свою очередь, используется для создания конкретных продуктов, возвращая их через абстрактные типы или интерфейсы.

В разных языках программирования существуют различные подходы в реализации решений абстрактной фабрики, однако большинство решений базируется на взаимодействии следующих классов участников:

  • Класс абстрактная фафбрика. Объявляет интерфейс для операций, создающих абстрактные объекты-продукты;
  • Класс конкретная фабрика. Реализует операции абстрактной фабрики;
  • Класс абстрактный продукт. Объявляет интерфейс для объекта продукта;
  • Класс конкретный продукт. Реализует операции абстрактного продукта.

Абстрактная фабрика в JavaScript

Итак, у нас имеется несколько классов, реализующих метод с одним и тем же именем. Предположим, это классы, создающие двери: класс, реализующий деревянные двери, и класс реализующий железные двери.

class WoodenDoor {
    getDescription() {
        console.log('I am a wooden door')
    }
}

class IronDoor {
    getDescription() {
        console.log('I am an iron door')
    }
}

Так же имеются узкие специалисты, создающие либо деревянные двери (класс Welder), либо железные (класс Carpenter).

class Welder {
    getDescription() {
        console.log('I can only fit iron doors')
    }
}

class Carpenter {
    getDescription() {
        console.log('I can only fit wooden doors')
    }
}

Реализуем фабрики. В комплекте с каждой дверью идет нужный мастер:

// Деревянная фабрика возвращает плотника и деревянную дверь
class WoodenDoorFactory {
    makeDoor(){
        return new WoodenDoor()
    }

    makeFittingExpert() {
        return new Carpenter()
    }
}

// Железная фабрика возвращает сварщика и железную дверь
class IronDoorFactory {
    makeDoor(){
        return new IronDoor()
    }

    makeFittingExpert() {
        return new Welder()
    }
}

Теперь, используя фабрики, создадим железную и деревянные двери:

woodenFactory = new WoodenDoorFactory()

door = woodenFactory.makeDoor()
expert = woodenFactory.makeFittingExpert()

door.getDescription()  // I am a wooden door
expert.getDescription() // I can only fit wooden doors

ironFactory = new IronDoorFactory()

door = ironFactory.makeDoor()
expert = ironFactory.makeFittingExpert()

door.getDescription()  // I am an iron door
expert.getDescription() // I can only fit iron doors

Абстрактная фабрика в PHP и Laravel

Известно несколько реализаций абстрактной фабрики в PHP. С помощью интерфейса:

interface Product{
    public function GetName();
}
 
class ConcreteProductA implements Product{
    public function GetName() { return "ProductA"; }
} 
 
class ConcreteProductB implements Product{
    public function GetName() { return "ProductB"; }
}
 
interface Creator{
    public function FactoryMethod();
} 
 
class ConcreteCreatorA implements Creator{
    public function FactoryMethod() { return new ConcreteProductA(); }
}

class ConcreteCreatorB implements Creator{
    public function FactoryMethod() { return new ConcreteProductB(); }
}

// An array of creators
$creators = array( new ConcreteCreatorA(), new ConcreteCreatorB() );
// Iterate over creators and create products
foreach ($creators as $creator) {
    $products[] = $creator->FactoryMethod()->getName();
}
 
echo var_export($products);

Рассмотрим еще один вариант реализации шаблона абстрактной фабрики в PHP, с помощью абстрактного класса:

abstract class Animal
{
    // фабричный метод, который на основе типа возвращает объект
    public static function initial($animal)
    {
        return new $animal();
    }
    abstract public function voice();
}

class Lion extends Animal
{
    public function voice()
    {
        echo 'Rrrrrrrr i\'m the lion 
' . PHP_EOL;
    }
}

class Cat extends Animal
{
    public function voice()
    {
        echo 'Meow, meow i\'m the kitty 
' . PHP_EOL;
    }
}

$animal1 = Animal::initial('Lion');
$animal2 = Animal::initial('Cat');

$animal1->voice();
$animal2->voice();

Абстрактная фабрика также может быть реализована с помощью интерфейса. Пример:

interface PhoneFactory
{
  public createPhone();
}

class AndroidFactory implements PhoneFactory
{
  public createPhone()
  {
    return new \AndroidPhone();
  }
}

class IPhoneFactory implements PhoneFactory
{
  public createPhone()
  {
    return new \IPhone();
  }
}

if ($user->wantsIPhone()) {
  $factory = new IPhoneFactory;
} else {
  $factory = new AndroidFactory;
}

$phone = factory->createPhone();

Количество комментариев: 0

Для того, чтобы оставить коментарий необходимо зарегистрироваться
814301 БГУИР
814302 БГУИР
814303 БГУИР
894351 БГУИР
90421 БГУИР


Изображения Видео

1. Абстрактная фабрика https://www.youtube.com/watch?v=1mVONOCxfLg
2. Фабричный метод https://www.youtube.com/watch?v=5UqUDR6_2cY
3. Шаблон декоратор https://www.youtube.com/watch?v=Lwb9bm8yKD0
4. Dessign patterns on PHP https://github.com/domnikl/DesignPatternsPHP
5. Приёмы объектно-ориентированного проектирования. Паттерны проектирования Э. Гамма, Р. Хелм, Р. Джонсон, Д. Влиссидес; [пер. с англ.: А. Слинкин науч. ред.: Н. Шалаев]. — Санкт-Петербург [и др.] : Питер, 2014. — 366 с. : ил. ; 24 см.
6. Приемы объектно-ориентированного проектирования. Паттерны проектирования Э. Гамма, Р. Хелм, Р. Джонсон, Д. Влиссидес; [пер. с англ.: А. Слинкин науч. ред.: Н. Шалаев]. — Санкт-Петербург [и др.] : Питер, 2014. — 366 с. : ил. ; 24 см.
7. Ajax http://erud.by/ajax
8. Ajax http://erud.by/ajax
9. Ajax http://erud.by/ajax
10. Документация Laravel http://laravel.com
Задание к курсовой работе
Задание к курсовой работе
Вопросы к экзамену