Когда целесообразно использовать фабричные методы внутри объекта вместо фабричного класса?
design-patterns
factory
factory-pattern
factory-method
Равиндра Бабу
источник
источник
Ответы:
Мне нравится думать о дизайнерских шаблонах с точки зрения того, что мои уроки - это «люди», а шаблоны - это способы, которыми люди общаются друг с другом.
Таким образом, для меня фабричный образец похож на агентство по найму. У вас есть кто-то, кому потребуется переменное количество работников. Этот человек может знать некоторую информацию, которая ему нужна в людях, которых он нанимает, но это все.
Поэтому, когда им нужен новый сотрудник, они звонят в агентство по найму и говорят им, что им нужно. Теперь, чтобы нанять кого-то, вам нужно знать много вещей - льготы, подтверждение соответствия требованиям и т. Д. Но нанимающему персоналу не нужно ничего знать об этом - агентство по найму все это обрабатывает.
Точно так же использование фабрики позволяет потребителю создавать новые объекты без необходимости знать детали того, как они создаются, или каковы их зависимости - они должны только предоставлять информацию, которую они на самом деле хотят.
Таким образом, теперь потребитель ThingFactory может получить Thing без необходимости знать о зависимостях Thing, за исключением строковых данных, которые поступают от потребителя.
источник
within an object instead of a Factory class
. Я думаю, что он имел в виду сценарий, в котором вы делаете ctor приватным и используете статический метод для создания экземпляра класса (создания объекта). Но чтобы следовать этому примеру, нужноThingFactory
сначала создать экземпляр класса, чтобы получитьThing
объекты, что делает егоFactory class
действительным.Фабричные методы следует рассматривать как альтернативу конструкторам - в основном, когда конструкторы недостаточно выразительны, т.е.
не так выразительно, как:
Фабричные классы полезны, когда вам нужен сложный процесс для создания объекта, когда для построения нужна зависимость, которую вы не хотите видеть для фактического класса, когда вам нужно создать разные объекты и т. Д.
источник
Одна ситуация, когда я лично нахожу отдельные классы Фабрики, чтобы иметь смысл, - когда конечный объект, который вы пытаетесь создать, зависит от нескольких других объектов. Например, в PHP: предположим, у вас есть
House
объект, который, в свою очередь, имеет объект aKitchen
иLivingRoom
объект, и уLivingRoom
объекта также естьTV
объект внутри.Простейший метод для достижения этой цели - заставить каждый объект создавать своих потомков в своем методе конструирования, но если свойства являются относительно вложенными, то при
House
неудачном создании вы, вероятно, потратите некоторое время на то, чтобы точно определить, что именно не так.Альтернатива состоит в том, чтобы сделать следующее (внедрение зависимости, если вам нравится причудливый термин):
Здесь, если процесс создания
House
неудачи есть, есть только одно место для поиска, но необходимость использовать этот кусок каждый раз, когда кто-то хочет новогоHouse
, далеко не удобна. Введите фабрики:Благодаря фабрике процесс создания a
House
абстрагируется (в том, что вам не нужно создавать и настраивать каждую отдельную зависимость, когда вы просто хотите создать aHouse
) и в то же время централизован, что облегчает поддержку. Существуют и другие причины, по которым использование отдельных фабрик может быть полезным (например, тестируемость), но я нахожу этот конкретный пример использования, чтобы лучше всего показать, как классы Фабрики могут быть полезны.источник
HouseFactory
класс?create
метод. Например, если у васHouse
всегда будет один и тот же тип,LivingRoom
то может иметь смысл жестко закодировать его параметры в фабричном классе, а не в качестве аргументов. Или вы можете предоставитьtype
аргумент вашемуHouseFactory::create
методу, если у вас есть несколько видовLivingRoom
s и есть переключатель внутри с параметрами, жестко закодированными для каждого типа.Важно четко дифференцировать идею использования фабричного или фабричного метода. Оба предназначены для решения взаимоисключающих различного рода проблем создания объектов.
Давайте определимся с "фабричным методом":
Во-первых, когда вы разрабатываете библиотеку или API-интерфейсы, которые, в свою очередь, будут использоваться для дальнейшей разработки приложения, то фабричный метод является одним из лучших вариантов выбора шаблона создания. Причина позади; Мы знаем, что когда создать объект с необходимыми функциональными возможностями, но тип объекта останется неопределенным, или будет принято решение о передаче динамических параметров .
Теперь дело в том, что примерно того же можно достичь, используя сам шаблон фабрики, но один огромный недостаток внесет в систему, если шаблон фабрики будет использоваться для вышеуказанной проблемы, это то, что ваша логика создания различных объектов (объектов подклассов) будет будьте внимательны к некоторым бизнес-условиям, поэтому в будущем, когда вам нужно будет расширить функциональность вашей библиотеки для других платформ (в более техническом плане вам нужно добавить больше подклассов базового интерфейса или абстрактного класса, чтобы factory возвращала эти объекты также в дополнение к существующему основанный на некоторых динамических параметрах), то каждый раз, когда вам нужно изменить (расширить) логику фабричного класса, что будет дорогостоящей операцией и негодной с точки зрения проектирования. С другой стороны, если «фабричный метод»
источник
Они также полезны, когда вам нужно несколько «конструкторов» с одинаковым типом параметра, но с другим поведением.
источник
Рекомендуется использовать фабричные методы внутри объекта, когда:
Рекомендуется использовать абстрактный класс фабрики, когда:
источник
UML от
Product: определяет интерфейс объектов, создаваемых методом Factory.
ConcreteProduct: реализует интерфейс продукта
Создатель: объявляет фабричный метод
ConcreateCreator: Реализует метод Factory для возврата экземпляра ConcreteProduct.
Постановка проблемы: Создайте Фабрику Игр, используя Фабричные Методы, которые определяют интерфейс игры.
Фрагмент кода:
вывод:
В этом примере показан
Factory
класс путем реализацииFactoryMethod
.Game
это интерфейс для всех типов игр. Он определяет сложный метод:createGame()
Chess, Ludo, Checkers
различные варианты игр, которые обеспечивают реализациюcreateGame()
public Game getGame(String gameName)
находитсяFactoryMethod
вIGameFactory
классеGameFactory
предварительно создает другой тип игр в конструкторе. Он реализуетIGameFactory
фабричный метод.Название игры передается в качестве аргумента командной строки
NotStaticFactoryDemo
getGame
inGameFactory
принимает имя игры и возвращает соответствующийGame
объект.Фабрика:
FactoryMethod
Случай использования:
Когда использовать:
Client
не знает, какие конкретные классы необходимо будет создать во время выполнения, но просто хочет получить класс, который будет выполнять эту работу.источник
getArea()
это не фабричный метод вообще .Это действительно вопрос вкуса. Фабричные классы можно абстрагировать / сопрягать по мере необходимости, тогда как фабричные методы имеют меньший вес (и также имеют тенденцию быть тестируемыми, поскольку они не имеют определенного типа, но для них потребуется известная точка регистрации, похожая на сервис локатор, но для поиска фабричных методов).
источник
Фабричные классы полезны, когда возвращаемый ими тип объекта имеет закрытый конструктор, когда разные фабричные классы устанавливают разные свойства для возвращаемого объекта или когда конкретный тип фабрики связан с возвращаемым конкретным типом.
WCF использует классы ServiceHostFactory для извлечения объектов ServiceHost в различных ситуациях. Стандартный ServiceHostFactory используется IIS для извлечения экземпляров ServiceHost для файлов .svc , но WebScriptServiceHostFactory используется для служб, которые возвращают сериализации клиентам JavaScript. ADO.NET Data Services имеет свой собственный специальный DataServiceHostFactory, а ASP.NET имеет свой ApplicationServicesHostFactory, так как его сервисы имеют частные конструкторы.
Если у вас есть только один класс, который потребляет фабрику, то вы можете просто использовать метод фабрики в этом классе.
источник
Рассмотрим сценарий, когда вам нужно разработать класс Order и Customer. Для простоты и начальных требований вы не чувствуете необходимости в фабрике для класса Order и заполняете вашу заявку множеством операторов 'new Order ()'. Все работает хорошо.
Теперь появляется новое требование, что объект Order не может быть создан без ассоциации с клиентом (новая зависимость). Теперь у вас есть следующие соображения.
1. Вы создаете перегрузку конструктора, которая будет работать только для новых реализаций. (Неприемлемо). 2- Вы изменяете подписи Order () и меняете каждый вызов. (Не хорошая практика и настоящая боль).
Вместо этого, если вы создали фабрику для Класса заказа, вам нужно всего лишь изменить одну строку кода, и все готово. Я предлагаю Фабричный класс для почти каждой совокупной ассоциации. Надеюсь, это поможет.
источник
если вы хотите создать другой объект с точки зрения использования. Это полезно.
источник
Любой класс, откладывающий создание объекта до его подкласса для объекта, с которым он должен работать, можно рассматривать как пример шаблона Factory.
Я подробно упомянул в другом ответе на https://stackoverflow.com/a/49110001/504133
источник
Я думаю, что это будет зависеть от степени слабой связи, которую вы хотите привнести в свой код.
Фабричный метод очень хорошо разделяет вещи, но фабричного класса нет.
Другими словами, проще изменить вещи, если вы используете фабричный метод, чем если вы используете простую фабрику (известную как фабричный класс).
Посмотрите на этот пример: https://connected2know.com/programming/java-factory-pattern/ . Теперь представьте, что вы хотите принести новое животное. В классе Factory вам нужно изменить Factory, но в методе factory нет, вам нужно только добавить новый подкласс.
источник
Фабричные классы более тяжелые, но дают вам определенные преимущества. В случаях, когда вам необходимо построить ваши объекты из нескольких источников необработанных данных, они позволяют вам инкапсулировать только логику построения (и, возможно, агрегацию данных) в одном месте. Там его можно протестировать абстрактно, не обращая внимания на интерфейс объекта.
Я нашел этот полезный шаблон, особенно когда я не могу заменить или неадекватно ORM и хочу эффективно создавать экземпляры многих объектов из объединений таблиц БД или хранимых процедур.
источник
Я сравниваю фабрики с концепцией библиотек. Например, у вас может быть библиотека для работы с числами и другая для работы с фигурами. Вы можете хранить функции этих библиотек в логически названных каталогах как
Numbers
илиShapes
. Это общие типы, которые могут включать целые числа, числа с плавающей запятой, двойные точки, длинные или прямоугольники, круги, треугольники, пятиугольники в случае форм.Заводской петтер использует полиморфизм, инъекцию зависимостей и инверсию контроля.
Заявленная цель фабричных шаблонов:
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
Итак, допустим, что вы создаете операционную систему или платформу и строите все отдельные компоненты.
Вот простой пример концепции Factory Pattern в PHP. Я не могу быть 100% на всем этом, но это предназначено, чтобы служить простым примером. Я не эксперт.
источник
NumbersFactory::makeNumber( 'float', 12.5 );
дает мне просто сказать,new Float(12.5);
если я знаю, что мне нужноFloat
? Это то, что я не понимаю о фабриках ... какой смысл?