Тоже заметил на 3:23 про "наследование" вмето "реализация". Здесь понятно, что класс ConcreteCreator реализует интерфейс Creator и т.д. там, где пунктирная стрелка . Отношения между классами: - при наследовании классов и реализации интерфейсов - IS-A (является), но есть уточнение, что в случае реализации интефрейсов - это скорее IS..., т.к. интерфейсы позволяют описать т.н. протокол, где говориться "Что", а не "Как". - при ассоциации, агрегации и композиции - HAS-A (является частью) Если я где-то не точен, ответьте мне - интересно. - - - наследование == extends, inheritance отношение == relationships реализует, расширяет == implements контракт, протокол == contract, protocol www.examclouds.com/ru/java/java-core-russian/class-relations stackoverflow.com/questions/35962451/what-kind-of-relationship-does-an-interface-have-with-it-implementing-class
Очень не плохое обьяснение. Но на мой взгляд главная изюминка в применении этого всего заключается как раз в работе с интерфейсами. А именно, мы можем просить фабрику (разные линии конвееров) создать нам товар без использования ифов и кейсов в коде. Другими словами мы уходим от гигантской вереницы if ... else в коде. В этом вся соль. Об этом как то не сказано ничего.
Есть вопрос. Как в данном случае избавится от гирлянды из if в getMakerByName ? Допустим у нас сотни часов. Гирлянда в сотни if не очень красивая как по мне. Что можно сделать?
В каждой фабрике создать статическое свойство с неким уникальным названием, описывающим сущность. Создать массив или список всех классов (можно так же автоматизировать), а потом через проход по всему массиву (итерация): сравнивать свойство класса, с уникальным названием, со строкой в методе - при совпадении создавать соответствующую фабрику.
Непанятна. Все что делает "Завод производитель" это производит часы (в данном примере) разного типа. Смысл менять тип "завода производителя", если можно с теми же усилиями заменить тип часов, а не заменять тип завода. ?????????????
зачем ради неизменности трёх строк кода столько обслуживающего кода? почему бы по передаваемому имени часов не получать именно часы, а не их производителя? А какая разница? Любой большой проект - есть набор маленьких, взаимосвязанных между собой. По-моему скромному мнению, получение конкретного продукта по его уникальному имени - это более прозрачный и понятный программисту любого уровня способ реализации шаблона "фабричный метод".
Так автор топика выше и говорит: ради трёх неизменных строчек кода-клиента гляньте сколько сверху нахуевертили! А теперь представьте огромный проект, там же геометрическая прогрессия будет лишней работы! Что по сути сделано: у двух схожих по поведению классов часов (общий предок интерфейс watch) вынесены конструкторы в отдельный класс - Watchmaker, конструкторы которого опять же вынесены в отдельный метод и реализуются по String наименованию первоначальных классов часов. Т.е. ещё раз: была абстракция интерфейс - watch на ней были реализованы реальные часы (digital и rome), но было мало просто создать один класс порождающий объекты от наименования часов, нужно было разделить часы на две группы, сверху налепить ещё два класса с выведенными в них конструкторами часов, после чего конструкторы уже этих классов вынести в ещё один отдельный метод, который, внимание... ПРИНИМАЕТ СТРОКОВУЮ ПЕРЕМЕННУЮ, ЧТОБЫ СОЗДАТЬ ТЕ САМЫЕ ЛИБО DIGITAL, ЛИБО ROME WATCH!!! Как говорили древние китайцы нахуа? Лично мне это напоминает шизофазию, только в виде кода.
Эту СТРОКОВУЮ ПЕРЕМЕННУЮ можно поместить в конфигурационный файл, который можно подменять на лету, не останавливая программу. Если же создавать классы самому, придеться останавливать программу ( а это может быть веб сервис какой-нибудь на яндексе) в коде менять, проходить все процедуры тестирования / интеграции / деплоя
"почему бы по передаваемому имени часов не получать именно часы, а не их производителя" - да, в реальности все пропускают эту ступень с производитетелем, и сразу создают продукты в зависимости от условий
он неправильно клиентский код реализовал. там должен быть метод который принимает интерфейс WatchMaker, а уже в рантайме туда приходит конкретная реализация этого интерфейса и создает конкретные часы. а то что он в мейне написал можно было и на конструкторах сделать
я так и не понял смысл этого паттерна. ruclips.net/video/HZ4ciLNWX4E/видео.htmlm27s в данном случае мы можем просто менять Watch watch = new DigitalWatch(); на Watch watch = new RomeWatch(); и в таком случае код ниже тоже изменять не потребуется
я так думаю имеет смысл создавать дополнительный класс maker, если имеются какие либо сложные составные объекты и существует сложность создания таких объектов ...
Вы правы. Именно для этого фабрика и нужна. Автор упустил этот важный момент, к сожалению. В данном примере класс-создатель и класс-продукт просто параллельные классы. И класс-создатель только и делает, что создает экземпляр класса-продукта. Пример был бы более полноценный, если бы класс-создатель помимо создания экземпляра класса-продукта делал бы еще какую либо работу, что, в принципе, и предполагается на практике.
Спасибо большое за ваше пояснение, теперь все по полочкам! Да кстати, почти во всех источниках от официальных изданий до личных блогов, везде один и тот же формальный пример реализации и не слова про оптимизацию дополнительных манипуляций при инстанцировании сложный классов. Еще раз благодарю!
@@bondarden что значит "класс-продукта делал бы ещё какую либо работу"? Не совсем понял вас. А как же чистый код? Не рекомендуется нагружать методы чем то ещё что не предполагалось в названии метода. Например вы создаете метод createDigitalWatch в котором помимо интанциирования нужного экземпляра часов будете создавать каких то юзеров для этих часов или писать в базу что то или что то другое. Тем самым введёте в заблуждение разработчиков.
WatchMaker -> Factory, getMakerByName -> factoryMethod, конкретных мейкеров - в топку, производить сразу вместо конкретных мейкеров. Немного не по книжке, но в жизни юзают так все. PS: ржу как аффтар использует англ язык ))) "а производитель переведем как мейкер )))"
?: Элементная база (железо) разных часов - разная => конвейеры должны быть разными и код, управляющий конвейерами (клиентский код) - тоже разный. И что крестьянину делать%( ?
Спасибо за урок! Неправильно говорить, что класс наследует интерфейс, он реализует его. После слов класс наследует интерфейс любое собеседование провалено
Наследование и реализация - общепринятые понятия. Можешь сказать расширяет. Но наследовать интерфейс нельзя. Наследование и имплементация (реализация) - разные понятия.
Эти лекции - высший пилотаж и непередаваемое удовольствие. Огромное человеческое спасибо, талантливому лектору.
Ваня , спасибо большое что учите нас ! )
+FryBrix chanel на здоровье!))
его же вроде Володя зовут
Много искал адекватное обьяснение фабричного метода. Большое спасибо.
Как по мне, так наиболее понятные уроки по шаблонам.Респект!!!
Пожалуй одно из лучших объяснений этого шаблона!!!
Огромное спасибо за урок! Наконец-то до меня дошло. Самый лучший и понятный пример.
Большое спасибо за подробный видео урок данного шаблона! Только благодаря Вам стало более-менее понятно что к чему!)
Тоже заметил на 3:23 про "наследование" вмето "реализация".
Здесь понятно, что класс ConcreteCreator
реализует интерфейс Creator и т.д. там, где пунктирная стрелка
.
Отношения между классами:
- при наследовании классов и реализации интерфейсов - IS-A (является), но есть уточнение, что в случае реализации интефрейсов - это скорее IS..., т.к. интерфейсы позволяют описать т.н. протокол, где говориться "Что", а не "Как".
- при ассоциации, агрегации и композиции - HAS-A (является частью)
Если я где-то не точен, ответьте мне - интересно.
- - -
наследование == extends, inheritance
отношение == relationships
реализует, расширяет == implements
контракт, протокол == contract, protocol
www.examclouds.com/ru/java/java-core-russian/class-relations
stackoverflow.com/questions/35962451/what-kind-of-relationship-does-an-interface-have-with-it-implementing-class
Хоспаде, как же доступно! Спасибо за труд!
это видео дало мне понимание в чем выгода от использования данного паттерна
2:26 "Класс! Просто класс!" -- сук, до слёз)))
Супер-удачно пример подобран с часами, спасибо!
Очень не плохое обьяснение. Но на мой взгляд главная изюминка в применении этого всего заключается как раз в работе с интерфейсами. А именно, мы можем просить фабрику (разные линии конвееров) создать нам товар без использования ифов и кейсов в коде. Другими словами мы уходим от гигантской вереницы if ... else в коде. В этом вся соль. Об этом как то не сказано ничего.
Для ухода от if else есть strategy, state
Есть вопрос. Как в данном случае избавится от гирлянды из if в getMakerByName ? Допустим у нас сотни часов. Гирлянда в сотни if не очень красивая как по мне. Что можно сделать?
В каждой фабрике создать статическое свойство с неким уникальным названием, описывающим сущность. Создать массив или список всех классов (можно так же автоматизировать), а потом через проход по всему массиву (итерация): сравнивать свойство класса, с уникальным названием, со строкой в методе - при совпадении создавать соответствующую фабрику.
Создав это свойство, надо при загрузке класса перегрузить все фабрики в мапу и получать эту фабрику из готовой мапы, чтоб не бегать по всему массиву
Непанятна. Все что делает "Завод производитель" это производит часы (в данном примере) разного типа. Смысл менять тип "завода производителя", если можно с теми же усилиями заменить тип часов, а не заменять тип завода. ?????????????
Kak hazivaetsa kniga iz video?
Очень хорошее объяснение! Спасибо
Браво!!!!
зачем ради неизменности трёх строк кода столько обслуживающего кода? почему бы по передаваемому имени часов не получать именно часы, а не их производителя?
А какая разница? Любой большой проект - есть набор маленьких, взаимосвязанных между собой. По-моему скромному мнению, получение конкретного продукта по его уникальному имени - это более прозрачный и понятный программисту любого уровня способ реализации шаблона "фабричный метод".
это в маленьком примере три строки кода. а теперь представь большой проект, где будет на несколько тысяч строк
Так автор топика выше и говорит: ради трёх неизменных строчек кода-клиента гляньте сколько сверху нахуевертили! А теперь представьте огромный проект, там же геометрическая прогрессия будет лишней работы!
Что по сути сделано: у двух схожих по поведению классов часов (общий предок интерфейс watch) вынесены конструкторы в отдельный класс - Watchmaker, конструкторы которого опять же вынесены в отдельный метод и реализуются по String наименованию первоначальных классов часов.
Т.е. ещё раз: была абстракция интерфейс - watch на ней были реализованы реальные часы (digital и rome), но было мало просто создать один класс порождающий объекты от наименования часов, нужно было разделить часы на две группы, сверху налепить ещё два класса с выведенными в них конструкторами часов, после чего конструкторы уже этих классов вынести в ещё один отдельный метод, который, внимание... ПРИНИМАЕТ СТРОКОВУЮ ПЕРЕМЕННУЮ, ЧТОБЫ СОЗДАТЬ ТЕ САМЫЕ ЛИБО DIGITAL, ЛИБО ROME WATCH!!!
Как говорили древние китайцы нахуа?
Лично мне это напоминает шизофазию, только в виде кода.
Эту СТРОКОВУЮ ПЕРЕМЕННУЮ можно поместить в конфигурационный файл, который можно подменять на лету, не останавливая программу. Если же создавать классы самому, придеться останавливать программу ( а это может быть веб сервис какой-нибудь на яндексе) в коде менять, проходить все процедуры тестирования / интеграции / деплоя
"почему бы по передаваемому имени часов не получать именно часы, а не их производителя" - да, в реальности все пропускают эту ступень с производитетелем, и сразу создают продукты в зависимости от условий
У Гранда написано, что курсивом выделяются абстракные классы. А интерфейсы -- просто стереотипом "interface".
он неправильно клиентский код реализовал. там должен быть метод который принимает интерфейс WatchMaker, а уже в рантайме туда приходит конкретная реализация этого интерфейса и создает конкретные часы. а то что он в мейне написал можно было и на конструкторах сделать
Спасибо за урок!
Спасибо за труд
я так и не понял смысл этого паттерна.
ruclips.net/video/HZ4ciLNWX4E/видео.htmlm27s
в данном случае мы можем просто менять
Watch watch = new DigitalWatch();
на
Watch watch = new RomeWatch();
и в таком случае код ниже тоже изменять не потребуется
какая разница подменять экземпляр maker либо экземпляр watch. результат одинаков
я так думаю имеет смысл создавать дополнительный класс maker, если имеются какие либо сложные составные объекты и существует сложность создания таких объектов ...
Вы правы. Именно для этого фабрика и нужна. Автор упустил этот важный момент, к сожалению. В данном примере класс-создатель и класс-продукт просто параллельные классы. И класс-создатель только и делает, что создает экземпляр класса-продукта. Пример был бы более полноценный, если бы класс-создатель помимо создания экземпляра класса-продукта делал бы еще какую либо работу, что, в принципе, и предполагается на практике.
Спасибо большое за ваше пояснение, теперь все по полочкам! Да кстати, почти во всех источниках от официальных изданий до личных блогов, везде один и тот же формальный пример реализации и не слова про оптимизацию дополнительных манипуляций при инстанцировании сложный классов. Еще раз благодарю!
@@bondarden что значит "класс-продукта делал бы ещё какую либо работу"? Не совсем понял вас. А как же чистый код? Не рекомендуется нагружать методы чем то ещё что не предполагалось в названии метода. Например вы создаете метод createDigitalWatch в котором помимо интанциирования нужного экземпляра часов будете создавать каких то юзеров для этих часов или писать в базу что то или что то другое. Тем самым введёте в заблуждение разработчиков.
Просто и Понятно, спасибо большое!!!!
Отличный урок!
Фабричный метод -это статический метод который возвращает экземпляр классса
И от меня спасибо.
Отличное видео
Спасибо!
concrete это бетон)
отличный урок
Затянуто, непонятно, без подготовки
Concrete - переводится как "бетон", а не конкретный
то что надо
+Nekit os спасибо, следующий будет Абстрактная фабрика
WatchMaker -> Factory, getMakerByName -> factoryMethod, конкретных мейкеров - в топку, производить сразу вместо конкретных мейкеров. Немного не по книжке, но в жизни юзают так все.
PS: ржу как аффтар использует англ язык ))) "а производитель переведем как мейкер )))"
?:
Элементная база (железо) разных часов - разная => конвейеры должны быть разными и код, управляющий конвейерами (клиентский код) - тоже разный. И что крестьянину делать%( ?
Приземлённо-железно посмотрел... Интерфейс-то одинаков...
Спасибо за урок! Неправильно говорить, что класс наследует интерфейс, он реализует его. После слов класс наследует интерфейс любое собеседование провалено
Наследует вообщем то тоже не правильно говорить, более правильно говорить расширяет.
Наследование и реализация - общепринятые понятия. Можешь сказать расширяет. Но наследовать интерфейс нельзя. Наследование и имплементация (реализация) - разные понятия.
Можно наследовать интерфейс, другим интерфейсом.
thx
нервируют кривые пальцы и опечатки
Спасибо за урок, но есть замечание. Когда класс реализует интерфейс - это всё же не "наследование".
Спасибо!!