Это Творческий Шаблон дизайна в рамках Банды четырех
Также известный как
Комплект
Намерение
Предоставляет интерфейс для создания семейств связанных или зависимых объектов без указания их конкретных классов.
Объяснение
Пример из реального мира
Чтобы создать королевство, нам нужны объекты с общей темой. Эльфийскому королевству нужен эльфийский король, эльфийский замок и эльфийская армия, в то время как оркскому королевству нужен оркский король, оркский замок и оркская армия. Существует зависимость между объектами в королевстве.
Простыми словами
Фабрика фабрик; фабрика, которая группирует отдельные, но связанные/зависимые фабрики вместе без указания их конкретных классов.
Википедия говорит
Шаблон абстрактной фабрики предоставляет способ инкапсуляции группы отдельных фабрик, имеющих общую тему, без указания их конкретных классов
Программный пример
Перевод приведенного выше примера королевства. Прежде всего, у нас есть некоторые интерфейсы и реализации для объектов в королевстве.
public interface Castle { String getDescription(); } public interface King { String getDescription(); } public interface Army { String getDescription(); } // Elven implementations -> public class ElfCastle implements Castle { static final String DESCRIPTION = "This is the Elven castle!"; @Override public String getDescription() { return DESCRIPTION; } } public class ElfKing implements King { static final String DESCRIPTION = "This is the Elven king!"; @Override public String getDescription() { return DESCRIPTION; } } public class ElfArmy implements Army { static final String DESCRIPTION = "This is the Elven Army!"; @Override public String getDescription() { return DESCRIPTION; } } // Orcish implementations similarly -> ...
Затем у нас есть абстракция и реализации для фабрики королевства
public interface KingdomFactory { Castle createCastle(); King createKing(); Army createArmy(); } public class ElfKingdomFactory implements KingdomFactory { public Castle createCastle() { return new ElfCastle(); } public King createKing() { return new ElfKing(); } public Army createArmy() { return new ElfArmy(); } } public class OrcKingdomFactory implements KingdomFactory { public Castle createCastle() { return new OrcCastle(); } public King createKing() { return new OrcKing(); } public Army createArmy() { return new OrcArmy(); } }
Теперь у нас есть наша абстрактная фабрика, которая позволяет нам создавать семейство связанных объектов, т.е. Фабрика эльфийского королевства создает эльфийский замок, короля и армию и т.д.
var factory = new ElfKingdomFactory(); var castle = factory.createCastle(); var king = factory.createKing(); var army = factory.createArmy(); castle.getDescription(); king.getDescription(); army.getDescription();
Вывод программы:
This is the Elven castle! This is the Elven king! This is the Elven Army!
Теперь мы можем спроектировать фабрику для наших различных фабрик королевства. В этом примере мы создали Factory Maker, ответственного за возврат экземпляра либо Elf Kingdom Factory, либо OrcKingdomFactory. Клиент может использовать Factory Maker для создания желаемой бетонной фабрики, которая, в свою очередь, будет производить различные бетонные объекты (Армия, Король, Замок). В этом примере мы также использовали перечисление, чтобы указать, какой тип фабрики королевств будет запрашивать клиент.
public static class FactoryMaker { public enum KingdomType { ELF, ORC } public static KingdomFactory makeFactory(KingdomType type) { switch (type) { case ELF: return new ElfKingdomFactory(); case ORC: return new OrcKingdomFactory(); default: throw new IllegalArgumentException("KingdomType not supported."); } } } public static void main(String[] args) { var app = new App(); LOGGER.info("Elf Kingdom"); app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF)); LOGGER.info(app.getArmy().getDescription()); LOGGER.info(app.getCastle().getDescription()); LOGGER.info(app.getKing().getDescription()); LOGGER.info("Orc Kingdom"); app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC)); -- similar use of the orc factory }
Диаграмма классов
Применимость
Используйте абстрактный фабричный шаблон, когда
- Система должна быть независимой от того, как создаются, составляются и представляются ее продукты
- Система должна быть настроена на одно из нескольких семейств продуктов
- Семейство связанных объектов продукта предназначено для совместного использования, и вам необходимо применить это ограничение
- Вы хотите предоставить библиотеку классов продуктов, и вы хотите показать только их интерфейсы, а не их реализации
- Срок службы зависимости концептуально короче, чем срок службы потребителя.
- Вам нужно значение во время выполнения, чтобы создать определенную зависимость
- Вы хотите решить, какой продукт вызывать из семейства во время выполнения.
- Вам необходимо указать один или несколько параметров, известных только во время выполнения, прежде чем вы сможете разрешить зависимость.
- Когда вам нужна согласованность между продуктами
- Вы не хотите изменять существующий код при добавлении новых продуктов или семейств продуктов в программу.
Примеры вариантов использования
- Выбор для вызова соответствующей реализации службы Acme файловой системы или службы Acme базы данных или NetworkAcmeService во время выполнения.
- Написание примеров модульных тестов становится намного проще
- Инструменты пользовательского интерфейса для разных ОС
Последствия:
- Внедрение зависимостей в java скрывает зависимости класса сервиса, которые могут привести к ошибкам во время выполнения, которые были бы обнаружены во время компиляции.
- В то время как шаблон отлично подходит для создания предопределенных объектов, добавление новых может оказаться сложной задачей.
- Код становится более сложным, чем должен быть, поскольку вместе с шаблоном вводится множество новых интерфейсов и классов.
Руководство
Известные области применения
- javax.xml.синтаксические анализаторы. DocumentBuilderFactory
- javax.xml.transform. Трансформаторная фабрика
- javax.xml.xpath. XPathFactory
Связанные модели
Кредиты
- Шаблоны проектирования: Элементы многоразового объектно-ориентированного программного обеспечения
- Шаблоны проектирования Head First: Удобное для мозга Руководство
Код можно найти здесь
Узнайте больше о шаблонах проектирования здесь
Заслуга оригинальных авторов этого поста:
- Илкка Сеппала
- Санкет Панхейл
- Родольфо Форте
- УЭС Gilleland
- Святослав Щаранский
- Праффул Агарвал
- ДжекиеНим
- Нарендра Патай
- Дениз
- Анураг Агарвал
Оригинал: “https://dev.to/ohbus/abstract-factory-design-pattern-2ajb”