Как стать автором
Обновить
26
13
Константин @Volokhovskii

Пользователь

Отправить сообщение

Ну, я этим буквоедством занялся шутки ради. Меня вполне устраивает определение, вычитанное мною ещё в университетском курсе по программированию. В целом, оно же продублировано в википедии если такой источник данных, конечно, устроит.

Какой-то спор тут разводить бесцельно, ибо использование термина я пояснил.

Ну а вы можете сколько угодно придумывать контекст разговора, будто обобщённого программирования не существует. К слову, в статье помимо Java есть и C#, давайте посмотрим определение из его документации:

A constructor is a method whose name is the same as the name of its type

Если уж докопались до определения, то по вашей ссылке его вообще нет, она ведёт на спецификацию по рефлексии :)

в Java это вообще возможно?

Если использовать только статические классы, то мы можем опасно к этому приблизиться :)

мы не избавимся от возможностей совершать ошибки.

Я уже однажды писал в комментариях, программирования без производства багов не бывает :)

И ведь даже в этом минимуме можно ошибиться, если мы полностью не отказываемся от ООП. Не говоря о том, идея шаблонного метода достаточно интуитивна. Из-за этого такую ошибку можно совершить, даже если не знаешь с чем имеешь дело.

Разговор ведётся в плоскости проектирования, а не типов данных в рефлексии. В этом контексте определение метода это процедура, связанная с объектом, чему конструктор соответствует.

А, мы об этом. Конечно, задачу сравнения конструктор не выполняет и выполнять не может (впрочем, там было начальное создание мементо, но я его не включил во фрагмент из-за небольшой мудрёности), этим занимается класс в целом.
В пример был приведён только конструктор c инициализацией объекта как конкретный случай использования опасной практики, что и является предметом статьи.

Я всё ещё немного теряюсь в теме обсуждения, но если мы говорим о ParameterBase и о том, не является ли плохой идеей оставить в конструкторе инициализацию - нет, не кажется. Как архитектору модуля нам должно быть известно, как и где объект должен создаваться (в данном случае объект-клиент создаёт конкретную реализацию абстрактного класса, которая ему нужна). Мы же это пишем для конкретного таска, а не в вакууме.
Если логика станет достаточно сложной/понадобится нужда в разных типах объектов в рамках одних и тех же объектов-клиентов то да, порождающий паттерн станет необходимым. Собственно, это я и предлагаю как один из вариантов решения найденного бага.

Много мыслей, а центральную я не уловил. Давайте по отдельности.

А если у вас объект фабрикой классов должен создаваться, что тогда получится?

Не понял. Если будет - тогда и посмотрим. Тут фабрика не рассматривается.

или не дай бог через Dependency Injection

DI никакие объекты не создаёт, оно их передаёт (не могу подобрать лучшую замену inject). Создаются они где-то в другом месте.

Фабрика класов должна создать объект и отдать его тому кто его будет использовать по назначению, а у вас получилось что объект все закончил уже внутри фабрики классов, и по назначению его уже нельзя использовать тому кому это нужно, как же так-то?

Не совсем уловил, что именно тут понимается под "фабрикой классов". Класс сам себя инициализирует, что в простых случаях является нормальной практикой. Использование какой-либо фабрики в приведённых случаях будет оверинжинирингом. К слову, фабрикам не надо заниматься передачей объекта куда бы то ни было, это уже не их задача (если мы говорим про IoC, то этим занимаются отдельные контейнеры). Про "по назначению его уже нельзя использовать тому кому это нужно" совсем не понял.

Шаблоны обычно используются в комбинации друг с другом, иначе в них мало смысла.

Согласен, что очень часто они идут рука об руку. Даже в моём примере с логгером я ненароком использовал стратегию, а в коде с ParameterBase упоминался хранитель. Но вот невозможность их независимого использования тезис очень спорный. Тут я сторонник KISS. Ну и

Если для вас шаблонный метод - один из самых простых паттернов, то такая логика тоже не должна вроде казаться сложной

Отдаю себе отчёт, что в контексте моего недопонимания по многим пунктам звучит забавно, но имеем что имеем :)

который я бы постеснялся назвать простым честно говоря

Это всё, конечно, моё имхо, но я с радостью послушаю других претендентов на это звание

вы бы логику реализовали в методе, а не в конструкторе.

А что, конструктор это не метод? :)
Плюс вольную трактовку я действительно мог где-то себе позволить, но тут сошлюсь на вводный параграф той же книжки GoF по паттернам. Там всё-таки сказано, что это не какой-то строгий свод правил :)

Конструктор вроде как должен только объект создать, вы уже тут нарушили SRP

