Абстрактная фабрика (шаблон проектирования)

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск
Шаблон проектирования
Абстрактная фабрика
Abstract factory
Тип:

порождающий

Назначение:

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

Структура:

Abstract factory UML.svg

Применяется в случаях:
  • Когда программа должна быть независимой от процесса и типов создаваемых новых объектов.
  • Когда необходимо создать семейства или группы взаимосвязанных объектов исключая возможность одновременного использования объектов из разных этих наборов в одном контексте[1].
Плюсы:
  • изолирует конкретные классы;
  • упрощает замену семейств продуктов;
  • гарантирует сочетаемость продуктов.
Минусы:
  • сложно добавить поддержку нового вида продуктов.
Описан в Design Patterns

Да

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

Назначение[править | править вики-текст]

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

Реализация[править | править вики-текст]

Abstract factory UML.svg

Плюсы[править | править вики-текст]

  • изолирует конкретные классы;
  • упрощает замену семейств продуктов;
  • гарантирует сочетаемость продуктов.

Минусы[править | править вики-текст]

  • сложно добавить поддержку нового вида продуктов.

Применимость[править | править вики-текст]

  • Система не должна зависеть от того, как создаются, компонуются и представляются входящие в нее объекты.
  • Входящие в семейство взаимосвязанные объекты должны использоваться вместе и вам необходимо обеспечить выполнение этого ограничения.
  • Система должна конфигурироваться одним из семейств составляющих ее объектов.
  • Требуется предоставить библиотеку объектов, раскрывая только их интерфейсы, но не реализацию.

Примеры[править | править вики-текст]

Пример на Swift[править | править вики-текст]

        /* ПРОДУКТЫ ФАБРИКИ */
 
//    Протокол или абстрактный класс для продуктов
protocol Numbers{
    func numbSet()->[Int]
}
 
//    Конкретные продукты разных конкретных фабрик
class PositiveNumbers: Numbers {
    func numbSet() -> [Int] {
        return [1, 2, 3, 4, 5]
    }
}
 
class NegativeNumbers: Numbers {
    func numbSet() -> [Int] {
        return [ -1, -2, -3, -4, -5]
    }
}
 
//    Класс нуля реализован для отображения всего численного диапазона.
//    Может быть использован как абстрактный класс для конкретных продуктов.
class ZeroNumber: Numbers {
    func numbSet() -> [Int] {
        return [0]
    }
}
 
 
        /* ТИП КОНКРЕТНОЙ ФАБРИКИ */
 
enum SignIndicator{
    case Positive, Negative, Zero
}
 
        /* ФАБРИКИ */
 
//    Абстрактная фабрика объявляет интерфейсы для конкретных фабрик, а также
//    создает экземпляр конкретной фабрики для клиента.
class NumbersFactory {
    
    //  Фабричный метод не переопределяется потомками.
    //  Обращиясь к нему, клиент получает экземпляр конкретной
    //  фабрики, на основании заданных настроек
    class final func factoryOfType(sign: SignIndicator) -> NumbersFactory{
        switch sign{
        case .Positive:
            return PositiveNumbersFactory()
        case .Negative:
            return NegativeNumbersFactory()
        default:
            return NumbersFactory()
        }
    }
    
    func sampleNumbers() -> Numbers{
//        возвращаем новый экземпляр конкретного продукта
        return ZeroNumber()
    }
}
 
class PositiveNumbersFactory: NumbersFactory {
    override func sampleNumbers() -> Numbers {
        return PositiveNumbers()
    }
}
 
class NegativeNumbersFactory: NumbersFactory {
    override func sampleNumbers() -> Numbers {
        return NegativeNumbers()
    }
}
 
        /* ИСПОЛЬЗОВАНИЕ */
 
//    обращаемся к абстрактной фабрике для получения экземпляра
var variableFactory = NumbersFactory.factoryOfType(.Positive)
//    экземпляр отвечает на наш тестовый запрос
variableFactory.sampleNumbers().numbSet()
 
//    меняем фабрику
variableFactory = NumbersFactory.factoryOfType(.Negative)
//    экземпляр продолжает отвечать на наш тестовый запрос
variableFactory.sampleNumbers().numbSet()

Литература[править | править вики-текст]

  • Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес Приемы объектно-ориентированного проектирования. Паттерны проектирования = Design Patterns: Elements of Reusable Object-Oriented Software. — СПб: «Питер», 2007. — С. 366. — ISBN 978-5-469-01136-1. (также ISBN 5-272-00355-1)

Ссылки[править | править вики-текст]

Примечания[править | править вики-текст]