Я знаю, что есть много сообщений о различиях между этими двумя моделями, но есть несколько вещей, которые я не могу найти.
Из того, что я читал, я вижу, что шаблон фабричного метода позволяет вам определить, как создать отдельный конкретный продукт, но скрыть реализацию от клиента, поскольку они увидят общий продукт. Мой первый вопрос об абстрактной фабрике. Его роль - позволить вам создавать семейства конкретных объектов (которые могут зависеть от того, какую конкретную фабрику вы используете), а не только один конкретный объект? Абстрактная фабрика возвращает только один очень большой объект или много объектов в зависимости от того, какие методы вы вызываете?
Мои последние два вопроса касаются одной цитаты, которую я не могу полностью понять, которую я видел во многих местах:
Одно из различий между ними заключается в том, что с шаблоном Abstract Factory класс делегирует ответственность за создание экземпляра объекта другому объекту посредством композиции, тогда как шаблон Factory Method использует наследование и опирается на подкласс для обработки требуемого экземпляра объекта.
Насколько я понимаю, шаблон фабричного метода имеет интерфейс Creator, который позволит ConcreteCreator знать, какой экземпляр ConcreteProduct нужно создать. Это то, что это означает, используя наследование для обработки объекта?
Теперь, что касается этой цитаты, как именно шаблон Abstract Factory делегирует ответственность за создание экземпляра объекта другому объекту посредством композиции? Что это значит? Похоже, что шаблон Abstract Factory также использует наследование для выполнения процесса построения в моих глазах, но опять же я все еще изучаю эти шаблоны.
Любая помощь, особенно с последним вопросом, будет принята с благодарностью.
Ответы:
Разница между двумя
Основное различие между «фабричным методом» и «абстрактной фабрикой» состоит в том, что фабричный метод - это отдельный метод, а абстрактная фабрика - это объект. Я думаю, что многие люди путают эти два термина и начинают использовать их взаимозаменяемо. Я помню, что мне было трудно найти, в чем именно разница, когда я узнал их.
Поскольку фабричный метод является просто методом, он может быть переопределен в подклассе, отсюда и вторая половина вашей цитаты:
Цитата предполагает, что объект вызывает здесь свой собственный метод фабрики. Поэтому единственное, что может изменить возвращаемое значение, это подкласс.
Абстрактная фабрика - это объект с несколькими фабричными методами. Глядя на первую половину вашей цитаты:
Они говорят, что есть объект A, который хочет создать объект Foo. Вместо создания самого объекта Foo (например, с помощью фабричного метода) он получит другой объект (абстрактную фабрику) для создания объекта Foo.
Примеры кода
Чтобы показать вам разницу, здесь используется фабричный метод:
И здесь используется абстрактная фабрика:
источник
SpecialFoo
чтобы быть более ясным.Абстрактная фабрика создает базовый класс с абстрактными методами, определяющими методы для объектов, которые должны быть созданы. Каждый фабричный класс, который наследует базовый класс, может создавать свою собственную реализацию каждого типа объекта.
Фабричный метод - это простой метод, используемый для создания объектов в классе. Обычно он добавляется в сводный корень (в
Order
классе есть метод с именемCreateOrderLine
)Абстрактная фабрика
В приведенном ниже примере мы проектируем интерфейс, чтобы можно было отделить создание очереди от системы обмена сообщениями и, следовательно, создать реализации для разных систем очереди без необходимости изменения базы кода.
Заводской метод
Проблема в HTTP-серверах заключается в том, что нам всегда нужен ответ на каждый запрос.
Без фабричного метода пользователи HTTP-сервера (т. Е. Программисты) были бы вынуждены использовать классы, специфичные для реализации, которые противоречат цели
IHttpRequest
интерфейса.Поэтому мы вводим фабричный метод, чтобы создание класса ответа также абстрагировалось.
Резюме
Разница заключается в том, что предназначение класса, содержащего метод фабрики, не состоит в создании объектов , тогда как абстрактная фабрика должна использоваться только для создания объектов.
При использовании фабричных методов следует соблюдать осторожность, поскольку при создании объектов легко нарушить LSP ( принцип подстановки Лискова ).
источник
Button()
«семейство связанных продуктов». Например, канонический пример GoF создаетScrollBar()
иWindow()
. Преимущество заключается в том, что абстрактная фабрика может применять общую тему для нескольких продуктов.Разница между шаблонами проектирования AbstractFactory и Factory заключается в следующем:
Реализация шаблона фабричного метода:
Реализация абстрактной фабричной модели:
источник
Основное различие между Абстрактной Фабрикой и Фабричным Методом состоит в том, что Абстрактная Фабрика реализуется Композицией ; но фабричный метод реализован по наследству .
Да, вы правильно прочитали: главное различие между этими двумя шаблонами - это старая композиция против дебатов о наследовании .
Диаграммы UML можно найти в книге (GoF). Я хочу привести примеры кода, потому что я думаю, что объединение примеров из двух верхних ответов в этой теме даст лучшую демонстрацию, чем один из ответов. Кроме того, я использовал терминологию из книги в именах классов и методов.
Абстрактная Фабрика
Заводской метод
ConcreteCreator
это клиент. Другими словами, клиент является подклассом, родитель которого определяетfactoryMethod()
. Вот почему мы говорим, что Factory Method реализуется по наследству.Creator
класс (родительский) вызывает свой собственныйfactoryMethod()
. Если мы удалимanOperation()
из родительского класса, оставив только один метод, он больше не будет шаблоном Factory Method. Другими словами, фабричный метод не может быть реализован менее чем с двумя методами в родительском классе; и один должен ссылаться на другого.Разный И Разные Фабричные Образцы
Имейте в виду, что, хотя GoF определяет два разных Фабричных паттерна, это не единственные существующие Фабричные паттерны. Они даже не являются наиболее часто используемыми фабричными шаблонами. Известным третьим примером является шаблон статической фабрики Джоша Блоха из Effective Java. Книга Head First Design Patterns включает в себя еще один паттерн, который они называют Simple Factory.
Не попадайтесь в ловушку, предполагая, что каждый шаблон фабрики должен соответствовать одному из GoF.
источник
factoryMethod()
всегда бытьprotected
метод в шаблоне «Factory Method»? (Думаю да)public
фабричные методы, и метод даже не должен бытьabstract
; но критическим моментом является то, что метод предназначен для наследования, поэтому он не может (например) быть илиstatic
илиfinal
. Я сделал методprotected
иabstract
здесь, чтобы подчеркнуть (обязательную) расширяемость.Abstract Factory - это интерфейс для создания связанных продуктов, но Factory Method - это только один метод. Абстрактная фабрика может быть реализована несколькими фабричными методами.
источник
Рассмотрим этот пример для простоты понимания.
Что предоставляют телекоммуникационные компании? Например, широкополосная связь, телефонная линия и мобильная связь, и вас попросят создать приложение, чтобы предлагать свои продукты своим клиентам.
Как правило, то, что вы делаете здесь, это создание продуктов, то есть широкополосного доступа, телефонной линии и мобильной связи, с помощью вашего фабричного метода, где вы знаете, какие свойства у вас есть для этих продуктов, и это довольно просто.
Теперь компания хочет предложить своим покупателям пакет своих продуктов, в том числе широкополосный доступ, телефонную линию и мобильную связь, и вот вам начинает играть Абстрактная фабрика .
Абстрактная фабрика , другими словами, входит в состав других фабрик, которые несут ответственность за создание своих собственных продуктов, и Абстрактная фабрика знает, как сделать эти продукты более значимыми в отношении своих собственных обязанностей.
В этом случае,
BundleFactory
это абстрактная фабрика,BroadbandFactory
,PhonelineFactory
иMobileFactory
являютсяFactory
. Чтобы упростить еще, эти фабрики будут иметь фабричный метод для инициализации отдельных продуктов.Посмотрите пример кода ниже:
Надеюсь это поможет.
источник
static
шаблоне GoF фабрики нет методов. Это не верно.Пример из реальной жизни. (Легко вспомнить)
завод
Представьте, что вы строите дом и подходите к плотнику за дверью. Вы даете размер двери и ваши требования, и он построит дверь для вас. В этом случае плотник представляет собой фабрику дверей. Ваши спецификации являются входными данными для фабрики, а дверь является выходом или продуктом от фабрики.
Абстрактная Фабрика
Теперь рассмотрим тот же пример двери. Вы можете пойти к плотнику или в магазин пластиковых дверей или магазин ПВХ. Все они являются дверными фабриками. Исходя из ситуации, вы решаете, к какой фабрике вам нужно подходить. Это как Абстрактная Фабрика.
Я объяснил здесь как шаблон фабричного метода, так и абстрактный фабричный шаблон, начиная с того, что не используя их, объясняя проблемы, а затем решая проблемы, используя вышеупомянутые шаблоны https://github.com/vikramnagineni/Design-Patterns/tree/master.
источник
Давайте поясним, что большую часть времени в производственном коде мы используем абстрактный шаблон фабрики, потому что класс A запрограммирован с интерфейсом B. И A должен создавать экземпляры B. Таким образом, A должен иметь объект фабрики, чтобы создавать экземпляры B Таким образом, A не зависит от какого-либо конкретного случая B. Надеюсь, это поможет.
источник
Понять разницу в мотивации:
Предположим, вы создаете инструмент, в котором есть объекты, и конкретную реализацию взаимосвязей объектов. Поскольку вы предвидите изменения в объектах, вы создали косвенное направление, возложив ответственность за создание вариантов объектов на другой объект ( мы называем это абстрактной фабрикой ). Эта абстракция находит сильное преимущество, так как вы предвидите будущие расширения, которым нужны варианты этих объектов.
Еще одна довольно интригующая мотивация в этой линии мыслей - это случай, когда каждый из объектов всей группы будет иметь соответствующий вариант. Исходя из некоторых условий, будет использоваться любой из вариантов, и в каждом случае все объекты должны быть одного варианта. Это может быть немного противоречивым для понимания, поскольку мы часто склонны думать, что - пока варианты объекта следуют общему унифицированному контракту ( интерфейс в более широком смысле ), конкретный код реализации никогда не должен нарушаться. Интересным фактом здесь является то, что не всегда это верно, особенно когда ожидаемое поведение не может быть смоделировано программным контрактом.
Простым ( заимствуя идею от GoF ) являются любые приложения с графическим интерфейсом, скажем, виртуальный монитор, который имитирует внешний вид ОС MS, Mac или Fedora. Здесь, например, когда все объекты виджета, такие как окно, кнопка и т. Д., Имеют вариант MS, за исключением полосы прокрутки, которая получена из варианта MAC, назначение инструмента не удается.
Эти вышеупомянутые случаи формируют фундаментальную потребность в абстрактной фабричной модели .
С другой стороны, представьте, что вы пишете фреймворк, чтобы многие люди могли создавать различные инструменты ( например, один из приведенных выше примеров ), используя ваш фреймворк. По самой идее фреймворка вам не нужно, хотя вы не можете использовать конкретные объекты в своей логике. Вы скорее заключаете какие-то контракты высокого уровня между различными объектами и тем, как они взаимодействуют. Пока вы ( как разработчик фреймворка ) остаетесь на очень абстрактном уровне, каждый создатель инструмента вынужден следовать вашим фреймворк-конструкциям. Тем не менее, они ( создатели инструментов ) могут свободно выбирать, какой объект будет построен и как все объекты, которые они создают, будут взаимодействовать. В отличие от предыдущего случая ( абстрактного шаблона ), вы ( как создатель фреймворка)в этом случае не нужно работать с конкретными объектами; и скорее может остаться на уровне контракта объектов. Кроме того, в отличие от второй части предыдущих мотиваций, у вас или у создателей инструментов никогда не бывает ситуаций смешивания объектов из вариантов. Здесь, в то время как код платформы остается на уровне контракта, каждый создатель инструмента ограничен ( по природе самого случая ) использованием своих собственных объектов. Создание объектов в этом случае делегируется каждому реализатору, а поставщики инфраструктуры просто предоставляют единые методы для создания и возврата объектов. Такие методы неизбежны для разработчика инфраструктуры для продолжения работы со своим кодом и имеют специальное имя, называемое фабричным методом ( Factory Method Pattern для базового шаблона ).
Несколько заметок:
Образец кода:
источник
Да. Целью Абстрактной Фабрики является:
В идеале он должен возвращать один объект на метод, который вызывает клиент.
Да. Фабричный метод использует наследование.
AbstractFactory определяет FactoryMethod, а ConcreteFactory отвечает за создание ConcreteProduct. Просто следуйте примеру кода в этой статье .
Вы можете найти более подробную информацию в соответствующих сообщениях SE:
В чем принципиальная разница между фабричными и абстрактными фабричными моделями?
Шаблоны проектирования: метод фабрики против фабрики против абстрактной фабрики
источник
Фабричный метод опирается на наследование: создание объекта делегируется подклассам, которые реализуют фабричный метод для создания объектов.
Абстрактная фабрика опирается на композицию объекта: создание объекта осуществляется методами, представленными в интерфейсе фабрики.
Диаграмма высокого уровня фабричной и абстрактной фабричной модели,
Для получения дополнительной информации о методе Factory, обратитесь к этой статье .
Для получения дополнительной информации о методе Abstract factory, обратитесь к этой статье .
источник
Чтобы сделать это очень просто с минимальным интерфейсом и, пожалуйста, сфокусируйте "// 1":
Здесь важные моменты: 1. Механизмы Factory & AbstractFactory должны использовать наследование (System.Object-> byte, float ...); так что если у вас есть наследование в программе, то Factory (абстрактный Factory, скорее всего, там не будет), уже существует в проекте 2. Creator (MyFactory) знает о конкретном типе, поэтому возвращает объект конкретного типа вызывающей стороне (Main); В абстрактной фабрике возвращаемым типом будет интерфейс.
Важные моменты: 1. Требование: Honda создаст "Regular", "Sports", а Hero создаст "DarkHorse", "Sports" и "Scooty". 2. почему два интерфейса? Один для типа производителя (IVehicleFactory) и другой для продукта фабрики (IVehicle); Другой способ понять 2 интерфейса - абстрактная фабрика - все о создании связанных объектов 2. Подвох - возвращение потомков IVehicleFactory и IVehicle (вместо бетона на фабрике); поэтому я получаю родительскую переменную (IVehicle); затем я создаю конкретный конкретный тип, вызывая CreateSingleVehicle и затем приводя родительский объект к фактическому дочернему объекту. Что будет, если я сделаю
RegularBike heroRegularBike = (RegularBike)hero.CreateSingleVehicle("Regular");
; вы получите ApplicationException, и поэтому нам нужна общая абстрактная фабрика, которую я объясню, если потребуется.источник
Абстрактная фабрика : фабрика заводов; фабрика, которая группирует отдельные, но связанные / зависимые фабрики вместе без указания их конкретных классов. Пример абстрактной фабрики
Фабрика : предоставляет способ делегировать логику реализации дочерним классам. Пример фабричного образца
источник
Я бы предпочел Абстрактную Фабрику перед Фабричным Методом в любое время. Из приведенного выше примера Тома Даллинга (отличное объяснение) мы можем видеть, что Абстрактная Фабрика является более компонуемой в том, что все, что нам нужно сделать, это передать другую Фабрику в конструктор (здесь используется внедрение зависимости конструктора). Но Factory Method требует от нас ввести новый класс (больше вещей для управления) и использовать подклассы. Всегда предпочитайте композицию наследству.
источник
позвольте мне сказать это точно. большинство ответов уже объяснены, предоставлены диаграммы и примеры. так что мой ответ будет только один лайнер. мои собственные слова: - «абстрактный шаблон фабрики добавляет на абстрактный слой несколько реализаций метода фабрики. означает, что абстрактная фабрика содержит или объединяет один или несколько шаблонов фабричных методов »
источник
Многие из приведенных выше ответов не обеспечивают сравнения кода между шаблоном Abstract Factory и Factory Method. Следующее - моя попытка объяснить это через Java. Надеюсь, это поможет кому-то нуждающемуся в простом объяснении.
источник