Честно говоря, не совсем понял к чему это - в конструкторе действительно происходит создание и инициализация объекта. Т.е. буквально то, для чего он нужен. Хотя даже если я что-то упустил - нет, не нарушил. SRP говорит о классах, а не о методах

Мне хочется признаться, что я уже сообщения со второго потерял нить разговора. И именно поэтому я раз за разом повторяю одно и то же разными словами.
Если я допустил ошибку или серьёзную неточность, то буду рад её исправить, если на неё укажете - я действительно мог что-то упустить.

Ну вот поэтому нам и важны абстракции :)
В спецификации действительно довольно расплывчатое определение этих механизмов, и конкретная реализация может отличаться в зависимости от железа и низкоуровневой настройки системы. Тем не менее, эти понятия в документации встречаются - в уже упомянутой выше jls упоминания кэшей значений в регистрах встречается тут и там.

Зависит от того, о каком уровне абстракции мы говорим :). Java на уровне спецификации позволяет потокам (процессора) иметь свой кэш. И в конкретном случае скорее всего это будет именно кэш и регистры процессора.

как у вас получается читать в этой фразе "закешированных значений каждым отдельным потоком "?

Никак. Это не прямая цитата, если это то, что вы хотели услышать :). Я сослался на ту часть документации, которая говорит о следствии - изменения сразу видны другим потокам.

Можете расшифровать что значит фраза:"Изменения видны всем потокам, вместо использования независимых чтений/записей закешированных значений каждым отдельным потоком." ?

По умолчанию потоки копируют значения переменных в свои кэши и работают с ним. Без volatile они бы продолжали использовать локальные кэши, и другие потоки никаких изменений сразу бы не увидели. Собственно, о том и мой пример. Похожий можно найти в спецификации (17.3).

  1. Собственно, вот.

This means that changes to a volatile variable are always visible to other threads

Формулировка, очевидно, совпадает не стопроцентно. Но если усреднить, то можно читать это как "Изменения видны всем потокам, вместо использования независимых чтений/записей закешированных значений каждым отдельным потоком."

  1. Там же, следующее предложение. Действительно всё и сразу.

What's more, it also means that when a thread reads a volatile variable, it sees not just the latest change to the volatile, but also the side effects of the code that led up the change.

В целом вопрос валидный, но на мой взгляд конкретно в этой диагностике работа с только трёхадресным кодом бы не давала достаточно информации для анализа т.к. нам нужно много семантических данных.
Что такое классовое представление, честно говоря, не очень понял.

Стратегию ака внедрение зависимости от функции делать в ООП лучше когда оно реально понадобится а не когда может быть понадобится.

Согласен, в масштабах одной задачи это и правда выглядит избыточно. С моей стороны стимулом всё же было превентивно отделить мух от котлет (ибо в данном случае задача поиска объявления переменных кажется слишком специфичной, если сравнивать её с раскрытием операторов).

А лучше писать в функциональном стиле, тогда и шаблон стратегия будет удобным

Ох, это же сам F# в видео! Всегда интересно про функциональщину слушать, но до дела (и у меня, и глобально) всё никак не доходит :/

Разумеется, есть 1001 и 1 причина рекурсию не использовать, хотя этим тоже связана разная магия.

Я просто о точности понятий, а то приравнивать StackOverflow и рекурсию, это как равнять программирование и производство багов — вроде одно без другого и не бывает, но вещи всё же разные :)

я тут недавно выяснил(ищите по слову "рекурсия"), что вместо рекурсии теперь модно использовать новый термин "stack dives"

Интересно, не слышал об этом. Хотя насколько я понял, stack dives в этом контексте - скорее идентификация потенциальной проблемы, нежели синоним для рекурсии, которая просто является инструментом.

если ООП подход позволяет избавится от рекурсии, это уже само по себе неплохо.

И правда, но в данном случае это скорее приятный побочный эффект, избавляться от любой рекурсии таким способом несколько экстравагантно :)
Сама задача развёртывания рекурсии всё же не новая и решается своими способами, которые легко находятся на хабре.

Именно, поэтому статья про java и работу с кодовой базой, а не о NGB :)
Как я и сказал в начале статьи - авторам Open Source проектов низкий поклон только за то, что они этим вообще занимаются.

Вопрос и правда интересный. Но почему-то большинство языков развиваются именно таким образом. Уж не знаю, связано ли это с техническими причинами (не будет ли проблем при работе с пакетами, использующими эти расширения?), или коллективным помешательством. Всё-таки в C# даже опциональные фичи (типа nullable контекста) отключаются на уровне сборки.

Информация

В рейтинге
417-й
Откуда
Тула, Тульская обл., Россия
Зарегистрирован
Активность