Не было пояснено, зачем вводить лишний уровень абстракции в виде фабрики. В рамках данного конкретного рассмотренного примера в клиентском коде вполне можно было в switch/case создавать конечные сущности в виде Developer минуя создание фабрики.
Рад тому, что увидел этот коммент, т.к. тоже не понимал, зачем этот уровень, если можно по слову сразу возвращаться нужного RandomLanguageDeveloper. Думал, что я не понимаю чего-то, но оказалось, что правильно подумал.
потому что switch/case нужно стараться избегать, вследствие одного из принципов solid, а точнее его второго принципа. при создании объекта, придется еще лезть под это switch и там добавлять условие, что не есть хорошо, на самом то деле.
Я согласен, что следует всегда минимизировать условную логику трансформируя такой код в полиморфизм иерархии наследования. Но в данном случае разве мы избавились от условной логики? Мы просто её переместили, а значит ровным счётом ничего не достигли.
Теперь при добавлении нового наследника Developer, программисту придётся изменять не один, а целых два зеркальных класса, и один статичный метод с вермишелью из if else. Просто потрясающий шаблон! Советую ещё через методов 5 с разными спецификациями это всё прогнать, чтобы изменять ещё их, если кому мало
Спасибо, всё понятно. Когда идёт последовательное усовершенствование кода с нуля до заданного шаблона, то всё идеально воспринимается (чем сразу написать правильный, но сложный код) :)
Долго не мог понять, что за фабричный метод и зачем он нужен. На данном примере можно понять, что фабричный метод штука очень не сложная но в то же время полезная. Спасибо Евгений.
Самый понятный стиль объяснения. Вначале вступление, затем демонстрация сути решаемой паттерном проблемы, а затем её решение. Чётко, быстро и по делу. Спасибо!
Спасибо автору за видео. Все такие умные в комментах, а вот видео дельного совершенного никто не записал, а жаль. Можно было бы столько вариантов посмотреть и оценить по достоинству данный шаблон
Прежде всего спасибо за ролик, суть кажется я уловил - вместо создания трёх классов с полезным кодом, мы городим ещё столько же классов прослоек и прослойки между прослойками - интерфейсы. И все это для того чтобы ленивые программисты излишне не утруждали себя если необходимо внести какие то изменения в основную логику работы программы.
Прежде всего для того, чтобы создание по-настоящему сложных классов с множеством необходимых данных создавались одной строкой кода , а не простыней кода )
Если я правильно понимаю, то еще смысл данного шаблона в том, что в аргументы методов можно добавлять экземпляр интерфейса, и тогда методу будет все равно какого в типа объект придет в момент выполнения программы.
Попробую пояснить полезность фабричного метода. Если в вашем коде будет много мест с "Developer developer = new JavaDeveloper". Представим 100 таких инициализаций класса. То когда вы захотите заменить JavaDeveloper на CppDeveloper, не смотря на то что вы использовали интерфейс, вам все равно придется сделать 100 изменений в коде. А фабричный метод инкапсулирует в себе инициализацию объекта определенного класса.(new JavaDeveloper) . Таким образом в данном кейсе вы заменяете "new JavaDeveloper" на "new CppDeveloper" только в одном месте внутри Фабрики, а в тех старых местах инициализации будет стандартный код "Developer developer = developerFabric.createDeveloper() "
@@EllaLavrik т.е. мы просто создаем "промежуточную переменную" , через которую идет создание новых объектов и когда нам надо поменять этот класс на другой мы типа меняем ссылку в этой переменной а все наши созданные объекты ее автоматом подхватывают? Правильно я понял? У меня один вопрос, а что так часто приходится изменять классы в реальных проектах? Вот только если нам надо просто добавить новый класс фабрика (из вышеприведенного примера) нам ни как в этом не поможет, т.к. кол-во приседаний от этого не уменьшается. Или я не прав?
@@lighto263 оно не проще. Суть именно в подходе к инициализации. Допустим(!!!), что программисту на ассемблере надо знать только ассемблер и архитектуру процессоров. То есть его инициализация состоит только в подготовке знаний самого ассемблера и АП. Всего две строки. А программисту на котлине надо знать Java Core, десяток библиотек и фреймворков, кучи паттернов, этой же кучи паттернов, но уже для Java и Kotlin, и собственно котлин. Например, инициализация такого программиста состоит из 20 строк. Итого, у нас получилась портянка IF'ов из 30 строк, и это только на два языка. Добавляем еще C++, C#, JS, TS - и, вуаля, у нас уже только стратегия выбора и инициализации программиста разрослась в 1000 строк трудноусвояемых условий. Читать такой код уже сложно. А в ходе развития задачи мы постоянно добавляем новые языки в эту, с позволения сказать, фабрику программистов. Паттерн "фабрика" же позволяет реализации создани и инициализации первичных параметров вынести в отдельный класс/объект. Каждый такой объект сам определяет, как ему создавать экземпляр - у кого-то пара строк, а у кого-то сотня, плюс хождения во внешние системы и тяжелая математика. А вот стратегия выбора способа создания конкретного программиста становится очень компактным и линейным кодом, который влазит уже в экран. Да, дальше можно стратегию сделать еще более "правильной", не требуя создавать портянку IF'ов, но это уже совсем другая история. Резюмируя, паттерн Factory нужен в первую очередь для улучшения читаемости, и снижения complexity кода.
Женя, огромный тебе тебе респект. Ты оказывается еще владеешь С++?! Это вызывает большой уважение. Этот язык сложнее Java. После того как я освою Java, я очень хочу освоить С++. Мне кажется очень круто то, что этот язык может управлять железом. Все топовые игры пишутся на С++
делегирование)) а так супер конечно! Хотелось бы еще несколько видосов для разъяснения ключевых различий между паттернами. Например прокси и декоратор. Спасибо за ваш труд.
Хорошо, что есть комменты, а то из видео вообще не понятно, что даёт данный паттерн и зачем он существует. А вот почитаешь комменты - станет понятно, что просто пример в видео не просто урезанный, а кастрированный, не отображающий сути паттерна.
По поводу имени метода - вы правы, тут нужно будет исправить - название метода вводит в заблуждение. А по поводу количества фабрик, важно понимать, что это обучающее видео, а не уровня production. И цель - понимание того, что и как работает.
@@hexruin4569 на самом деле в каждой фабрике для наглядности тоже должны быть ветвления. Например тестировщика, разработчика, техлида. Реализовать это вне фабрики будет проблематично, поэтому удобно будет вынести это так как указал автор. С одним лишь методом в фабрике это действительно бессмысленно. В данном случае достаточно интерфейса девелопера
Евгений Здравствуйте , как думаете сейчас смотря на ваш код его же можно было усовершенствовать чтобы мы ужже не зависели от статического метода при добавлении нового класса?
Factory и Factory Method это разные шаблоны Abstract Factory и Factory - вот что есть одно и то же. Еще Factory Method может называться Virtual Constructor
цель фабрик - создание ОБЪЕКТОВ и инкапсуляция создания объекта вне клиентского кода, тем самым мы освобождаем клиента от больших изменений кода (как показано на примере метода main), а все изменения инкапсулируем в объекте "фабрика", тем самым не нарушаем принцип открытости к расширению программы и закрытости к ее изменению уже существующего кода. Это фишка, которая предоставляет нам ООП. Используя Фабричный метод создаётся ОБЪЕКТ классами (JavaDeveloperFactory и PHPdeveloper factory), реализующими абстракцию (DeveloperFactory) для создания объекта интерфейса (Developer). Т.е. используется наследование для реализации этого метода. Абстрактная фабрика создаёт СЕМЕЙСТВО ОБЪЕКТОВ. Абстрактная фабрика используется с помощью композиции, т.е. создав в клиенте экземпляр абстрактной фабрики, ты задаешь создание всех объектов сразу, которые представляют собой одно семейство объектов (ингредиенты к блюду, виды цветов в одном букете, и тд). И используешь объекты этого семейства. Читай HeadfirstJava паттерны. Фабрика
@@JohnWickMovie а каким это не простым ? есть ли примеры ? если весь процесс создания инкапуслирован внутри конструктора класса "девелопер", и фабрика при этом ничего не вызывает кроме как конструктор этого класса. upd: это может быть вызов разных конструкторов, в зависимости от ситуации? И мы как бы скрываем из основного метода MAIN большую часть портянки блоков IF / SWITCH в этих самых фабриках, и таким образом получаем более красивое архитектурно решение?
@@kolob204 Здесь просто демонстрируется пример абстракции. В жизни случают сложные ситуации, например тебе нужно отслеживать создание объектов или аллоцировать его в собственном участке памяти, фабрики это позволят легко делать. Да и весь COM от Microsoft построен подобным образом, взгляни на какой нибудь DirectX на досуге, в качестве примера фабрики
Нормально, но я в последнее время отказался от флагов в виде стрингов как в примере: java, c++, php, использую enum-ы. А так тема понятна, спасибо за видео.
Все ок, понятно и доступно. Но лучше у фабрике сделать какой-то метод в который передаем "specialty" и при это нам вернут не фабрику, а уже девелопера.. Так же лучше использовать int значение или Enum вместо String для (specialty), ну и в самом методе createFactory проситься switch вместо ифов (но это уже вкусовщина). Но так все понятно.
Евгений, отличные видео, спасибо. Но есть вопрос. Так и не понял, какой выигрыш нам дает использование этого паттерна по сравнению с классическим полиформизмом (через интерфейс)? Все равно нужно менять тип вызываемого класса, причем в клиенте, так не все ли равно что менять, тип класса Developer или тип вызываемой фабрики? Я вижу только увеличение объема кода, кроме классов нужно создавать столько же фабричных методов... Спасибо
Полиморфизм даёт нам позможность переопределять поведение класса, а фабрика отвечает за создание объектов. А код в клиентском классе является лишь примером использования.
То, что код - это лишь пример, я понимаю. Не могу сообразить, чем создание объектов в фабрике предпочтительнее непосредственного создания объектов. И так, и так, для добавления новых классов или изменения типов объектов надо править код, вся разница, что без паттерна мы правим код в клиенте, а с паттерном - в классе фабрики. Что мы этим выигрываем? Или есть еще что-то, что я не понял?
Tariel Regev Вероятнее всего, вы не сталкивались с по-настоящему сложными системами, в которых мы изначально не имеем всех данных для создания объекта, а получаем их из разных источников. Ведь, если нам необходима ссылка на какой-то объект SomeObject, то, намного разумнее поместить эту ссылку в фабрику а не в клиентский код.
Осталось ощущение что метод createDeveloperBySpecialy(String string) может с тем же успехом (работая на if else) возвращать готового девелопера, а не фабрику. Программа при этом будет работать так же, а мы избавимся от лишних 3-х классов и 1-го интерфейса.
Паттерн, который только усложняет. Если вы хотите добавить девелопера - пишете класс девелопера, и создаёте через new - Все. А если у вас есть фактори - вам надо добавить нового деведопера, новую фактори, и потом ещё добавить новый if. Ёлки палки - где тут преимущество. Этот паттерн в таком *голом* виде не делает проще. Если вы хотите показать основы - то лучше их показыать не на таких синтетических примерах. После такого только ещё больше вопросов. Если вы думаете, что чем меньше деталей вы говорите, тем проще слушателям - это не так. Детали очень важны и очень интересны
createDeveloperBySpecialty() ...можно было сделать не статичным? Если сделать не интерфейс, а абстрактный класс Фабрику? Или нам нужно будет предусмотреть возможность расширения фабрик?
Можно, но это будет не самым простым к пониманию решением. Можно создать ассоциативный массив String->Factory, и при инициализации его заполнять всеми возможными билдерами. Доступ к нужному в таком случае произойдёт просто по индексу. Да и заполнение такой коллекции можно сделать через рефлексию или Dependency Injection, но это уже совсем энтерпрайзно. Но это всё уже не к шаблону Factory, а скорее к Strategy.
Разве клиенту надо видеть этот статический метод createDeveloperBySpecialty ? В чем тогда смысл фабрики если клиенту все равно придется апдейтить код каждый раз когда добавится новый тип разработчика. Не надо ли его спрятать в базовый класс DeveloperFactory ?
Вот чаще у меня возникает случай когда те два класса существуют и существует этот интерфейс. И нужно чтобы те классы оставались чистыми, а по интерфейсу можно было взаимодействовать с ними двумя. Тут получается, что нужен класс (или несколько), которые будут реализовать логику тех двух классов через этот интерфейс. Что это за классы будут? Какие паттерны они должны реализовать?
Такое может возникнуть, когда два класса используют два разных источника данных (Модели к разным таблицам, например), но у классов будет одна группа действий. Под один интерфейс их не подвести за счет того, что они должны оставаться чистыми (например, не соответствуют зоне ответственности или это библиотека стороннего разработчика).
@@vsezanyato ну автор, на мой взгяд, взял не самый лучший пример. На самом деле может быть и одна фабрика (например, в конкретном примере). Но в сложных проектах дела обстоят по другому и создание фабрики фабрик оправдано. Например, есть Enum с условным DeveloperTier (Junior, Middle, Senior), и уже исходя из него и будет создаваться Developer. Factory factory = createDeveloperFactory("java"); Developer developer = factory.createDeveloper(DeveloperTier.SENIOR) developer.writeCode();
@@TheSporpion, ничего не мешает, автор создал очень плохую реализацию, с совершенно лишним слоем фабрик, еще и в клиентский класс запихнул функцию создания фабрик, которую придется менять, хотя изначально именно к изменениям в клиентском классе была претензия.
Суть как я понял в том, что если сравнить график функции(количество классов, коэффициент показывающий на сколько код упрощается если использовать фабрику) и функции(количество классов, коэффициент показывающий на сколько код упрощается если НЕ использовать фабрику) То увидим что - количество кода растет в второй функции. Хотя на первый взгляд да, никаким упрощением и не пахнет
Автор описал Абстрактную фабрику, подходящую для создания групп элементов, а не фабричный метод. Фабричный метод - это когда у тебя продукты/объекты реализуют один интерфейс, и дальше в клиентском коде ты создаёшь метод с конструкцией switch/case, для определения того, какой конкретный объект тебе нужен, фабрика в этом случае не требуется. Смысл происходяшего был бы понятен, если бы он использовал фабрику для создания ГРУПП ОБЪЕКТОВ ОДНОГО СЕМЕЙСТВА, а не просто одного объекта. К примеру, нужно создавать не одного Developer, а ещё и SeniorDeveloper, TeamLeadDeveloper и прочее. Тогда есть смысл делегировать их создание методам Абстрактной Фабрики, а фабрику определять через свитч-кейс, и эта фабрика могла бы уже производить ОБЪЕКТЫ ОДНОГО СЕМЕЙСТВА, а не тупо один объект. Но в любом случае спасибо, с каждым таким видео узнаю что-то новое!
Как по мне, все же лучше сделать одну фабрику с одним методом,где расположить свитч, и в клиентском классе уже обращаться к нему. Конечно, зависит от ситуации, но так куда читаемее со моему мнению.
Я вот чего не могу понять, а почему в данном примере нужна именно фабрика? Почему нельзя просто вот так сделать: 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"); }
А зачем вообще фабрики, можно же в методе getDeveloperBySpeciality(String tag){ Developer developer; switch(tag): case "java": developer = new AnyDeveloper();} return developer;} Зачем Фабрики??? Объясните пожалуйста, эта тема мне очень интересна. Я начинающий Android Developer.
Видео про фабрику, как реализацию низкосвязного кода, в итоге свести к жесткой зависимости от значения стринга? Читающий обучалку не понимает, о чем читает.
Думаю что паттерн фактори используется для вносение доп функциональность в программи. К примеру из java hed first привожу пример. Есть пицарея. Программа создана для одного пицарея, а если пицарея начинает расшираться то как постпуить так что бы вносить доп изменение ? Думаю в этом поможет фабричныий метод что бы вносит доп франшизы к нашему пицарею и тд. Pizzastore extends NystylePizza store, ChicagoPizzaStore, Russian Pizza Store. So on
Спасибо за видео. Но я думал ты в конце вытащишь зависимость от конкретной реализации программиста из клиенсткого кода. Можно было сделать хоть в самой фабрике или например в конфиг файл.
Зачем? Как вы создадите экземпляр класса из ничего? цель фабрик в отделении создании объектов от неизменяемой части кода, а не в отделении клиентского кода от созданий объектов в принципе!
Я так понимаю данные шаблон актуально использовать если мы создаем много "продуктов" в программе, т.е. фабрика создает много "продуктов" в программе, на то она и называется фабрика, а не один "продукт" как в вашем примере (у вас типы "продуктов" много, но сам "продукт" один) ? Я понимаю что это учебная прога, но почему то это никто не поясняет. Или я чего то не знаю. А так спасибо за курс, пожалуй это лучшее что я нашел в ютубе по паттернам.
В любом приложении мы почти всегда создаём много объектов. Причем, к созданию прибавляется некоторая бизнес-логика. Поэтому часто имеет смысл вынести функционал создания объектов в отдельный класс.
Потому что класс может быть сложным и его инициализация - тоже. И, вместо того, чтобы классе-клиенте писать простыню кода мы просто вызываем метод у класса-фабрики. Ну, и гибкость приложения, чтобы была возможность легко вносить изменения в программу.
А зачем нужно так много фабрик если их единственная цель создавать разработчиков? Их же вручную можно создавать таким же образом. Без кучи классов для фабрик. Получается этот шаблон для тех у кого много времени, чтобы плодить лишние сущности.
мне кажется или само по себе создание реализаций фабрики разработчиков немного бредовое и не имеет смысла и нужно было сделать одну фабрику для разработчиков и туда впихнуть метод из конца видео в котором выбирается какого разработчика выдать исходя из условия, а само по себе создание и инциализация объекта это по сути же паттерн билдера, так что тут как будто все в кучу намешали
Абсолютно некорректный пример. Вместо паттерна "фабричный метод" показан урезанный паттерн "абстрактная фабрика". В итоге имеется бесполезный слой фабрик, а фабрика является пустой оберткой над конструктором девелопера. И самый сок, началось все претензией к тому, что нужно вносить изменения в клиентский класс, закончилось созданием в клиентском классе целого метода под это дело, в итоге количество мест, куда нужно вносить изменения, только увеличилось. Как нужно было сделать: ДевелоперФабрик сделать классом, в нем реализовать метод криэйтДевелопер, который принимает строку и возвращает объект нудного девелопера. Итого минус изменения в клиентском классе, минус два ненужных класса, соблюдаются принципы единственной ответственности и простоты, пример становится понятным и, что самое главное, применяемым на практике.
минусую. Потому что как и в других видео ничего не объяснено. Почему я должен воротить такую не**ическую инфраструктуру только чтобы делегировать создание классов? Что такого сказано в видео чего я не могу прочитать в книге или просто увидев название этого шаблона?
Автор, вот лучше ответил бы на вопрос: почему я не могу возвращать из метода с if'ми сразу экземпляр класса тем более что метод называется createDeveloper а не createFactory? Зачем мне прослойка из структуры фабрик между клиентом и реализациями интерфейса? Вот на такие вопросы надо давать ответы в видео а не просто кратко пересказывать содержимое книги.
Если никто не понял чего мы пытаемся здесь добиться то максимально рекомендую данное видео ua-cam.com/video/rd6wxPzXQvo/v-deo.html&ab_channel=JPoint%2CJokerиJUGru
@@EugeneSuleimanov там все было Ок, на мой взгляд, до появления статического метода получения разработчика по специальности. Этот метод нарушает принцип open/close.
без объяснения зачем и в каких случаях нужен этот фабричный метод мне как новичку не понятно зачем надо создавать кучу классов и интерфейсов чтобы в итоге создать один объект и вызвать его метод 🙃
Не понимаю людей ,которые пишут про понятное объяснение. Что тут понятно? Для чего куча всего этого создается? Ничего не понятно. А статичный метод? Серьезно? А если на разработчиков всех языков программирования выводить,то какое же это полотно получится. Что за бред? И сколько будет доп класс с переопределенными методами,в которых будет выводиться строка под каждого. Это же с ума сойти можно. Я не разработчик,может сейчас фигню сморожу. Но не проще было бы сделать,что бы этот статичный метод принимал не строку с названием специальности а ОБЪЕКТ? Интерфейс ,блин. И в main вместо строки лямбду передавать. И не придется каждый раз при добавлении нового создавать доп классы, лепить доп условия.
Зачем так сложно ? Зачем столько фабрик ? Почему ответственность за создание нужного класса не инкапсулируется в фабрике, а реализована в статическом методе пользователем ? Разве это не нарушает основную идею паттерна ? Почему нельзя фабричный метод сделать с параметром ?
Даже если ты не прав, с таким ответом, свою неправоту уже не признаешь. Не ссылок, ни примеров. Разве в книге нет примера фабричного метода с параметром?
Странный комментарий. Раз 10 перечитал - так и не понял о чём он. Понял только вопрос. Отвечаю: В книге есть пример, но несколько более сложный и его трудно использовать без контекста всей книги.
На мой взгляд нет ответа на самый главный вопрос: ЧЕМ фабричный метод ЛУЧШЕ классического конструктора. Ответ прост на примере. Необходимо создать объект класса Студент. При определенных параметрах объект создать не возможно. Например, при возрасте менее 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."); }; } }
Не было пояснено, зачем вводить лишний уровень абстракции в виде фабрики. В рамках данного конкретного рассмотренного примера в клиентском коде вполне можно было в switch/case создавать конечные сущности в виде Developer минуя создание фабрики.
именно! Если вы поняли зачем это, то не могли бы вы объяснить?
@@_camper_5769 не зачем, прост. Притянуто за уши для демонстрации примера создания фабрики. В этом и печаль большинства блогеров-публицистов.
Рад тому, что увидел этот коммент, т.к. тоже не понимал, зачем этот уровень, если можно по слову сразу возвращаться нужного RandomLanguageDeveloper. Думал, что я не понимаю чего-то, но оказалось, что правильно подумал.
потому что switch/case нужно стараться избегать, вследствие одного из принципов solid, а точнее его второго принципа. при создании объекта, придется еще лезть под это switch и там добавлять условие, что не есть хорошо, на самом то деле.
Я согласен, что следует всегда минимизировать условную логику трансформируя такой код в полиморфизм иерархии наследования. Но в данном случае разве мы избавились от условной логики? Мы просто её переместили, а значит ровным счётом ничего не достигли.
Теперь при добавлении нового наследника Developer, программисту придётся изменять не один, а целых два зеркальных класса, и один статичный метод с вермишелью из if else. Просто потрясающий шаблон! Советую ещё через методов 5 с разными спецификациями это всё прогнать, чтобы изменять ещё их, если кому мало
Правильно, даешь супер-класс где все до кучи и авер 500 строк кода, вот так сразу все понятно будет
Спасибо, всё понятно. Когда идёт последовательное усовершенствование кода с нуля до заданного шаблона, то всё идеально воспринимается (чем сразу написать правильный, но сложный код) :)
да, куда лучше чем в обьясняли
Долго не мог понять, что за фабричный метод и зачем он нужен. На данном примере можно понять, что фабричный метод штука очень не сложная но в то же время полезная.
Спасибо Евгений.
Спасибо за отзыв!
Рад , что материал помог разобраться.
Спасибо за труд. Самые понятные примеры.
Спасибо за урок. Неделю учу этот паттер на англ и на русском,не понимала пока ваше видео не посмотрела!!!
Спасибо огромное за видео! Очень доходчиво объясняете, удивлена, что на Вашем канале мало подписчиков.
Спасибо за отзыв!
Самый понятный стиль объяснения. Вначале вступление, затем демонстрация сути решаемой паттерном проблемы, а затем её решение. Чётко, быстро и по делу. Спасибо!
спасибо тебе добрый человек ! и английский у тебя тоже хороший. А то других слушаешь, уши заворачиваются в трубочку
Спасибо большое за объяснение. Без практики довольно тяжело запоминать паттерны. Но Ваше объяснение даёт базовые понимания этого паттерна!
Спасибо за отзыв!
Ваще круть!
Очень полезно было, как на пальцах)
Если бы мог поставил 100 "пальцев вверх"
как ваши успехи в разработке спустя 6 лет?
@@АлександрЮтушуй спился
Ты красавчик. Здоровья тебе и твоим близким!
Превосходное объяснение фабричного метода. Просто лучшее из всех.
О, наконец-то разобрался с этим паттерном. Оказалось все легко) спасибо!
Спасибо автору за видео. Все такие умные в комментах, а вот видео дельного совершенного никто не записал, а жаль. Можно было бы столько вариантов посмотреть и оценить по достоинству данный шаблон
Спасибо за отзыв!
Круто! Всё очень четко и понятно! 👍
Прежде всего спасибо за ролик, суть кажется я уловил - вместо создания трёх классов с полезным кодом, мы городим ещё столько же классов прослоек и прослойки между прослойками - интерфейсы. И все это для того чтобы ленивые программисты излишне не утруждали себя если необходимо внести какие то изменения в основную логику работы программы.
Прежде всего для того, чтобы создание по-настоящему сложных классов с множеством необходимых данных создавались одной строкой кода , а не простыней кода )
@@EugeneSuleimanov желательно было это и упомянуть в видео)
Если я правильно понимаю, то еще смысл данного шаблона в том, что в аргументы методов можно добавлять экземпляр интерфейса, и тогда методу будет все равно какого в типа объект придет в момент выполнения программы.
Вроде как все понятно и просто, но осознать полезность этого подхода не получается. Было бы не плохо если бы кто-то объяснил именно этот момент
вот именно.
а вообще взялся учить по этому сайту. вроде очень даже хороший
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 кода.
Женя, огромный тебе тебе респект. Ты оказывается еще владеешь С++?! Это вызывает большой уважение. Этот язык сложнее Java. После того как я освою Java, я очень хочу освоить С++. Мне кажется очень круто то, что этот язык может управлять железом. Все топовые игры пишутся на С++
делегирование)) а так супер конечно! Хотелось бы еще несколько видосов для разъяснения ключевых различий между паттернами. Например прокси и декоратор. Спасибо за ваш труд.
Спасибо за отзыв :)
Хорошо, что есть комменты, а то из видео вообще не понятно, что даёт данный паттерн и зачем он существует. А вот почитаешь комменты - станет понятно, что просто пример в видео не просто урезанный, а кастрированный, не отображающий сути паттерна.
не createDeveloperBySpeciality, а createDeveloperFactoryBySpeciality
зачем нам создавать много фабрик, если можно создать одну с параметрами?
По поводу имени метода - вы правы, тут нужно будет исправить - название метода вводит в заблуждение.
А по поводу количества фабрик, важно понимать, что это обучающее видео, а не уровня production.
И цель - понимание того, что и как работает.
ясно, спасибо
что и как и так понятно. Ответь на вопрос ЗАЧЕМ?
Актуальный вопрос спустя 3 года, таки ЗАЧЕМ?
@@hexruin4569 на самом деле в каждой фабрике для наглядности тоже должны быть ветвления. Например тестировщика, разработчика, техлида. Реализовать это вне фабрики будет проблематично, поэтому удобно будет вынести это так как указал автор. С одним лишь методом в фабрике это действительно бессмысленно. В данном случае достаточно интерфейса девелопера
Евгений Здравствуйте , как думаете сейчас смотря на ваш код его же можно было усовершенствовать чтобы мы ужже не зависели от статического метода при добавлении нового класса?
Factory и Factory Method это разные шаблоны
Abstract Factory и Factory - вот что есть одно и то же.
Еще Factory Method может называться Virtual Constructor
в каких источниках описан шаблон с названием Factory?
5 лет прошло, 21 год на дворе, но лучше объяснения на ютубе я не нашёл
И это прискорбно
Спасибо! Я только запутался какая разница между Фабричным методом и Абстрактной фабрикой.
цель фабрик - создание ОБЪЕКТОВ и инкапсуляция создания объекта вне клиентского кода, тем самым мы освобождаем клиента от больших изменений кода (как показано на примере метода main), а все изменения инкапсулируем в объекте "фабрика", тем самым не нарушаем принцип открытости к расширению программы и закрытости к ее изменению уже существующего кода. Это фишка, которая предоставляет нам ООП.
Используя Фабричный метод создаётся ОБЪЕКТ классами (JavaDeveloperFactory и PHPdeveloper factory), реализующими абстракцию (DeveloperFactory) для создания объекта интерфейса (Developer). Т.е. используется наследование для реализации этого метода.
Абстрактная фабрика создаёт СЕМЕЙСТВО ОБЪЕКТОВ. Абстрактная фабрика используется с помощью композиции, т.е. создав в клиенте экземпляр абстрактной фабрики, ты задаешь создание всех объектов сразу, которые представляют собой одно семейство объектов (ингредиенты к блюду, виды цветов в одном букете, и тд). И используешь объекты этого семейства.
Читай HeadfirstJava паттерны. Фабрика
Абстрактная фабрика, состоит из фабричных методов
Честно, лучшего объяснения этого паттерна не видел)
Не вижу никакого преимущества, почему в том if-else блоке просто не возвращать конкретных Developer-ов, а не фабрики?
Например создание девелопера может быть не таким простым. А девелопер фактори инкапсулирует конкретную реализацию девелопера
@@JohnWickMovie а каким это не простым ? есть ли примеры ? если весь процесс создания инкапуслирован внутри конструктора класса "девелопер", и фабрика при этом ничего не вызывает кроме как конструктор этого класса.
upd: это может быть вызов разных конструкторов, в зависимости от ситуации? И мы как бы скрываем из основного метода MAIN большую часть портянки блоков IF / SWITCH в этих самых фабриках, и таким образом получаем более красивое архитектурно решение?
@@kolob204 Здесь просто демонстрируется пример абстракции. В жизни случают сложные ситуации, например тебе нужно отслеживать создание объектов или аллоцировать его в собственном участке памяти, фабрики это позволят легко делать. Да и весь COM от Microsoft построен подобным образом, взгляни на какой нибудь DirectX на досуге, в качестве примера фабрики
Нормально, но я в последнее время отказался от флагов в виде стрингов как в примере: java, c++, php, использую enum-ы. А так тема понятна, спасибо за видео.
Тоже в голову мысль пришла ограничить варианты через перечисления.
@@Maksym_Palii да, это норм практика, так можно не переживать, что кто-то, передаст что-то не то )))
Все советуют использовать только enum , в строке легко ошибиться , нежели в перечисление .
Можно ожидать Developer как параметр и передавать нужный класс и делать instanceof для нужной фабрики
здесь стринги как учебный пример, полагаю
для упрощения восприятия
Крутой талант объяснять !
Спасибо за отзыв!
Все ок, понятно и доступно. Но лучше у фабрике сделать какой-то метод в который передаем "specialty" и при это нам вернут не фабрику, а уже девелопера.. Так же лучше использовать int значение или Enum вместо String для (specialty), ну и в самом методе createFactory проситься switch вместо ифов (но это уже вкусовщина). Но так все понятно.
Спасибо, отличное объяснение
может быть так нужно: ветвление делать в единственной фабрике и там же создавать разработчиков?
Евгений, отличные видео, спасибо. Но есть вопрос.
Так и не понял, какой выигрыш нам дает использование этого паттерна по сравнению с классическим полиформизмом (через интерфейс)? Все равно нужно менять тип вызываемого класса, причем в клиенте, так не все ли равно что менять, тип класса Developer или тип вызываемой фабрики? Я вижу только увеличение объема кода, кроме классов нужно создавать столько же фабричных методов...
Спасибо
Полиморфизм даёт нам позможность переопределять поведение класса, а фабрика отвечает за создание объектов.
А код в клиентском классе является лишь примером использования.
То, что код - это лишь пример, я понимаю. Не могу сообразить, чем создание объектов в фабрике предпочтительнее непосредственного создания объектов. И так, и так, для добавления новых классов или изменения типов объектов надо править код, вся разница, что без паттерна мы правим код в клиенте, а с паттерном - в классе фабрики. Что мы этим выигрываем? Или есть еще что-то, что я не понял?
Tariel Regev Вероятнее всего, вы не сталкивались с по-настоящему сложными системами, в которых мы изначально не имеем всех данных для создания объекта, а получаем их из разных источников. Ведь, если нам необходима ссылка на какой-то объект SomeObject, то, намного разумнее поместить эту ссылку в фабрику а не в клиентский код.
Осталось ощущение что метод createDeveloperBySpecialy(String string) может с тем же успехом (работая на if else) возвращать готового девелопера, а не фабрику. Программа при этом будет работать так же, а мы избавимся от лишних 3-х классов и 1-го интерфейса.
Нет, это плохая идея. Для примитивного класса Developer может и годится (и то, так себе идея), для чего-то серьёзного - нет.
Паттерн, который только усложняет. Если вы хотите добавить девелопера - пишете класс девелопера, и создаёте через new - Все. А если у вас есть фактори - вам надо добавить нового деведопера, новую фактори, и потом ещё добавить новый if. Ёлки палки - где тут преимущество. Этот паттерн в таком *голом* виде не делает проще. Если вы хотите показать основы - то лучше их показыать не на таких синтетических примерах. После такого только ещё больше вопросов. Если вы думаете, что чем меньше деталей вы говорите, тем проще слушателям - это не так. Детали очень важны и очень интересны
Вероятнее всего вы не смотрели введение и не обратили внимание на цель этого курса. Но, в чем-то вы, возможно, правы.
У меня только один вопрос. В каком случае нам может понадобиться создавать объекты с учетом того что мы работаем с ioc контейнером?
Ты гений. Спасибо !
Что это за фишка с диаграммами? В андроид студии есть такая?
Спасибо Вам) Вы делаете очень полезные видео) Хотел спросить как сделать в IDE как у Вас что бы показывало UML diagrams?
День добрый, Дмитрий.
Спасибо за отзыв.
Это стандартный плагин, который входит с Ultimate Edition. В Community его, к сожалению, нет.
@@EugeneSuleimanov Евгений, а есть ли достойная замена для Community Edition? По вашему мнению?
@@Dmitry2385 ultimate edition :) По моему мнению - Jet Brains делает лучшие IDE. А для Java - лучше IDEA точно нет.
@@EugeneSuleimanov Евгений, я имел ввиду uml plugin для idea Community edition.
дякую велике
Дякую за відгук
createDeveloperBySpecialty() ...можно было сделать не статичным? Если сделать не интерфейс, а абстрактный класс Фабрику? Или нам нужно будет предусмотреть возможность расширения фабрик?
Спасибо. Хорошо объясняете!
спасибо , а можно эти if заменить на полиморфизм ?
Можно, но это будет не самым простым к пониманию решением. Можно создать ассоциативный массив String->Factory, и при инициализации его заполнять всеми возможными билдерами. Доступ к нужному в таком случае произойдёт просто по индексу. Да и заполнение такой коллекции можно сделать через рефлексию или Dependency Injection, но это уже совсем энтерпрайзно. Но это всё уже не к шаблону Factory, а скорее к Strategy.
Здравствуйте. Помогите мне разобраться с диаграммой. Никак не могу установить чтобы также как у вас было отображение при нажатии правой клавиши мыши.
Доброе утро, Михаил.
Это стандартный плагин, который входит только в ULTIMATE версию IDEA. По-другому получить его, вряд ли, получится.
Большое спасибо!
Мудрёный вариант реализации, конечно, но видео отличное, спасибо
Разве клиенту надо видеть этот статический метод createDeveloperBySpecialty ? В чем тогда смысл фабрики если клиенту все равно придется апдейтить код каждый раз когда добавится новый тип разработчика. Не надо ли его спрятать в базовый класс DeveloperFactory ?
Вот чаще у меня возникает случай когда те два класса существуют и существует этот интерфейс. И нужно чтобы те классы оставались чистыми, а по интерфейсу можно было взаимодействовать с ними двумя. Тут получается, что нужен класс (или несколько), которые будут реализовать логику тех двух классов через этот интерфейс.
Что это за классы будут? Какие паттерны они должны реализовать?
Такое может возникнуть, когда два класса используют два разных источника данных (Модели к разным таблицам, например), но у классов будет одна группа действий. Под один интерфейс их не подвести за счет того, что они должны оставаться чистыми (например, не соответствуют зоне ответственности или это библиотека стороннего разработчика).
Это не лайфхак для копипаста, почитайте тз. Все круто , спасибо мужик!❤
Спасибо за отзыв!
В конце код стал более громоздким чем в начале... зачем..?
короче вместо одного класса придется создавать 5, круто че
тут очень простой пример, а в реальности когда много запутанного кода, создание фабрик оправдано.
Я то же не особо понял плюсов, а что мешает так же создать метод который вернет нужный класс, если мы на каждый класс делаем свою фабрику?
+++ вообще непонятно вместо пары строк такая лапша
@@vsezanyato ну автор, на мой взгяд, взял не самый лучший пример. На самом деле может быть и одна фабрика (например, в конкретном примере). Но в сложных проектах дела обстоят по другому и создание фабрики фабрик оправдано. Например, есть Enum с условным DeveloperTier (Junior, Middle, Senior), и уже исходя из него и будет создаваться Developer.
Factory factory = createDeveloperFactory("java");
Developer developer = factory.createDeveloper(DeveloperTier.SENIOR)
developer.writeCode();
@@TheSporpion, ничего не мешает, автор создал очень плохую реализацию, с совершенно лишним слоем фабрик, еще и в клиентский класс запихнул функцию создания фабрик, которую придется менять, хотя изначально именно к изменениям в клиентском классе была претензия.
Суть как я понял в том, что если сравнить график
функции(количество классов, коэффициент показывающий на сколько код упрощается если использовать фабрику)
и
функции(количество классов, коэффициент показывающий на сколько код упрощается если НЕ использовать фабрику)
То увидим что - количество кода растет в второй функции.
Хотя на первый взгляд да, никаким упрощением и не пахнет
Зачем создавать интрефейс на каждого разраба?? Можно ведь просто в DeveloperFactory делать логику через if и возвращать конкретный объект.
Мне кажется здесь была рассмотрена абстрактная фабрика, а не фабричный метод.
Не хватает плюсов и минусов, а их много
вот это намудрил, нужно несколько раз пересмотреть, то мыли запутались под конец, а так норм)
Автор описал Абстрактную фабрику, подходящую для создания групп элементов, а не фабричный метод. Фабричный метод - это когда у тебя продукты/объекты реализуют один интерфейс, и дальше в клиентском коде ты создаёшь метод с конструкцией switch/case, для определения того, какой конкретный объект тебе нужен, фабрика в этом случае не требуется.
Смысл происходяшего был бы понятен, если бы он использовал фабрику для создания ГРУПП ОБЪЕКТОВ ОДНОГО СЕМЕЙСТВА, а не просто одного объекта.
К примеру, нужно создавать не одного Developer, а ещё и SeniorDeveloper, TeamLeadDeveloper и прочее. Тогда есть смысл делегировать их создание методам Абстрактной Фабрики, а фабрику определять через свитч-кейс, и эта фабрика могла бы уже производить ОБЪЕКТЫ ОДНОГО СЕМЕЙСТВА, а не тупо один объект.
Но в любом случае спасибо, с каждым таким видео узнаю что-то новое!
Как по мне, все же лучше сделать одну фабрику с одним методом,где расположить свитч, и в клиентском классе уже обращаться к нему. Конечно, зависит от ситуации, но так куда читаемее со моему мнению.
а можно строки для фабрики java и тд загнать в enum?
Добрый день, Михали.
Да, конечно, можно.
Я так и делаю, по сути в примере это обычный флаг, в таком случае использую enam-ы.
А можно создать файл с проперти и писать нужного разраба вместо метода ? Или это уже не фабрика?
Очень круто объясняешь, спасибо. И слава коду, что на ютубе можно поставить скорость воспроизведения 0.75 для заторможенных вроде меня)
Я вот чего не могу понять, а почему в данном примере нужна именно фабрика? Почему нельзя просто вот так сделать:
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");
}
А зачем вообще фабрики, можно же в методе getDeveloperBySpeciality(String tag){
Developer developer;
switch(tag):
case "java":
developer = new AnyDeveloper();}
return developer;}
Зачем Фабрики??? Объясните пожалуйста, эта тема мне очень интересна. Я начинающий Android Developer.
Потому что объекты могут быть крайне сложными и выносить инициализация в клиентский код не практично
Видео про фабрику, как реализацию низкосвязного кода, в итоге свести к жесткой зависимости от значения стринга? Читающий обучалку не понимает, о чем читает.
Да спасибо, очень интересно! )
Думаю что паттерн фактори используется для вносение доп функциональность в программи. К примеру из java hed first привожу пример. Есть пицарея. Программа создана для одного пицарея, а если пицарея начинает расшираться то как постпуить так что бы вносить доп изменение ? Думаю в этом поможет фабричныий метод что бы вносит доп франшизы к нашему пицарею и тд. Pizzastore extends NystylePizza store, ChicagoPizzaStore, Russian Pizza Store. So on
диаграммы выводятся с помощью какого-то плагина?
Добрый вечер, Евгений. Это стандартный плагин в Intellij IDEA Ultimate edition. Т.е. в community такого плагина нет
@@EugeneSuleimanov спасибо
Спасибо за видео. Но я думал ты в конце вытащишь зависимость от конкретной реализации программиста из клиенсткого кода. Можно было сделать хоть в самой фабрике или например в конфиг файл.
Зачем? Как вы создадите экземпляр класса из ничего? цель фабрик в отделении создании объектов от неизменяемой части кода, а не в отделении клиентского кода от созданий объектов в принципе!
все правильно вы говорите, странно что в клиенте сделано
придется такую логику теперь писать в каждом клиенте
Я так понимаю данные шаблон актуально использовать если мы создаем много "продуктов" в программе, т.е. фабрика создает много "продуктов" в программе, на то она и называется фабрика, а не один
"продукт" как в вашем примере (у вас типы "продуктов" много, но сам "продукт" один) ? Я понимаю что это учебная прога, но почему то это никто не поясняет. Или я чего то не знаю.
А так спасибо за курс, пожалуй это лучшее что я нашел в ютубе по паттернам.
В любом приложении мы почти всегда создаём много объектов.
Причем, к созданию прибавляется некоторая бизнес-логика.
Поэтому часто имеет смысл вынести функционал создания объектов в отдельный класс.
Я понял что вы сделали, но не понял зачем это нужно…
Красиво пояснил, молодец. Я понял.
Java developer IS WRITING code... (present continuous)
зачем столько классов плодить ?
Потому что класс может быть сложным и его инициализация - тоже. И, вместо того, чтобы классе-клиенте писать простыню кода мы просто вызываем метод у класса-фабрики. Ну, и гибкость приложения, чтобы была возможность легко вносить изменения в программу.
@@EugeneSuleimanov принцип как MVC
Добавим дерево из ифелсов и наш код станет более гибким, отвечаю!
Чтобы это всё понять, нужны знания как минимум Java core
Безусловно
не смог промолчать то как вы печатайте это как бутта с кулака ударяете по кнопкам)
Я старался :)
В момент записи этого цикла видео не учитывал этот момент, стараюсь не повторять подобного в новых видео. Спасибо критику!
А зачем нужно так много фабрик если их единственная цель создавать разработчиков? Их же вручную можно создавать таким же образом. Без кучи классов для фабрик.
Получается этот шаблон для тех у кого много времени, чтобы плодить лишние сущности.
мне кажется или само по себе создание реализаций фабрики разработчиков немного бредовое и не имеет смысла и нужно было сделать одну фабрику для разработчиков и туда впихнуть метод из конца видео в котором выбирается какого разработчика выдать исходя из условия, а само по себе создание и инциализация объекта это по сути же паттерн билдера, так что тут как будто все в кучу намешали
ИМХО. Надо бы литерал и строковую переменную поменять местами, иначе получим NPE " if ("java".equalsIgnoreCase(speciality)) "
Спасибо!
Пожалуйста :)
Абсолютно некорректный пример. Вместо паттерна "фабричный метод" показан урезанный паттерн "абстрактная фабрика".
В итоге имеется бесполезный слой фабрик, а фабрика является пустой оберткой над конструктором девелопера.
И самый сок, началось все претензией к тому, что нужно вносить изменения в клиентский класс, закончилось созданием в клиентском классе целого метода под это дело, в итоге количество мест, куда нужно вносить изменения, только увеличилось.
Как нужно было сделать: ДевелоперФабрик сделать классом, в нем реализовать метод криэйтДевелопер, который принимает строку и возвращает объект нудного девелопера. Итого минус изменения в клиентском классе, минус два ненужных класса, соблюдаются принципы единственной ответственности и простоты, пример становится понятным и, что самое главное, применяемым на практике.
минусую. Потому что как и в других видео ничего не объяснено. Почему я должен воротить такую не**ическую инфраструктуру только чтобы делегировать создание классов? Что такого сказано в видео чего я не могу прочитать в книге или просто увидев название этого шаблона?
Автор, вот лучше ответил бы на вопрос: почему я не могу возвращать из метода с if'ми сразу экземпляр класса тем более что метод называется createDeveloper а не createFactory? Зачем мне прослойка из структуры фабрик между клиентом и реализациями интерфейса? Вот на такие вопросы надо давать ответы в видео а не просто кратко пересказывать содержимое книги.
Афобий II просмотр введения в цикл даст ответы на все вопросы
толково)
Если никто не понял чего мы пытаемся здесь добиться то максимально рекомендую данное видео
ua-cam.com/video/rd6wxPzXQvo/v-deo.html&ab_channel=JPoint%2CJokerиJUGru
Такое нагромождение из if else не есть гуд. Это нарушение принципа open/close.
Спасибо за комментарий!
Старался делать в точности по материалам GoF, если подскажите, где было отклонение от их примеров - буду признателен.
@@EugeneSuleimanov там все было Ок, на мой взгляд, до появления статического метода получения разработчика по специальности. Этот метод нарушает принцип open/close.
без объяснения зачем и в каких случаях нужен этот фабричный метод мне как новичку не понятно зачем надо создавать кучу классов и интерфейсов чтобы в итоге создать один объект и вызвать его метод 🙃
Без статичного метода в клиенте вообще бесполезная штука. Что так, что так надо менять ручками java /cpp.
krosava!
Не понимаю людей ,которые пишут про понятное объяснение. Что тут понятно? Для чего куча всего этого создается? Ничего не понятно. А статичный метод? Серьезно? А если на разработчиков всех языков программирования выводить,то какое же это полотно получится. Что за бред? И сколько будет доп класс с переопределенными методами,в которых будет выводиться строка под каждого. Это же с ума сойти можно. Я не разработчик,может сейчас фигню сморожу. Но не проще было бы сделать,что бы этот статичный метод принимал не строку с названием специальности а ОБЪЕКТ? Интерфейс ,блин. И в main вместо строки лямбду передавать. И не придется каждый раз при добавлении нового создавать доп классы, лепить доп условия.
тут и Фабричный Метод из гоф, и Статик Фактори Метод из блоха )
Ты путаешь simple fabric, template method. Плюс зачем тебе лишний слой конкретных фабрик. Учи базу короч
@@mirlaniusUMK возможно, если можете скинуть ссылки на источники с обоснованием, буду признателен. Спасибо за комментарий.
Зачем так сложно ? Зачем столько фабрик ? Почему ответственность за создание нужного класса не инкапсулируется в фабрике, а реализована в статическом методе пользователем ? Разве это не нарушает основную идею паттерна ? Почему нельзя фабричный метод сделать с параметром ?
Это реализация шаблона по GoF.
Если вы не согласны с их подходом к проектированию...
Без комментариев.
Даже если ты не прав, с таким ответом, свою неправоту уже не признаешь. Не ссылок, ни примеров. Разве в книге нет примера фабричного метода с параметром?
Странный комментарий.
Раз 10 перечитал - так и не понял о чём он.
Понял только вопрос. Отвечаю:
В книге есть пример, но несколько более сложный и его трудно использовать без контекста всей книги.
Я ничего утверждаю, но возможно своим упрощением вы разрушали основную идею паттерна. :))
Какое упрощение?
Паттерн сделан стандартно - а клиентский класс всего лишь демонстрирует его работу.
даже я понял
как-то не очень сплошные ифы смотрятся, лучше уже 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.");
};
}
}