В чем принципиальная разница между фабричными и абстрактными фабричными моделями?
createThing()
), а Abstract Factory - композицию (например, косвенное направление getFactory().createThing()
)
В чем принципиальная разница между фабричными и абстрактными фабричными моделями?
createThing()
), а Abstract Factory - композицию (например, косвенное направление getFactory().createThing()
)
Ответы:
С рисунком Factory, вы производите экземпляров реализаций ( Apple
, Banana
, Cherry
и т.д.) конкретного интерфейса - скажем, IFruit
.
С помощью шаблона «Абстрактная фабрика» вы предоставляете возможность каждому создать собственную фабрику. Это позволяет вашему складу быть или IFruitFactory
или IJuiceFactory
без, не требуя, чтобы ваш склад знал что-нибудь о фруктах или соках.
IFruit
- она создает вещи, которые реализуют IFruit
. Конечно, не нужно создавать экземпляры вещей, которые реализуют определенный интерфейс, но это, вероятно, запах кода, если у вас есть Фабрика, которая производит вещи, которые абсолютно не связаны друг с другом.
Источник этой информации взят из: http://java.dzone.com/news/intro-design-patterns-abstract
Методы абстрактной фабрики реализованы как фабричные методы. И абстрактный шаблон фабрики, и шаблон метода фабрики отделяют клиентскую систему от реальных классов реализации через абстрактные типы и фабрики. Фабричный метод создает объекты с помощью наследования, а Абстрактная фабрика создает объекты с помощью композиции.
Шаблон Abstract Factory состоит из AbstractFactory, ConcreteFactory, AbstractProduct, ConcreteProduct и клиента.
Абстрактный шаблон фабрики может быть реализован с использованием шаблона фабричного метода, шаблона прототипа или шаблона Singleton. Объект ConcreteFactory может быть реализован как Singleton, поскольку необходим только один экземпляр объекта ConcreteFactory.
Шаблон Factory Method - это упрощенная версия шаблона Abstract Factory. Шаблон Factory Method отвечает за создание продуктов, принадлежащих одному семейству, а шаблон Abstract Factory - для нескольких семейств продуктов.
Фабричный метод использует интерфейсы и абстрактные классы для отделения клиента от класса генератора и конечных продуктов. Абстрактная фабрика имеет генератор, который является контейнером для нескольких фабричных методов, а также интерфейсы, отделяющие клиента от генератора и продуктов.
Используйте шаблон Factory Method, когда необходимо отделить клиента от конкретного продукта, который он использует. Используйте фабричный метод, чтобы снять с клиента ответственность за создание и настройку экземпляров продукта.
Используйте шаблон Abstract Factory, когда клиенты должны быть отделены от классов продуктов. Особенно полезно для настройки и модификации программы. Шаблон Абстрактная фабрика также может навязывать ограничения относительно того, какие классы должны использоваться с другими. Может быть много работы по созданию новых бетонных заводов.
Эта спецификация для дисков для приготовления различных видов макаронных изделий в устройстве для изготовления макаронных изделий является абстрактной фабрикой, а каждый конкретный диск - фабрикой. все фабрики (диски для изготовления макаронных изделий) наследуют свои свойства от абстрактной фабрики. Каждый отдельный диск содержит информацию о том, как создать макароны, а производитель макаронных изделий - нет.
Штамповочное оборудование соответствует абстрактной фабрике, так как это интерфейс для операций, которые создают абстрактные объекты продукта. Матрицы соответствуют бетонному заводу, поскольку они создают конкретный продукт. Каждая категория деталей (капот, дверь и т. Д.) Соответствует абстрактному произведению. Конкретные детали (то есть дверь со стороны водителя на 99 кулачков) соответствуют конкретным изделиям.
Компания по производству игрушек соответствует Создателю, поскольку она может использовать фабрику для создания объектов товара. Подразделение компании по производству игрушек, которое производит игрушку определенного типа (лошадь или автомобиль), соответствует ConcreteCreator.
Фабричный шаблон: Фабрика производит IProduct-реализации
Абстрактная модель фабрики: фабрика-фабрика производит фабрики, которые в свою очередь производят продукцию IP :)
[Обновление в соответствии с комментариями]
То, что я написал ранее, по крайней мере, неверно в Википедии . Абстрактная фабрика - это просто фабричный интерфейс. С его помощью вы можете переключать свои фабрики во время выполнения, чтобы разрешить разные фабрики в разных контекстах. Примерами могут быть разные фабрики для разных ОС, провайдеры SQL, промежуточные драйверы и т. Д.
Предоставить интерфейс для создания семейств связанных или зависимых объектов без указания их конкретных классов.
Шаблон Abstract Factory очень похож на шаблон Factory Method. Одно из различий между ними состоит в том, что с шаблоном Abstract Factory класс делегирует ответственность за создание экземпляра объекта другому объекту через композицию, тогда как шаблон Factory Method использует наследование и опирается на подкласс для обработки требуемого экземпляра объекта.
На самом деле, делегированный объект часто использует фабричные методы для выполнения экземпляров!
Фабричные образцы - примеры творческих образцов
Образцы творчества абстрагируют процесс создания объекта. Они скрывают, как создаются объекты, и помогают сделать систему в целом независимой от того, как создаются и создаются ее объекты.
Шаблоны создания классов фокусируются на использовании наследования для определения объекта, который должен быть создан. Factory Method
Шаблоны создания объекта ориентированы на делегирование экземпляра другому объекту. Абстрактная фабрика
Справка: Фабрика против Абстрактной Фабрики
Заводской метод: вас есть фабрика, которая создает объекты, производные от определенного базового класса
Абстрактная фабрика: у вас есть фабрика, которая создает другие фабрики , а эти фабрики в свою очередь создают объекты, производные от базовых классов. Вы делаете это, потому что вы часто не просто хотите создать отдельный объект (как в методе Factory), а хотите создать коллекцию связанных объектов.
Основное отличие:
Фабрика: создает объекты, не раскрывая логику реализации клиенту.
Фабричный метод : определите интерфейс для создания объекта, но пусть подклассы решают, какой класс создать. Метод Factory позволяет классу откладывать создание экземпляров для подклассов
Абстрактная Фабрика : предоставляет интерфейс для создания семейств связанных или зависимых объектов без указания их конкретных классов.
Шаблон AbstractFactory использует композицию, чтобы делегировать ответственность за создание объекта другому классу, в то время как метод Factory шаблон использует наследование и опирается на производный класс или подкласс для создания объекта.
Из статей о дизайне :
Заводская диаграмма классов:
Пример: StaticFactory
public class ShapeFactory {
//use getShape method to get object of type shape
public static Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
}
Нестатическая фабрика, реализующая пример FactoryMethod, доступна в этом посте:
Шаблоны проектирования: метод фабрики против фабрики против абстрактной фабрики
Когда использовать: Клиенту просто нужен класс, и ему все равно, какую конкретную реализацию он получает.
Заводской метод класса дигарам:
Когда использовать: Клиент не знает, какие конкретные классы необходимо будет создать во время выполнения, но просто хочет получить класс, который будет выполнять эту работу.
Абстрактная фабричная диаграмма классов из dzone
Когда использовать: когда вашей системе необходимо создать несколько семейств продуктов или вы хотите предоставить библиотеку продуктов без раскрытия деталей реализации.
Примеры исходного кода в вышеприведенных статьях очень хороши для четкого понимания концепций.
Связанный вопрос SE с примером кода:
Заводская модель. Когда использовать фабричные методы?
Отличия:
Другие полезные статьи:
factory_method от создания источника
abstract_factory от создания источника
абстрактный-фабричный-дизайн-шаблон из журнала
Пример / сценарий для абстрактной фабрики
Я живу в месте, где в сезон дождей идет дождь, зимой - снег, а летом жарко и солнечно. Мне нужна другая одежда, чтобы защитить себя от стихии. Для этого я иду в магазин рядом с моим домом и прошу одежду / предметы, чтобы защитить себя. Хранитель магазина дает мне соответствующий предмет в соответствии с окружающей средой и глубиной моего кармана. Предметы, которые он мне дает, имеют такой же уровень качества и ценовой категории. Поскольку он знает о моих стандартах, ему легко это сделать. Но когда богатый парень с другой стороны улицы предъявляет те же требования, он получает дорогой фирменный товар. Одна заметная вещь - все предметы, которые он дает мне, дополняют друг друга с точки зрения качества, стандарта и стоимости. Можно сказать, что они идут друг с другом. То же самое и с вещами, которые получает этот богатый парень.
Итак, глядя на вышеприведенный сценарий, я теперь оцениваю эффективность продавца. Я могу заменить этого лавочника абстрактным магазином. Предметы, которые мы получаем с абстрактными предметами, и я, и богатые как перспективные клиенты. Все, что нам нужно, это продукт / предмет, который соответствует нашим потребностям.
Теперь я легко вижу себя, рассматривая интернет-магазин, который предоставляет множество услуг своим многочисленным клиентам. Каждый клиент принадлежит к одной из трех групп. Когда пользователь премиум-группы открывает сайт, он получает отличный пользовательский интерфейс, настраиваемую панель рекламы, больше опций в меню и т. Д. Этот же набор функций представлен золотому пользователю, но функциональность в меню меньше, реклама в основном релевантна, и немного менее эргономичный интерфейс. Последний - мой тип пользователя, пользователь «свободной группы». Я просто достаточно обслужен, чтобы не обижаться. Пользовательский интерфейс - это минимум, рекламные объявления настолько далеки от отслеживания, что я не знаю, что из этого выйдет, наконец, в меню есть только выход из системы.
Если бы у меня была возможность создать что-то похожее на этот сайт, я бы определенно рассмотрел шаблон Abstract Factory Pattern
Абстрактные продукты: Панель рекламы, Меню, Пользовательский интерфейс художника.
Абстрактная фабрика: пользовательский опыт интернет-магазина.
Конкретная фабрика: опыт премиум-пользователя, удобство работы с золотом, общее удобство пользователя.
Многие могут удивиться, но этот вопрос неверен . Если вы слышите этот вопрос во время собеседования, вам нужно помочь интервьюеру понять, в чем путаница.
Начнем с того, что нет конкретного шаблона, который называется просто «Фабрика». Существует шаблон, который называется «Абстрактная фабрика», и существует шаблон, который называется «Метод фабрики».
Итак, что же значит «Фабрика»? одно из следующего (все может считаться правильным, в зависимости от объема ссылки):
И, к сожалению , многие люди используют «Фабрика» для обозначения другого вида фабрики, которая создает фабрику или фабрики (или их интерфейсы). Основываясь на их теории:
Продукт реализует IProduct, который создается Factory, который реализует IFactory, который создается AbstractFactory.
Чтобы понять, насколько это глупо, давайте продолжим наше уравнение:
AbstractFactory реализует IAbstractFactory, который создается ... AbstractAbstractFactory ???
Я надеюсь, что вы видите смысл. Не смущайтесь, и, пожалуйста, не изобретайте вещи, которые не существуют по причине.
-
PS : Фабрика для продуктов - это AbstractFactory, а Фабрика для абстрактных фабрик - еще один пример AbstractFactory.
//Abstract factory - Provides interface to create factory of related products
interface PizzaIngredientsFactory{
public Dough createDough(); //Will return you family of Dough
public Clam createClam(); //Will return you family of Clam
public Sauce createSauce(); //Will return you family of Sauce
}
class NYPizzaIngredientsFactory implements PizzaIngredientsFactory{
@Override
public Dough createDough(){
//create the concrete dough instance that NY uses
return doughInstance;
}
//override other methods
}
Определения учебника уже предоставлены другими ответами. Я думал, что приведу пример этого тоже.
Итак, здесь PizzaIngredientsFactory
есть абстрактная фабрика, так как она предоставляет методы для создания семейства связанных продуктов.
Обратите внимание, что каждый метод в абстрактной фабрике сам по себе является фабричным методом . Like createDough()
сам по себе является фабричным методом, чьи конкретные реализации будут предоставляться подклассами like NYPizzaIngredientsFactory
. Таким образом, используя это, каждое другое местоположение может создавать экземпляры конкретных ингредиентов, которые принадлежат их местоположению.
Предоставляет пример конкретной реализации
В примере:
- createDough()
- предоставляет конкретную реализацию для теста. Так что это фабричный метод
Предоставляет интерфейс для создания семейства связанных объектов
В примере:
- PizzaIngredientsFactory
это абстрактная фабрика , поскольку это позволяет создать связанный набор объектов , таких как Dough
, Clams
, Sauce
. Для создания каждого семейства объектов предусмотрен фабричный метод.
Пример из головы Первые шаблоны дизайна
У меня есть несколько моментов, которые я могу внести в ответ Джона следующим образом:
С «Factory Method» (потому что только «Фабрика» неоднозначно), вы производите реализации ( Lemon
, Orange
и т.д.) конкретного интерфейса - скажем, IFruit
. Эту Фабрику можно назвать CitricFruitFactory
.
Но теперь вы хотите создать другие виды фруктов, которые не может создать CitricFruitFactory. Может быть, код CitricFruitFactory
не будет иметь смысла, если вы создадите Strawberry
в нем (клубника не лимонный фрукт!).
Таким образом , вы можете создать новый завод под названием , RedFruitFactory
которая производит Strawberry
, Raspberry
и т.д.
Как сказал Джон Феминелла:
«Используя шаблон Abstract Factory, вы создаете реализации определенного интерфейса Factory - например, IFruitFactory
каждый из них знает, как создавать различные виды фруктов».
Это реализации IFruitFactory
являются CitricFruitFactory
и RedFruitFactory
!
Мои источники: StackOverflow
, tutorialspoint.com
, programmers.stackexchange.com
и CodeProject.com
.
Factory Method
(также называется Factory
) для развязки клиента Interface
реализации. Для примера у нас есть Shape
интерфейс с двумя Circle
и Square
реализациями. Мы определили класс фабрики с методом фабрики с параметром определителя, таким как Type
и новая связанная реализация Shape
интерфейса.
Abstract Factory
содержит несколько фабричных методов или фабричный интерфейс несколькими фабричными реализациями. Для следующего примера выше у нас есть Color
интерфейс с двумя Red
и Yellow
реализациями. Мы должны определить ShapeColorFactory
интерфейс с двумя RedCircleFactory
и YellowSquareFactory
. Следующий код для объяснения этой концепции:
interface ShapeColorFactory
{
public Shape getShape();
public Color getColor();
}
class RedCircleFactory implements ShapeColorFactory
{
@Override
public Shape getShape() {
return new Circle();
}
@Override
public Color getColor() {
return new Red();
}
}
class YellowSquareFactory implements ShapeColorFactory
{
@Override
public Shape getShape() {
return new Square();
}
@Override
public Color getColor() {
return new Yellow();
}
}
Здесь разница между FactoryMethod
а AbstractFactory
. Factory Method
а просто вернуть конкретный класс интерфейса, ноAbstract Factory
вернуть factory of factory
. Другими словами, Abstract Factory
возвращаются различные сочетания из серии интерфейсов.
Я надеюсь, что мое объяснение полезно.
Основное различие в этих фабриках заключается в том, когда вы хотите делать с фабриками, и когда вы хотите их использовать.
Иногда, когда вы делаете IOC (инверсия управления, например, инжекция в конструктор), вы знаете, что можете создавать твердые объекты. Как упоминалось в примере выше фруктов, если вы готовы создавать объекты из фруктов, вы можете использовать простой фабричный шаблон .
Но часто вы не хотите создавать твердые объекты, они появятся позже в потоке программы. Но конфигурация говорит вам, какую фабрику вы хотите использовать при запуске, вместо создания объектов вы можете передавать фабрики, производные от общего класса фабрики, конструктору в IOC.
Итак, я думаю, что это также о времени существования и создания объекта.
Оба Factory Method
и Abstract Factory
держат клиентов отделенными от конкретных типов. Оба создают объекты, но Factory
метод использует наследование, тогда какAbstract Factory
использует композицию.
Factory Method
Наследуется в подклассах для создания конкретных объектов (продукции) , тогда какAbstract Factory
предоставляют интерфейс для создания семейства связанных продуктов, а подклассы этого интерфейса определяют, как создавать связанные продукты.
Затем эти подклассы при создании экземпляра передаются в классы продукта, где он используется как абстрактный тип. Связанные продукты в Abstract Factory
часто реализуются с использованием Factory Method
.
Расширяя ответ Джона Феминеллы:
Apple
, Banana
, Cherry
Инвентарь FruitFactory
и что есть метод , называемый , Create
который несет ответственность создания компании Apple или банана или вишни. Вы сделали, с вашим Factory
методом.
Теперь вы хотите Create
специальный салат из своих фруктов, и вот вам ваша абстрактная фабрика . Abstract Factory знает, как создать свой особенный салат из яблок, бананов и вишни.
public class Apple implements Fruit, FruitFactory {
public Fruit Create() {
// Apple creation logic goes here
}
}
public class Banana implements Fruit, FruitFactory {
public Fruit Create() {
// Banana creation logic goes here
}
}
public class Cherry implements Fruit, FruitFactory {
public Fruit Create() {
// Cherry creation logic goes here
}
}
public class SpecialSalad implements Salad, SaladFactory {
public static Salad Create(FruitFactory[] fruits) {
// loop through the factory and create the fruits.
// then you're ready to cut and slice your fruits
// to create your special salad.
}
}
По определению мы можем вытянуть различия двух:
Фабрика: интерфейс используется для создания объекта, но подкласс решает, какой класс создать. Создание объекта выполняется тогда, когда это требуется.
Абстрактная фабрика: шаблон Абстрактная фабрика действует как суперфабрика, которая создает другие фабрики. В шаблоне Abstract Factory интерфейс отвечает за создание набора связанных объектов или зависимых объектов без указания их конкретных классов.
Таким образом, в приведенных выше определениях мы можем подчеркнуть конкретное различие. то есть шаблон Factory отвечает за создание объектов, а Abstract Factory отвечает за создание набора связанных объектов; очевидно, как через интерфейс.
Заводская модель:
public interface IFactory{
void VehicleType(string n);
}
public class Scooter : IFactory{
public void VehicleType(string n){
Console.WriteLine("Vehicle type: " + n);
}
}
public class Bike : IFactory{
public void VehicleType(string n) {
Console.WriteLine("Vehicle type: " + n);
}
}
public interface IVehicleFactory{
IFactory GetVehicleType(string Vehicle);
}
public class ConcreteVehicleFactory : IVehicleFactory{
public IFactory GetVehicleType(string Vehicle){
switch (Vehicle){
case "Scooter":
return new Scooter();
case "Bike":
return new Bike();
default:
return new Scooter();
}
}
class Program{
static void Main(string[] args){
IVehicleFactory factory = new ConcreteVehicleFactory();
IFactory scooter = factory.GetVehicleType("Scooter");
scooter.VehicleType("Scooter");
IFactory bike = factory.GetVehicleType("Bike");
bike.VehicleType("Bike");
Console.ReadKey();
}
}
Абстрактная фабричная картина:
interface IVehicleFactory{
IBike GetBike();
IScooter GetScooter();
}
class HondaFactory : IVehicleFactory{
public IBike GetBike(){
return new FZS();
}
public IScooter GetScooter(){
return new FZscooter();
}
}
class HeroFactory: IVehicleFactory{
public IBike GetBike(){
return new Pulsur();
}
public IScooter GetScooter(){
return new PulsurScooter();
}
}
interface IBike
{
string Name();
}
interface IScooter
{
string Name();
}
class FZS:IBike{
public string Name(){
return "FZS";
}
}
class Pulsur:IBike{
public string Name(){
return "Pulsur";
}
}
class FZscooter:IScooter {
public string Name(){
return "FZscooter";
}
}
class PulsurScooter:IScooter{
public string Name(){
return "PulsurScooter";
}
}
enum MANUFACTURERS
{
HONDA,
HERO
}
class VehicleTypeCheck{
IBike bike;
IScooter scooter;
IVehicleFactory factory;
MANUFACTURERS manu;
public VehicleTypeCheck(MANUFACTURERS m){
manu = m;
}
public void CheckProducts()
{
switch (manu){
case MANUFACTURERS.HONDA:
factory = new HondaFactory();
break;
case MANUFACTURERS.HERO:
factory = new HeroFactory();
break;
}
Console.WriteLine("Bike: " + factory.GetBike().Name() + "\nScooter: " + factory.GetScooter().Name());
}
}
class Program
{
static void Main(string[] args)
{
VehicleTypeCheck chk = new VehicleTypeCheck(MANUFACTURERS.HONDA);
chk.CheckProducts();
chk= new VehicleTypeCheck(MANUFACTURERS.HERO);
chk.CheckProducts();
Console.Read();
}
}
Проверьте здесь: http://www.allapplabs.com/java_design_patterns/abstract_factory_pattern.htm кажется, что метод Factory использует определенный класс (не абстрактный) в качестве базового класса, в то время как Abstract factory использует для этого абстрактный класс. Также, если использовать интерфейс вместо абстрактного класса, результатом будет другая реализация шаблона Абстрактной фабрики.
: D
Abstract Factory - шаблон для создания различных типов интерфейсов. Предположим, у вас есть проект, который требует, чтобы вы анализировали различные типы CSV-файлов, содержащих информацию о количестве, цене и товаре, например, некоторые содержат данные о фруктах, другие о шоколадных конфетах, а затем после анализа вам нужно обновить эту информацию в соответствующей базе данных, чтобы теперь вы могли иметь одна абстрактная фабрика возвращает вам парсер и фабрику модификаторов, а затем эта фабрика парсеров может возвращать вам объект синтаксического анализатора шоколада, объект анализатора фруктов и т. д., и аналогично фабрика модификаторов может возвращать объект модификатора шоколада, объект модификатора фруктов и т. д.
Я думаю, что мы можем понять разницу между этими двумя, увидев пример кода Java8:
interface Something{}
interface OneWhoCanProvideSomething {
Something getSomething();
}
interface OneWhoCanProvideCreatorsOfSomething{
OneWhoCanProvideSomething getCreator();
}
public class AbstractFactoryExample {
public static void main(String[] args) {
//I need something
//Let's create one
Something something = new Something() {};
//Or ask someone (FACTORY pattern)
OneWhoCanProvideSomething oneWhoCanProvideSomethingOfTypeA = () -> null;
OneWhoCanProvideSomething oneWhoCanProvideSomethingOfTypeB = () -> null;
//Or ask someone who knows soemone who can create something (ABSTRACT FACTORY pattern)
OneWhoCanProvideCreatorsOfSomething oneWhoCanProvideCreatorsOfSomething = () -> null;
//Same thing, but you don't need to write you own interfaces
Supplier<Something> supplierOfSomething = () -> null;
Supplier<Supplier<Something>> supplierOfSupplier = () -> null;
}
}
Теперь вопрос в том, какой способ создания следует использовать и почему: Первый способ (без шаблона, просто простой конструктор): создание самостоятельно - не очень хорошая идея, вы должны выполнить всю работу, и ваш клиентский код привязан к конкретная реализация.
Второй способ (с использованием шаблона Factory): предоставляет вам преимущество, заключающееся в том, что вы можете передать любой тип реализации, который может предоставить другой тип чего-либо на основе некоторого условия (возможно, параметра, передаваемого в метод создания).
Третий способ (использование шаблона Abstract Factory): это дает вам больше гибкости. Вы можете найти разные типы создателей чего-либо на основании какого-либо условия (возможно, переданного параметра).
Обратите внимание, что вы всегда можете обойтись без паттерна Factory, комбинируя вместе два условия (что немного увеличивает сложность кода и связывание), я думаю, поэтому мы редко видим реальные случаи использования паттерна Abstract Factory.