Шаблоны проектирования: Factory vs Factory метод vs Аннотация Factory
Я читал образцы дизайна с веб-сайта
Там я читал о Factory, Factory методе и в реферате Factory, но они настолько запутывают, не ясны по определению. Согласно определениям
Factory - создает объекты, не подвергая логику создания экземпляра клиенту, и ссылается на вновь созданный объект через общий интерфейс. Является упрощенной версией Factory Метод
Factory Метод. Определяет интерфейс для создания объектов, но позволяет подклассам решать, какой класс следует создавать и ссылается на вновь созданный объект через общий интерфейс.
Аннотация Factory - предлагает интерфейс для создания семейства связанных объектов без явного указания их классов.
Я также рассмотрел другие потоки stackoverflow в отношении метода Abstract Factory vs Factory, но диаграммы UML, нарисованные там, еще больше ухудшили мое понимание.
Кто-нибудь может сказать мне
- Как эти три шаблона отличаются друг от друга?
- Когда использовать какой?
- А также, если возможно, любые примеры Java, связанные с этими шаблонами?
Ответы
Ответ 1
Все три типа Factory делают то же самое: они являются "интеллектуальным конструктором".
Предположим, вы хотите создать два вида фруктов: Apple и Orange.
Factory
Factory является "фиксированным", поскольку у вас есть только одна реализация без подкласса. В этом случае у вас будет такой класс:
class FruitFactory {
public Apple makeApple() {
// Code for creating an Apple here.
}
public Orange makeOrange() {
// Code for creating an orange here.
}
}
Случай использования. Построение Apple или Orange слишком сложно обрабатывать в конструкторе.
Factory Метод
Factory метод обычно используется, когда у вас есть некоторая общая обработка в классе, но вы хотите изменить тот вид фруктов, который вы на самом деле используете. Итак:
abstract class FruitPicker {
protected abstract Fruit makeFruit();
public void pickFruit() {
private final Fruit f = makeFruit(); // The fruit we will work on..
<bla bla bla>
}
}
... затем вы можете повторно использовать общую функциональность в FruitPicker.pickFruit()
, реализовав метод Factory в подклассах:
class OrangePicker extends FruitPicker {
@Override
protected Fruit makeFruit() {
return new Orange();
}
}
Аннотация Factory
Аннотация Factory обычно используется для таких вещей, как зависимость/стратегия зависимости, когда вы хотите создать целые семейства объектов, которые должны быть "одного типа" и иметь некоторые общие базовые классы. Вот пример, связанный с фруктами. Пример использования здесь заключается в том, что мы хотим убедиться, что мы случайно не используем OrangePicker на Apple. До тех пор, пока мы получим наш Fruit and Picker из того же factory, они будут соответствовать.
interface PlantFactory {
Plant makePlant();
Picker makePicker();
}
public class AppleFactory implements PlantFactory {
Plant makePlant() {
return new Apple();
}
Picker makePicker() {
return new ApplePicker();
}
}
public class OrangeFactory implements PlantFactory {
Plant makePlant() {
return new Orange();
}
Picker makePicker() {
return new OrangePicker();
}
}
Ответ 2
- Чем эти три модели отличаются друг от друга?
Фабрика: создает объекты без предоставления клиенту логики создания экземпляров.
Фабричный метод: определите интерфейс для создания объекта, но пусть подклассы решают, какой класс создать. Метод Factory позволяет классу откладывать создание экземпляров для подклассов
Абстрактная фабрика: предоставляет интерфейс для создания семейств связанных или зависимых объектов без указания их конкретных классов.
Шаблон AbstractFactory использует композицию, чтобы делегировать ответственность за создание объекта другому классу, в то время как шаблон проектирования метода Factory использует наследование и опирается на производный класс или подкласс для создания объекта.
- Когда использовать что?
Фабрика: Клиенту просто нужен класс, и ему все равно, какую конкретную реализацию он получает.
Фабричный метод: Клиент не знает, какие конкретные классы ему потребуется создать во время выполнения, но просто хочет получить класс, который будет выполнять эту работу.
AbstactFactory: когда вашей системе необходимо создать несколько семейств продуктов или вы хотите предоставить библиотеку продуктов без раскрытия деталей реализации.
Абстрактные фабричные классы часто реализуются с помощью фабричного метода. Заводские методы обычно вызываются в шаблонных методах.
- А также, если возможно, какие-либо примеры Java, связанные с этими шаблонами?
Фабрика и ФабрикаМетод
Намерение:
Определите интерфейс для создания объекта, но пусть подклассы решают, какой класс создать. Фабричный метод позволяет отложить создание экземпляров класса для подклассов.
UML-диаграмма:
Product: определяет интерфейс объектов, создаваемых методом Factory.
ConcreteProduct: реализует интерфейс продукта
Создатель: объявляет фабричный метод
ConcreateCreator: реализует метод Factory для возврата экземпляра ConcreteProduct.
Постановка задачи: Создайте Фабрику Игр, используя Фабричные Методы, которые определяют интерфейс игры.
Фрагмент кода:
Заводская модель. Когда использовать фабричные методы?
Сравнение с другими шаблонами творчества:
-
Проектирование начинается с использования Factory Method (менее сложный, более настраиваемый, подклассы распространяются) и развивается в сторону Abstract Factory, Prototype или Builder (более гибкий, более сложный), когда дизайнер обнаруживает, где необходима большая гибкость
-
Абстрактные фабричные классы часто реализуются с помощью фабричных методов, но они также могут быть реализованы с использованием Prototype
Ссылки для дальнейшего чтения: Создание шаблонов дизайна
Ответ 3
Factory - Разделить класс Factory для создания сложного объекта.
Ex: класс FruitFactory для создания объекта Fruit
class FruitFactory{
public static Fruit getFruit(){...}
}
Factory Метод. Вместо целого отдельного класса для factory просто добавьте один метод в этот класс как factory.
Пример:
Calendar.getInstance() (Java Calendar)
Аннотация Factory Метод - Factory из Factory
Пример: Предположим, мы хотим построить Factory для частей компьютера. Таким образом, существует несколько типов компьютеров, таких как Laptop, Desktop, Server.
Итак, для каждого типа компилятора нам нужно factory. Таким образом, мы создаем один высокоуровневый Factory заводов, как показано ниже
ComputerTypeAbstractFactory.getComputerPartFactory(String computerType) ---> This will return PartFactory which can be one of these ServerPartFactory, LaptopPartFactory, DesktopPartFactory.
Теперь эти 3 себя снова являются фабриками. (Вы будете иметь дело с PartFactory самостоятельно, но под капотом будет отдельная реализация, основанная на том, что вы предоставили в абстрактном factory)
Interface-> PartFactory. getComputerPart(String s),
Implementations -> ServerPartFactory, LaptopPartFactory, DesktopPartFactory.
Usage:
new ComputerTypeAbstractFactory().getFactory("Laptop").getComputerPart("RAM")
EDIT: отредактирован для предоставления точных интерфейсов для Abstract Factory в соответствии с возражениями в комментариях.
Ответ 4
Каждый шаблон дизайна процветает, чтобы гарантировать, что письменный, рабочий код не тронут. Мы все знаем, что, как только мы касаемся рабочего кода, есть недостатки в существующих рабочих потоках, и нужно сделать намного больше испытаний, чтобы мы ничего не нарушили.
A factory шаблон создает объекты на основе критериев ввода, тем самым гарантируя, что вам не нужно писать код, как если бы этот создатель создавал этот объект вида else this kinda object. Хорошим примером этого является веб-сайт для путешествий. Туристический веб-сайт может предоставлять только путешествия (рейс, поезд, автобус) и/или предоставлять отели и/или предоставлять туристические пакеты. Теперь, когда пользователь выбирает следующий, веб-сайт должен решить, какие объекты ему нужно создать. Если это только создаст объект путешествия или гостиницы.
Теперь, если вы предполагаете добавить еще один веб-сайт в свой портфель, и вы считаете, что один и тот же ядро будет использоваться, например, на веб-сайте, использующем автомобиль, который теперь ищет такси и делает платежи онлайн, вы можете использовать абстрактный factory в вашем ядре. Таким образом, вы можете просто щелкнуть еще один factory кабин и автомобилей.
Оба factory не имеют ничего общего друг с другом, поэтому его хороший дизайн позволяет держать их в разных factory.
Надеюсь, теперь это ясно. Изучите веб-сайт, снова учитывая этот пример, надеюсь, это поможет. И я очень надеюсь, что правильно представил шаблоны:).
Ответ 5
AbstractProductA, A1 and A2 both implementing the AbstractProductA
AbstractProductB, B1 and B2 both implementing the AbstractProductB
interface Factory {
AbstractProductA getProductA(); //Factory Method - generate A1/A2
}
Используя метод Factory, пользователь может создать A1 или A2 AbstractProductA.
interface AbstractFactory {
AbstractProductA getProductA(); //Factory Method
AbstractProductB getProductB(); //Factory Method
}
Но абстрактный Factory имеющий более 1 Factory метод (например: 2 Factory), используя эти методы Factory, он создаст набор объектов/связанных объектов.
Используя Abstract Factory, пользователь может создавать объекты A1, B1 AbstractProductA, AbstractProductB