Шаблоны Java. FactoryMethod (Фабричный метод)
HTML-код
- Опубликовано: 1 май 2016
- proselyte.net/
Шаблон: Фабрика (Factory Method)
=======================================================================================================
Цель:
Создание интерфейса, который создаёт объект. При этом, выбор того, экземпляр какого класса создавать
остаётся за классами, которые имплементируют данный интерфейс.
=======================================================================================================
Для чего используется:
Для делигирования создания экземпляров, другому классу.
=======================================================================================================
Пример использования:
- заранее неизвестно, экземпляры, какого класса нужно будет создавать;
- класс спроектирован таким образом, что создаваемые им объекты имеют свойства определённого класса.
=======================================================================================================
Самый понятный стиль объяснения. Вначале вступление, затем демонстрация сути решаемой паттерном проблемы, а затем её решение. Чётко, быстро и по делу. Спасибо!
Не было пояснено, зачем вводить лишний уровень абстракции в виде фабрики. В рамках данного конкретного рассмотренного примера в клиентском коде вполне можно было в switch/case создавать конечные сущности в виде Developer минуя создание фабрики.
именно! Если вы поняли зачем это, то не могли бы вы объяснить?
@@_camper_5769 не зачем, прост. Притянуто за уши для демонстрации примера создания фабрики. В этом и печаль большинства блогеров-публицистов.
Рад тому, что увидел этот коммент, т.к. тоже не понимал, зачем этот уровень, если можно по слову сразу возвращаться нужного RandomLanguageDeveloper. Думал, что я не понимаю чего-то, но оказалось, что правильно подумал.
потому что switch/case нужно стараться избегать, вследствие одного из принципов solid, а точнее его второго принципа. при создании объекта, придется еще лезть под это switch и там добавлять условие, что не есть хорошо, на самом то деле.
Я согласен, что следует всегда минимизировать условную логику трансформируя такой код в полиморфизм иерархии наследования. Но в данном случае разве мы избавились от условной логики? Мы просто её переместили, а значит ровным счётом ничего не достигли.
Спасибо за труд. Самые понятные примеры.
Спасибо, всё понятно. Когда идёт последовательное усовершенствование кода с нуля до заданного шаблона, то всё идеально воспринимается (чем сразу написать правильный, но сложный код) :)
да, куда лучше чем в обьясняли
Превосходное объяснение фабричного метода. Просто лучшее из всех.
Теперь при добавлении нового наследника Developer, программисту придётся изменять не один, а целых два зеркальных класса, и один статичный метод с вермишелью из if else. Просто потрясающий шаблон! Советую ещё через методов 5 с разными спецификациями это всё прогнать, чтобы изменять ещё их, если кому мало
Правильно, даешь супер-класс где все до кучи и авер 500 строк кода, вот так сразу все понятно будет
Спасибо за урок. Неделю учу этот паттер на англ и на русском,не понимала пока ваше видео не посмотрела!!!
О, наконец-то разобрался с этим паттерном. Оказалось все легко) спасибо!
Спасибо огромное за видео! Очень доходчиво объясняете, удивлена, что на Вашем канале мало подписчиков.
Спасибо за отзыв!
Спасибо большое за объяснение. Без практики довольно тяжело запоминать паттерны. Но Ваше объяснение даёт базовые понимания этого паттерна!
Спасибо за отзыв!
Долго не мог понять, что за фабричный метод и зачем он нужен. На данном примере можно понять, что фабричный метод штука очень не сложная но в то же время полезная.
Спасибо Евгений.
Спасибо за отзыв!
Рад , что материал помог разобраться.
Ты красавчик. Здоровья тебе и твоим близким!
спасибо тебе добрый человек ! и английский у тебя тоже хороший. А то других слушаешь, уши заворачиваются в трубочку
Спасибо. Хорошо объясняете!
Спасибо, отличное объяснение
Ты гений. Спасибо !
Да спасибо, очень интересно! )
Спасибо автору за видео. Все такие умные в комментах, а вот видео дельного совершенного никто не записал, а жаль. Можно было бы столько вариантов посмотреть и оценить по достоинству данный шаблон
Спасибо за отзыв!
Крутой талант объяснять !
Спасибо за отзыв!
Честно, лучшего объяснения этого паттерна не видел)
делегирование)) а так супер конечно! Хотелось бы еще несколько видосов для разъяснения ключевых различий между паттернами. Например прокси и декоратор. Спасибо за ваш труд.
Спасибо за отзыв :)
Если я правильно понимаю, то еще смысл данного шаблона в том, что в аргументы методов можно добавлять экземпляр интерфейса, и тогда методу будет все равно какого в типа объект придет в момент выполнения программы.
Большое спасибо!
У меня только один вопрос. В каком случае нам может понадобиться создавать объекты с учетом того что мы работаем с ioc контейнером?
Женя, огромный тебе тебе респект. Ты оказывается еще владеешь С++?! Это вызывает большой уважение. Этот язык сложнее Java. После того как я освою Java, я очень хочу освоить С++. Мне кажется очень круто то, что этот язык может управлять железом. Все топовые игры пишутся на С++
Красиво пояснил, молодец. Я понял.
Евгений Здравствуйте , как думаете сейчас смотря на ваш код его же можно было усовершенствовать чтобы мы ужже не зависели от статического метода при добавлении нового класса?
Ваще круть!
Очень полезно было, как на пальцах)
Если бы мог поставил 100 "пальцев вверх"
как ваши успехи в разработке спустя 6 лет?
@@user-er5uz4os1t спился
Хорошо, что есть комменты, а то из видео вообще не понятно, что даёт данный паттерн и зачем он существует. А вот почитаешь комменты - станет понятно, что просто пример в видео не просто урезанный, а кастрированный, не отображающий сути паттерна.
Спасибо!
Пожалуйста, Дарья.
Мудрёный вариант реализации, конечно, но видео отличное, спасибо
Прежде всего спасибо за ролик, суть кажется я уловил - вместо создания трёх классов с полезным кодом, мы городим ещё столько же классов прослоек и прослойки между прослойками - интерфейсы. И все это для того чтобы ленивые программисты излишне не утруждали себя если необходимо внести какие то изменения в основную логику работы программы.
Прежде всего для того, чтобы создание по-настоящему сложных классов с множеством необходимых данных создавались одной строкой кода , а не простыней кода )
@@EugeneSuleimanov желательно было это и упомянуть в видео)
Все ок, понятно и доступно. Но лучше у фабрике сделать какой-то метод в который передаем "specialty" и при это нам вернут не фабрику, а уже девелопера.. Так же лучше использовать int значение или Enum вместо String для (specialty), ну и в самом методе createFactory проситься switch вместо ифов (но это уже вкусовщина). Но так все понятно.
вот это намудрил, нужно несколько раз пересмотреть, то мыли запутались под конец, а так норм)
Спасибо! Я только запутался какая разница между Фабричным методом и Абстрактной фабрикой.
цель фабрик - создание ОБЪЕКТОВ и инкапсуляция создания объекта вне клиентского кода, тем самым мы освобождаем клиента от больших изменений кода (как показано на примере метода main), а все изменения инкапсулируем в объекте "фабрика", тем самым не нарушаем принцип открытости к расширению программы и закрытости к ее изменению уже существующего кода. Это фишка, которая предоставляет нам ООП.
Используя Фабричный метод создаётся ОБЪЕКТ классами (JavaDeveloperFactory и PHPdeveloper factory), реализующими абстракцию (DeveloperFactory) для создания объекта интерфейса (Developer). Т.е. используется наследование для реализации этого метода.
Абстрактная фабрика создаёт СЕМЕЙСТВО ОБЪЕКТОВ. Абстрактная фабрика используется с помощью композиции, т.е. создав в клиенте экземпляр абстрактной фабрики, ты задаешь создание всех объектов сразу, которые представляют собой одно семейство объектов (ингредиенты к блюду, виды цветов в одном букете, и тд). И используешь объекты этого семейства.
Читай HeadfirstJava паттерны. Фабрика
Абстрактная фабрика, состоит из фабричных методов
Спасибо Вам) Вы делаете очень полезные видео) Хотел спросить как сделать в IDE как у Вас что бы показывало UML diagrams?
День добрый, Дмитрий.
Спасибо за отзыв.
Это стандартный плагин, который входит с Ultimate Edition. В Community его, к сожалению, нет.
@@EugeneSuleimanov Евгений, а есть ли достойная замена для Community Edition? По вашему мнению?
@@Dmitry2385 ultimate edition :) По моему мнению - Jet Brains делает лучшие IDE. А для Java - лучше IDEA точно нет.
@@EugeneSuleimanov Евгений, я имел ввиду uml plugin для idea Community edition.
толково)
5 лет прошло, 21 год на дворе, но лучше объяснения на ютубе я не нашёл
И это прискорбно
Спасибо!!!
Пожалуйста, Андрей.
Спасибо за отзыв )
createDeveloperBySpecialty() ...можно было сделать не статичным? Если сделать не интерфейс, а абстрактный класс Фабрику? Или нам нужно будет предусмотреть возможность расширения фабрик?
Очень круто объясняешь, спасибо. И слава коду, что на ютубе можно поставить скорость воспроизведения 0.75 для заторможенных вроде меня)
может быть так нужно: ветвление делать в единственной фабрике и там же создавать разработчиков?
Что это за фишка с диаграммами? В андроид студии есть такая?
Евгений, отличные видео, спасибо. Но есть вопрос.
Так и не понял, какой выигрыш нам дает использование этого паттерна по сравнению с классическим полиформизмом (через интерфейс)? Все равно нужно менять тип вызываемого класса, причем в клиенте, так не все ли равно что менять, тип класса Developer или тип вызываемой фабрики? Я вижу только увеличение объема кода, кроме классов нужно создавать столько же фабричных методов...
Спасибо
Полиморфизм даёт нам позможность переопределять поведение класса, а фабрика отвечает за создание объектов.
А код в клиентском классе является лишь примером использования.
То, что код - это лишь пример, я понимаю. Не могу сообразить, чем создание объектов в фабрике предпочтительнее непосредственного создания объектов. И так, и так, для добавления новых классов или изменения типов объектов надо править код, вся разница, что без паттерна мы правим код в клиенте, а с паттерном - в классе фабрики. Что мы этим выигрываем? Или есть еще что-то, что я не понял?
Tariel Regev Вероятнее всего, вы не сталкивались с по-настоящему сложными системами, в которых мы изначально не имеем всех данных для создания объекта, а получаем их из разных источников. Ведь, если нам необходима ссылка на какой-то объект SomeObject, то, намного разумнее поместить эту ссылку в фабрику а не в клиентский код.
дякую велике
Дякую за відгук
Нормально, но я в последнее время отказался от флагов в виде стрингов как в примере: java, c++, php, использую enum-ы. А так тема понятна, спасибо за видео.
Тоже в голову мысль пришла ограничить варианты через перечисления.
@@user-sj9kh4pf7n да, это норм практика, так можно не переживать, что кто-то, передаст что-то не то )))
Все советуют использовать только enum , в строке легко ошибиться , нежели в перечисление .
Можно ожидать Developer как параметр и передавать нужный класс и делать instanceof для нужной фабрики
здесь стринги как учебный пример, полагаю
для упрощения восприятия
Factory и Factory Method это разные шаблоны
Abstract Factory и Factory - вот что есть одно и то же.
Еще Factory Method может называться Virtual Constructor
в каких источниках описан шаблон с названием Factory?
Осталось ощущение что метод createDeveloperBySpecialy(String string) может с тем же успехом (работая на if else) возвращать готового девелопера, а не фабрику. Программа при этом будет работать так же, а мы избавимся от лишних 3-х классов и 1-го интерфейса.
Нет, это плохая идея. Для примитивного класса Developer может и годится (и то, так себе идея), для чего-то серьёзного - нет.
Суть как я понял в том, что если сравнить график
функции(количество классов, коэффициент показывающий на сколько код упрощается если использовать фабрику)
и
функции(количество классов, коэффициент показывающий на сколько код упрощается если НЕ использовать фабрику)
То увидим что - количество кода растет в второй функции.
Хотя на первый взгляд да, никаким упрощением и не пахнет
Не вижу никакого преимущества, почему в том if-else блоке просто не возвращать конкретных Developer-ов, а не фабрики?
Например создание девелопера может быть не таким простым. А девелопер фактори инкапсулирует конкретную реализацию девелопера
@@JohnWickMovie а каким это не простым ? есть ли примеры ? если весь процесс создания инкапуслирован внутри конструктора класса "девелопер", и фабрика при этом ничего не вызывает кроме как конструктор этого класса.
upd: это может быть вызов разных конструкторов, в зависимости от ситуации? И мы как бы скрываем из основного метода MAIN большую часть портянки блоков IF / SWITCH в этих самых фабриках, и таким образом получаем более красивое архитектурно решение?
@@kolob204 Здесь просто демонстрируется пример абстракции. В жизни случают сложные ситуации, например тебе нужно отслеживать создание объектов или аллоцировать его в собственном участке памяти, фабрики это позволят легко делать. Да и весь COM от Microsoft построен подобным образом, взгляни на какой нибудь DirectX на досуге, в качестве примера фабрики
Это не лайфхак для копипаста, почитайте тз. Все круто , спасибо мужик!❤
Спасибо за отзыв!
Паттерн, который только усложняет. Если вы хотите добавить девелопера - пишете класс девелопера, и создаёте через new - Все. А если у вас есть фактори - вам надо добавить нового деведопера, новую фактори, и потом ещё добавить новый if. Ёлки палки - где тут преимущество. Этот паттерн в таком *голом* виде не делает проще. Если вы хотите показать основы - то лучше их показыать не на таких синтетических примерах. После такого только ещё больше вопросов. Если вы думаете, что чем меньше деталей вы говорите, тем проще слушателям - это не так. Детали очень важны и очень интересны
Вероятнее всего вы не смотрели введение и не обратили внимание на цель этого курса. Но, в чем-то вы, возможно, правы.
не createDeveloperBySpeciality, а createDeveloperFactoryBySpeciality
зачем нам создавать много фабрик, если можно создать одну с параметрами?
По поводу имени метода - вы правы, тут нужно будет исправить - название метода вводит в заблуждение.
А по поводу количества фабрик, важно понимать, что это обучающее видео, а не уровня production.
И цель - понимание того, что и как работает.
ясно, спасибо
что и как и так понятно. Ответь на вопрос ЗАЧЕМ?
Актуальный вопрос спустя 3 года, таки ЗАЧЕМ?
@@hexruin4569 на самом деле в каждой фабрике для наглядности тоже должны быть ветвления. Например тестировщика, разработчика, техлида. Реализовать это вне фабрики будет проблематично, поэтому удобно будет вынести это так как указал автор. С одним лишь методом в фабрике это действительно бессмысленно. В данном случае достаточно интерфейса девелопера
Вроде как все понятно и просто, но осознать полезность этого подхода не получается. Было бы не плохо если бы кто-то объяснил именно этот момент
вот именно.
а вообще взялся учить по этому сайту. вроде очень даже хороший
refactoring.guru/ru/design-patterns/factory-method
Попробую пояснить полезность фабричного метода.
Если в вашем коде будет много мест с "Developer developer = new JavaDeveloper". Представим 100 таких инициализаций класса. То когда вы захотите заменить JavaDeveloper на CppDeveloper, не смотря на то что вы использовали интерфейс, вам все равно придется сделать 100 изменений в коде.
А фабричный метод инкапсулирует в себе инициализацию объекта определенного класса.(new JavaDeveloper) .
Таким образом в данном кейсе вы заменяете "new JavaDeveloper" на "new CppDeveloper" только в одном месте внутри Фабрики, а в тех старых местах инициализации будет стандартный код "Developer developer = developerFabric.createDeveloper() "
@@EllaLavrik т.е. мы просто создаем "промежуточную переменную" , через которую идет создание новых объектов и когда нам надо поменять этот класс на другой мы типа меняем ссылку в этой переменной а все наши созданные объекты ее автоматом подхватывают? Правильно я понял? У меня один вопрос, а что так часто приходится изменять классы в реальных проектах? Вот только если нам надо просто добавить новый класс фабрика (из вышеприведенного примера) нам ни как в этом не поможет, т.к. кол-во приседаний от этого не уменьшается. Или я не прав?
@@EllaLavrik А каким образом с точки зрения количества кода создание 100 java девелоперов в фабрике проще?
@@lighto263 оно не проще. Суть именно в подходе к инициализации. Допустим(!!!), что программисту на ассемблере надо знать только ассемблер и архитектуру процессоров. То есть его инициализация состоит только в подготовке знаний самого ассемблера и АП. Всего две строки. А программисту на котлине надо знать Java Core, десяток библиотек и фреймворков, кучи паттернов, этой же кучи паттернов, но уже для Java и Kotlin, и собственно котлин. Например, инициализация такого программиста состоит из 20 строк. Итого, у нас получилась портянка IF'ов из 30 строк, и это только на два языка. Добавляем еще C++, C#, JS, TS - и, вуаля, у нас уже только стратегия выбора и инициализации программиста разрослась в 1000 строк трудноусвояемых условий. Читать такой код уже сложно. А в ходе развития задачи мы постоянно добавляем новые языки в эту, с позволения сказать, фабрику программистов. Паттерн "фабрика" же позволяет реализации создани и инициализации первичных параметров вынести в отдельный класс/объект. Каждый такой объект сам определяет, как ему создавать экземпляр - у кого-то пара строк, а у кого-то сотня, плюс хождения во внешние системы и тяжелая математика. А вот стратегия выбора способа создания конкретного программиста становится очень компактным и линейным кодом, который влазит уже в экран. Да, дальше можно стратегию сделать еще более "правильной", не требуя создавать портянку IF'ов, но это уже совсем другая история. Резюмируя, паттерн Factory нужен в первую очередь для улучшения читаемости, и снижения complexity кода.
krosava!
спасибо , а можно эти if заменить на полиморфизм ?
Можно, но это будет не самым простым к пониманию решением. Можно создать ассоциативный массив String->Factory, и при инициализации его заполнять всеми возможными билдерами. Доступ к нужному в таком случае произойдёт просто по индексу. Да и заполнение такой коллекции можно сделать через рефлексию или Dependency Injection, но это уже совсем энтерпрайзно. Но это всё уже не к шаблону Factory, а скорее к Strategy.
Вот чаще у меня возникает случай когда те два класса существуют и существует этот интерфейс. И нужно чтобы те классы оставались чистыми, а по интерфейсу можно было взаимодействовать с ними двумя. Тут получается, что нужен класс (или несколько), которые будут реализовать логику тех двух классов через этот интерфейс.
Что это за классы будут? Какие паттерны они должны реализовать?
Такое может возникнуть, когда два класса используют два разных источника данных (Модели к разным таблицам, например), но у классов будет одна группа действий. Под один интерфейс их не подвести за счет того, что они должны оставаться чистыми (например, не соответствуют зоне ответственности или это библиотека стороннего разработчика).
А можно создать файл с проперти и писать нужного разраба вместо метода ? Или это уже не фабрика?
Здравствуйте. Помогите мне разобраться с диаграммой. Никак не могу установить чтобы также как у вас было отображение при нажатии правой клавиши мыши.
Доброе утро, Михаил.
Это стандартный плагин, который входит только в ULTIMATE версию IDEA. По-другому получить его, вряд ли, получится.
Автор описал Абстрактную фабрику, подходящую для создания групп элементов, а не фабричный метод. Фабричный метод - это когда у тебя продукты/объекты реализуют один интерфейс, и дальше в клиентском коде ты создаёшь метод с конструкцией switch/case, для определения того, какой конкретный объект тебе нужен, фабрика в этом случае не требуется.
Смысл происходяшего был бы понятен, если бы он использовал фабрику для создания ГРУПП ОБЪЕКТОВ ОДНОГО СЕМЕЙСТВА, а не просто одного объекта.
К примеру, нужно создавать не одного Developer, а ещё и SeniorDeveloper, TeamLeadDeveloper и прочее. Тогда есть смысл делегировать их создание методам Абстрактной Фабрики, а фабрику определять через свитч-кейс, и эта фабрика могла бы уже производить ОБЪЕКТЫ ОДНОГО СЕМЕЙСТВА, а не тупо один объект.
Но в любом случае спасибо, с каждым таким видео узнаю что-то новое!
Как по мне, все же лучше сделать одну фабрику с одним методом,где расположить свитч, и в клиентском классе уже обращаться к нему. Конечно, зависит от ситуации, но так куда читаемее со моему мнению.
Я так понимаю данные шаблон актуально использовать если мы создаем много "продуктов" в программе, т.е. фабрика создает много "продуктов" в программе, на то она и называется фабрика, а не один
"продукт" как в вашем примере (у вас типы "продуктов" много, но сам "продукт" один) ? Я понимаю что это учебная прога, но почему то это никто не поясняет. Или я чего то не знаю.
А так спасибо за курс, пожалуй это лучшее что я нашел в ютубе по паттернам.
В любом приложении мы почти всегда создаём много объектов.
Причем, к созданию прибавляется некоторая бизнес-логика.
Поэтому часто имеет смысл вынести функционал создания объектов в отдельный класс.
Спасибо за видео. Но я думал ты в конце вытащишь зависимость от конкретной реализации программиста из клиенсткого кода. Можно было сделать хоть в самой фабрике или например в конфиг файл.
Зачем? Как вы создадите экземпляр класса из ничего? цель фабрик в отделении создании объектов от неизменяемой части кода, а не в отделении клиентского кода от созданий объектов в принципе!
все правильно вы говорите, странно что в клиенте сделано
придется такую логику теперь писать в каждом клиенте
ИМХО. Надо бы литерал и строковую переменную поменять местами, иначе получим NPE " if ("java".equalsIgnoreCase(speciality)) "
Добавим дерево из ифелсов и наш код станет более гибким, отвечаю!
Чтобы это всё понять, нужны знания как минимум Java core
Безусловно
Разве клиенту надо видеть этот статический метод createDeveloperBySpecialty ? В чем тогда смысл фабрики если клиенту все равно придется апдейтить код каждый раз когда добавится новый тип разработчика. Не надо ли его спрятать в базовый класс DeveloperFactory ?
Зачем создавать интрефейс на каждого разраба?? Можно ведь просто в DeveloperFactory делать логику через if и возвращать конкретный объект.
диаграммы выводятся с помощью какого-то плагина?
Добрый вечер, Евгений. Это стандартный плагин в Intellij IDEA Ultimate edition. Т.е. в community такого плагина нет
@@EugeneSuleimanov спасибо
а можно строки для фабрики java и тд загнать в enum?
Добрый день, Михали.
Да, конечно, можно.
Я так и делаю, по сути в примере это обычный флаг, в таком случае использую enam-ы.
Мне кажется здесь была рассмотрена абстрактная фабрика, а не фабричный метод.
Не хватает плюсов и минусов, а их много
Я вот чего не могу понять, а почему в данном примере нужна именно фабрика? Почему нельзя просто вот так сделать:
public static void main(String[] args) {
Developer javaDeveloper = createDeveloperBySpeciality("java");
javaDeveloper.writeCode();
Developer cppDeveloper = createDeveloperBySpeciality("cpp");
cppDeveloper.writeCode();
}
static Developer createDeveloperBySpeciality(String speciality){
if(speciality.equalsIgnoreCase("java")){
return new JavaDeveloper();
}else if(speciality.equalsIgnoreCase("cpp")){
return new CppDeveloper();
}else throw new RuntimeException(speciality + " is unknown");
}
Java developer IS WRITING code... (present continuous)
тут и Фабричный Метод из гоф, и Статик Фактори Метод из блоха )
А зачем вообще фабрики, можно же в методе getDeveloperBySpeciality(String tag){
Developer developer;
switch(tag):
case "java":
developer = new AnyDeveloper();}
return developer;}
Зачем Фабрики??? Объясните пожалуйста, эта тема мне очень интересна. Я начинающий Android Developer.
Потому что объекты могут быть крайне сложными и выносить инициализация в клиентский код не практично
Я понял что вы сделали, но не понял зачем это нужно…
короче вместо одного класса придется создавать 5, круто че
тут очень простой пример, а в реальности когда много запутанного кода, создание фабрик оправдано.
Я то же не особо понял плюсов, а что мешает так же создать метод который вернет нужный класс, если мы на каждый класс делаем свою фабрику?
+++ вообще непонятно вместо пары строк такая лапша
@@vsezanyato ну автор, на мой взгяд, взял не самый лучший пример. На самом деле может быть и одна фабрика (например, в конкретном примере). Но в сложных проектах дела обстоят по другому и создание фабрики фабрик оправдано. Например, есть Enum с условным DeveloperTier (Junior, Middle, Senior), и уже исходя из него и будет создаваться Developer.
Factory factory = createDeveloperFactory("java");
Developer developer = factory.createDeveloper(DeveloperTier.SENIOR)
developer.writeCode();
@@TheSporpion, ничего не мешает, автор создал очень плохую реализацию, с совершенно лишним слоем фабрик, еще и в клиентский класс запихнул функцию создания фабрик, которую придется менять, хотя изначально именно к изменениям в клиентском классе была претензия.
В конце код стал более громоздким чем в начале... зачем..?
даже я понял
Видео про фабрику, как реализацию низкосвязного кода, в итоге свести к жесткой зависимости от значения стринга? Читающий обучалку не понимает, о чем читает.
Без статичного метода в клиенте вообще бесполезная штука. Что так, что так надо менять ручками java /cpp.
А зачем нужно так много фабрик если их единственная цель создавать разработчиков? Их же вручную можно создавать таким же образом. Без кучи классов для фабрик.
Получается этот шаблон для тех у кого много времени, чтобы плодить лишние сущности.
Если никто не понял чего мы пытаемся здесь добиться то максимально рекомендую данное видео
ruclips.net/video/rd6wxPzXQvo/видео.html&ab_channel=JPoint%2CJokerиJUGru
без объяснения зачем и в каких случаях нужен этот фабричный метод мне как новичку не понятно зачем надо создавать кучу классов и интерфейсов чтобы в итоге создать один объект и вызвать его метод 🙃
зачем столько классов плодить ?
Потому что класс может быть сложным и его инициализация - тоже. И, вместо того, чтобы классе-клиенте писать простыню кода мы просто вызываем метод у класса-фабрики. Ну, и гибкость приложения, чтобы была возможность легко вносить изменения в программу.
@@EugeneSuleimanov принцип как MVC
Спасибо, но понятнее не стало
минусую. Потому что как и в других видео ничего не объяснено. Почему я должен воротить такую не**ическую инфраструктуру только чтобы делегировать создание классов? Что такого сказано в видео чего я не могу прочитать в книге или просто увидев название этого шаблона?
Автор, вот лучше ответил бы на вопрос: почему я не могу возвращать из метода с if'ми сразу экземпляр класса тем более что метод называется createDeveloper а не createFactory? Зачем мне прослойка из структуры фабрик между клиентом и реализациями интерфейса? Вот на такие вопросы надо давать ответы в видео а не просто кратко пересказывать содержимое книги.
Афобий II просмотр введения в цикл даст ответы на все вопросы
Такое нагромождение из if else не есть гуд. Это нарушение принципа open/close.
Спасибо за комментарий!
Старался делать в точности по материалам GoF, если подскажите, где было отклонение от их примеров - буду признателен.
@@EugeneSuleimanov там все было Ок, на мой взгляд, до появления статического метода получения разработчика по специальности. Этот метод нарушает принцип open/close.
как-то не очень сплошные ифы смотрятся, лучше уже switch
Не лучше, switch жёстче, чем if else, т.к. зависит от конкретного сравниваемой переменной и ее типа
В switch ignorecase не получится
На мой взгляд нет ответа на самый главный вопрос: ЧЕМ фабричный метод ЛУЧШЕ классического конструктора. Ответ прост на примере. Необходимо создать объект класса Студент. При определенных параметрах объект создать не возможно. Например, при возрасте менее 16 лет . Фабрика СМОЖЕТ вернуть NULL. А вот конструктор НЕ СМОЖЕТ. В этом и есть прелесть фабрики.
Более обобщенно - фабрика может скрыть любую логику по созданию объекта - например создание объекта, который требует параметры в конструктор, кеширование, выбор между несколькими реализациями, скачивание данных (даже класса возвращаемого объекта) из интернета
Бедная клавиатура
Она не выдержала :)
Бедная клавиатура...
Она до сих пор приходит ко мне во снах :)
Абсолютно некорректный пример. Вместо паттерна "фабричный метод" показан урезанный паттерн "абстрактная фабрика".
В итоге имеется бесполезный слой фабрик, а фабрика является пустой оберткой над конструктором девелопера.
И самый сок, началось все претензией к тому, что нужно вносить изменения в клиентский класс, закончилось созданием в клиентском классе целого метода под это дело, в итоге количество мест, куда нужно вносить изменения, только увеличилось.
Как нужно было сделать: ДевелоперФабрик сделать классом, в нем реализовать метод криэйтДевелопер, который принимает строку и возвращает объект нудного девелопера. Итого минус изменения в клиентском классе, минус два ненужных класса, соблюдаются принципы единственной ответственности и простоты, пример становится понятным и, что самое главное, применяемым на практике.
Как насчет такого, более интерактивного варианта?
public class Program {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Введите язык программирования для создания нового программиста:");
System.out.println("1. \"java\"
2. \"c++\"
3. \"php\"
");
String specialtyFromUser = sc.nextLine();
DeveloperFactory developerFactory = createDeveloperBySpecialty(specialtyFromUser);
Developer developer = developerFactory.createDeveloper();
developer.writeCode();
}
static DeveloperFactory createDeveloperBySpecialty(String specialty) {
return switch (specialty.toLowerCase()) {
case "java" -> new JavaDeveloperFactory();
case "c++" -> new CppDeveloperFactory();
case "php" -> new PhpDeveloperFactory();
default -> throw new RuntimeException(specialty + " specialty is unknown.");
};
}
}
Вместо паутины if else лучше мапу
Не понимаю людей ,которые пишут про понятное объяснение. Что тут понятно? Для чего куча всего этого создается? Ничего не понятно. А статичный метод? Серьезно? А если на разработчиков всех языков программирования выводить,то какое же это полотно получится. Что за бред? И сколько будет доп класс с переопределенными методами,в которых будет выводиться строка под каждого. Это же с ума сойти можно. Я не разработчик,может сейчас фигню сморожу. Но не проще было бы сделать,что бы этот статичный метод принимал не строку с названием специальности а ОБЪЕКТ? Интерфейс ,блин. И в main вместо строки лямбду передавать. И не придется каждый раз при добавлении нового создавать доп классы, лепить доп условия.
Зачем так сложно ? Зачем столько фабрик ? Почему ответственность за создание нужного класса не инкапсулируется в фабрике, а реализована в статическом методе пользователем ? Разве это не нарушает основную идею паттерна ? Почему нельзя фабричный метод сделать с параметром ?
Это реализация шаблона по GoF.
Если вы не согласны с их подходом к проектированию...
Без комментариев.
Даже если ты не прав, с таким ответом, свою неправоту уже не признаешь. Не ссылок, ни примеров. Разве в книге нет примера фабричного метода с параметром?
Странный комментарий.
Раз 10 перечитал - так и не понял о чём он.
Понял только вопрос. Отвечаю:
В книге есть пример, но несколько более сложный и его трудно использовать без контекста всей книги.
Я ничего утверждаю, но возможно своим упрощением вы разрушали основную идею паттерна. :))
Какое упрощение?
Паттерн сделан стандартно - а клиентский класс всего лишь демонстрирует его работу.
больше похоже на полиморфизм
Зачем лепить фабрику в примере про фабричный метод
конечно шляпа, а не урок
java головного мозга)
25 ненужных классов, которые не решают никак проблему создания объектов, просто оборачивают это в 3 слоя.
Ещё и solid сломан.
Понятно почему у вас в java нормальными считаются стектрейсы в 2000 вложений.