LINUX.ORG.RU

Java джун познаёт мир

 , ,


4

2

Работаю больше 4 месяцев джуном на джаве (spring-boot, hibernate), познаю кровавый интерпрайз. Пока легаси поддерживать не кидали, пилю новый функционал на проектах.

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

Getters/Setters

Постоянно в дтошках вижу одну и туже картину. Куча private полей, и к каждому из них геттер и сеттер. Больше ничего в классе нету. Я не понимаю, нафига строить тут типа «инкапсуляцию», если класс ничего семантически не инкапсулирует? Почему бы не сделать просто public филды?

Lombok

Крутая штука, но некоторые её до жути боятся и продолжают генерировать шаблонный код. Из трёх проектов, в которых я писал код, в двух ломбока не было и всё надо было делать руками (да, нажать биндинг для генерации в idea - тоже, считай, руками). Кроме того ломбок предоставляет @RequiredArgsConstructor, который в спринг-бинах просто мастхэв

Любовь к старым технологиям

Во всех трёх проектах (и это не легаси говно, с нуля все написаны в 2020) используется java 8. Почему не 9, где для optional подвезли нормальные методы? Почему вообще у чуваков такая тяга к старым технологиям? В новой джаве вот уже рекорды добавили, чтобы без ломбока и прочего жить нормально, так не, мы продолжим сидеть на 8, в худше случае и без ломбока.

И это не только с версией джавы, на проектах (новых!) используется версия querydsl 3.x, поддержка которой давно закончилась. Понятно, что в 4.x поломали совместимость, но неужели разобраться с этим это прям такое запарное дело?

Ехал singleton через singleton или процедурное программирование

По сути в архитектуре веб-приложухи на джаве нету никакого ООП. Все Service-компоненты с бизнес-логикой это по сути просто набор процедур. Все объекты service-классов существуют в единственном виде как синглтон. По крайней мере, я так это понял. Dtoшки это вообще не класс, это просто классический record в виде си. Всё в итоге сводится к процедурному программированию, когда дтошки (читай - записи) суются в методы сервисов (читай - в процедуры), откуда вызываются другие методы (по сути те же процедуры).

Код и данные максимально разделены. Это как-то не сходится с моими представлениями о ооп и тому, чего я ожидал от «ооп-языка»

Непонятные решения в БД и около её.

В лабах я привык использовать idшники в качестве PK, однако в реальном интерпрайзе везде uuidшники. Я погуглил, понял, что всё как-то связано с масштабированием и немного с безопастностью (если неавторизованные юзеры работают с сущностями), но в одном проекте у нас были и idшники, и uuidшники! Зочем?

Чейнджсеты ведутся в liquibase, причём все они хранятся в одном каталоги и инклюдятся в мастер-чейнджсет через includeAll. Нумеруются по принципу дата-айдишник-описание.xml. НО. Это же костыль! Если у меня в один день будет changeset в id=9 и с id=10, то 10ка попросту выполнится перед девяткой! Если уж использовать только числовые айди, то почему бы liquibase Не выполнять их по очереди?

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

Во всех трёх проектах (и это не легаси говно, с нуля все написаны в 2020) используется java 8.

Java 8 до 2030 года использовать будут, вот увидишь. Как бы тут не копротивлялся местный клоун.

EXL ★★★★★ ()

Постоянно в дтошках вижу одну и туже картину. Куча private полей, и к каждому из них геттер и сеттер. Больше ничего в классе нету. Я не понимаю, нафига строить тут типа «инкапсуляцию», если класс ничего семантически не инкапсулирует? Почему бы не сделать просто public филды?

Ради однородности, на будущее, чтобы не думать. Ну и чтобы не обосраться случайно, поставив += где-то или = вместо ==.

Вообще должно быть очевидно даже на 2 курсе, а ты работаешь.

peregrine ★★★★★ ()
Последнее исправление: peregrine (всего исправлений: 3)

Постоянно в дтошках вижу одну и туже картину. Куча private полей, и к каждому из них геттер и сеттер. Больше ничего в классе нету. Я не понимаю, нафига строить тут типа «инкапсуляцию», если класс ничего семантически не инкапсулирует? Почему бы не сделать просто public филды?

Во-первых иногда нужны нетривиальные геттеры/сеттеры. Возможно в будущем. В этом случае у тебя будет каша из полей и методов. Некрасиво. А также потребует переписывать клиентский код, если в будущем какое-то поле нужно будет переделать в геттер/сеттер. А если он у тебя изначально есть, тебе даже не нужно перекомпилировать клиентский код.

Во-вторых многие фреймворки требуют именно геттеров/сеттеров и не будут работать с полями.

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

В-четвёртых так принято.

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

Крутая штука, но некоторые её до жути боятся и продолжают генерировать шаблонный код. Из трёх проектов, в которых я писал код, в двух ломбока не было и всё надо было делать руками (да, нажать биндинг для генерации в idea - тоже, считай, руками).

Ломбок слишком магический. Многие этого не любят.

Кроме того ломбок предоставляет @RequiredArgsConstructor, который в спринг-бинах просто мастхэв

Вообще-то не маст-хэв. Лично я считаю, что это вообще вредный стиль и не делаю так. Сеттеры гораздо удобней и наглядней, если тебе нужно инициализировать бин без спринга.

Во всех трёх проектах (и это не легаси говно, с нуля все написаны в 2020) используется java 8. Почему не 9, где для optional подвезли нормальные методы? Почему вообще у чуваков такая тяга к старым технологиям? В новой джаве вот уже рекорды добавили, чтобы без ломбока и прочего жить нормально, так не, мы продолжим сидеть на 8, в худше случае и без ломбока.

Возможно есть технические причины. В целом да, многие Java-разработчики не любят новое. Это реальность. 8-ка будет поддерживаться вечно, проще её использовать, чем учить новое.

И это не только с версией джавы, на проектах (новых!) используется версия querydsl 3.x, поддержка которой давно закончилась. Понятно, что в 4.x поломали совместимость, но неужели разобраться с этим это прям такое запарное дело?

Может и не запарное, но зачем?

По сути в архитектуре веб-приложухи на джаве нету никакого ООП. Все Service-компоненты с бизнес-логикой это по сути просто набор процедур. Все объекты service-классов существуют в единственном виде как синглтон. По крайней мере, я так это понял. Dtoшки это вообще не класс, это просто классический record в виде си. Всё в итоге сводится к процедурному программированию, когда дтошки (читай - записи) суются в методы сервисов (читай - в процедуры), откуда вызываются другие методы (по сути те же процедуры).

Код и данные максимально разделены. Это как-то не сходится с моими представлениями о ооп и тому, чего я ожидал от «ооп-языка»

Потому, что ООП это говно. То, что ты видишь, называется анемичная модель и это правильный подход.

Непонятные решения в БД и около её. В лабах я привык использовать idшники в качестве PK, однако в реальном интерпрайзе везде uuidшники. Я погуглил, понял, что всё как-то связано с масштабированием и немного с безопастностью (если неавторизованные юзеры работают с сущностями), но в одном проекте у нас были и idшники, и uuidшники! Зочем?

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

Чейнджсеты ведутся в liquibase, причём все они хранятся в одном каталоги и инклюдятся в мастер-чейнджсет через includeAll. Нумеруются по принципу дата-айдишник-описание.xml. НО. Это же костыль! Если у меня в один день будет changeset в id=9 и с id=10, то 10ка попросту выполнится перед девяткой! Если уж использовать только числовые айди, то почему бы liquibase Не выполнять их по очереди?

Да, это потенциальная проблема. Опять же тебе лучше спрашивать у тех, кто за это отвечает, а не на лоре.

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

Удобно, когда всё в одном коде. Плюс триггеров в том, что они работают, даже когда с базой работают другие приложения. Если в вашем случае база жёстко привязана к приложению, то особо про это думать не нужно. Ещё минус триггеров в том, что приложение невнятно падает при нарушении этого триггера и нужно писать нетривиальный код, чтобы понять, из-за чего именно упало и сформировать, например, правильное описание ошибки для пользователя. Когда валидация в Java-коде, этой проблемы нет.

Вообще ответы на все твои вопросы по сути в том, что там, где ты работаешь, так принято. Можно делать и так, можно делать и по-другому, правильного ответа тут нет.

Legioner ★★★★★ ()

Во всех трёх проектах (и это не легаси говно, с нуля все написаны в 2020) используется java 8.

Идём сюда: https://adoptopenjdk.net/support.html#roadmap и видим, что восьмёрка будет поддерживаться минимум до 26го года, а более свежая LTS джава 11 всего лишь до 24го.

Почему не 9, где для optional подвезли нормальные методы?

Потому что не поддерживается. У нас чуваки из другого отдела написали сервис на 12ой джаве. На дворе уже 15-ая, багфиксов для 12-ой нет и не будет. Обновлять проект до более свежей джавы никто не будет. Клоуны, блин.

Irben ★★ ()

Getters/Setters

Карго-культ. Боятся использовать публичные поля, как бы чего не выстрелило в каком-то дремучем легаси.

Lombok

Постоянно ломается поддержка в IDE и в новых версиях Java, чинится долго. Это неприятно кому угодно.

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

В серьезном ынтерпрайзе бывают требования к качеству написанного кода с 11 девятками. Если на проде в банке ключевая часть инфраструктуры падает, то там доходит до того, что покупают платную поддержку от Oracle, RedHat и IBM и чинят бессонными ночами за огромные бабки.

Короче, ломбок - это хорошая штука для обычных людей, но в кардиостимуляторах я бы не стал

Любовь к старым технологиям

Три проблемные категории

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

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

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

Ехал singleton через singleton или процедурное программирование

Обычно никто не знает ООП, и всем пофиг. Поспрашивай архитекторов, в чем смысл SOLID. Не что такое SOLID, а в чем его смысл. Большая часть людей не сможет ответить

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

Про процедурное программирование, впрочем, всё то же самое

Можно писать ООП, не имея ООП-инструментов. А можно писать процедурщину на языке, который ее напрямую запрещает. А Spring это вообще отдельная идеалогия

Попробуй задать себе философские вопросы - зачем ты делаешь то, что делаешь. В чем ценность этого в глобальном смысле.

но в одном проекте у нас были и idшники, и uuidшники! Зочем?

надо было сделать везде uuid-шники, но сразу не подумали, а потом старый код уже не поправишь. Как он работает в точности никто не знает, и даже мало-мальски адекватных тестов на это нет. Обычная ситуация

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

Чейнджсеты ведутся в liquibase

liquibase говно, но ничего лучше пока не сделали. Если чувствуешь себя в силах - сделай

но лучше не тратить на это время :) Ну говно и ладно. Что, мало говна в мире? Лучше улучшить какую-то вещь, которая реально требует улучшения и сделает всем хорошо

stevejobs ★★★★☆ ()
Ответ на: комментарий от Legioner

Возможно есть технические причины. В целом да, многие Java-разработчики не любят новое. Это реальность. 8-ка будет поддерживаться вечно, проще её использовать, чем учить новое.

Вроде как для 11-ой ничего такого учить не надо, можно писать как писал на восьмёрке. Однако согласен с техническими вопросами. Автор ничего не сказал про среду, в которой крутятся приложения. Возможно там банально не поднять 11ую джаву (старый application server). Ну или для этого необходимо переписать часть скриптов.

Также нельзя забывать, что из 11-ой джавы выкинули jax-ws. Если там SOAPы во все поля, то придётся ручками добавлять недостающие библиотеки. Не то, чтобы это было сложно, но всё же.

Irben ★★ ()
Ответ на: комментарий от Irben

Вроде как для 11-ой ничего такого учить не надо, можно писать как писал на восьмёрке.

В Java 9 добавили модули, которые кучу всего поломали. У многих разработчиков это оставило серьёзную психологическую травму. Пожалуй это самый ломающий совместимость релиз в истории Java.

Legioner ★★★★★ ()
Последнее исправление: Legioner (всего исправлений: 1)
Ответ на: комментарий от Legioner

У многих разработчиков это оставило серьёзную психологическую травму.

Вот это главная проблема. Зашкаливающее количество шизиков на сеньерных и менеджерских позициях

Менеджеры и сеньеры - люди с опытом, а в ходе опыта они сходят с ума и впадают в легасибесие и дргугие серьезные заболевания

Это вопрос не инженерии, а психологии и психиатрии :)

stevejobs ★★★★☆ ()
Ответ на: комментарий от Legioner

В Java 9 добавили модули, которые кучу всего поломали. У многих разработчиков это оставило серьёзную психологическую травму. Пожалуй это самый ломающий совместимость релиз в истории Java.

Видать, мне повезло с разработчиками. Даже мужик под 60 лет фигачит на 11ой джаве. Я его, правда, не спрашивал. Дал задание, он и делает.

Irben ★★ ()
Ответ на: комментарий от stevejobs

С другой стороны я думаю, что Java 8 будет поддерживаться беспрецедентно долго как раз из-за этих причин, что очень многие не хотят никуда переходить. Т.е. если нужно написать программу, которая должна работать без обновлений в течение лет 20, Java 8 подойдёт больше, чем Java 11. Тем более, что ничего особого в Java 11 не добавили, синтаксический сахар var и какую-то мелочь в стандартные библиотеки.

Legioner ★★★★★ ()

Getters/Setters

В плоских DTO не знаю зачем, а вот если из них делать иерархию то поля в java не переопределяемые (override). Например если один класс наследуется от другого и по какой-то причине в них оказались поля с одинаковым именем, то поле дочернего класса скроет поле из супер класса, а не переопределит.

В DAO геттеры и сеттеры еще нужны для проксирования, чтоб всякие Fetch.LAZY работали. Т.е. при обращении через метод сущности entity.getRelatedEntity() в контексте сессии может быть выполнен select из базы, прокси перехватит вызов и ORM выполнил выборку.

Lombok … до жути боятся и продолжают генерировать шаблонный код.

Индивидуальные заморочки, все люди разные, с разными предпочтениями.

Любовь к старым технологиям … используется java 8. Почему не 9

9 не LTS версия, её бесплатный суппорт кончился два года назад, можно взять Java 11, это LTS. https://www.oracle.com/java/technologies/java-se-support-roadmap.html

Ехал singleton через singleton или процедурное программирование

В общем так и есть. Я так понимаю у вас там Spring Web MVC, MVC подразумевает что есть Контроллер, есть модель (которая передается через DTO), есть View куда должна быть отправлена модель.
Плюс если используется Hibernate/JPA то он фактически реализует шаблон Datamapper, т.е. данные отдельно, логика выборки одтельно.

В лабах я привык использовать idшники в качестве PK, однако в реальном интерпрайзе везде uuidшники.
Хотя в некоторых местах триггеры выглядели бы прям как образцовый пример из методички, на мой взгляд.

Нет догм, тут все делают по разному, как кто решил.

Aber ★★★★ ()
Последнее исправление: Aber (всего исправлений: 1)

Во всех трёх проектах (и это не легаси говно, с нуля все написаны в 2020) используется java 8. Почему не 9

Возможно прод на каком-нибудь говённом гнилом центосе 6 где свежей жавы не подвезут никогда.

slovazap ★★★★★ ()

Getters/Setters

Ты не сможешь заоверрайдить паблик поле даже если очень захочется

Lombok

Вкусовщина, некоторые не любят.

Любовь к старым технологиям

Это твой локальный опыт.

процедурное программирование

Чем проще код тем проще его поддерживать.

Непонятные решения в БД и около её.

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

ya-betmen ★★★★★ ()
Ответ на: комментарий от peregrine

Ради однородности, на будущее, чтобы не думать.

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

Ну и чтобы не обосраться случайно, поставив += где-то или = вместо ==.

Ох уж эта джава и её боязнь лишних операций. В плюсах вот можно перегрузить (и успешно перегружают в куче либ) кучу операций, от + до ->, и ничего, живут. В йода-стайле на c/c++ тоже уже давно никто не пишет.

Вообще должно быть очевидно даже на 2 курсе, а ты работаешь

Пока мне очевидна лишь ограниченность языка %)

Fizzika ()
Последнее исправление: Fizzika (всего исправлений: 1)
Ответ на: комментарий от Legioner

Во-первых иногда нужны нетривиальные геттеры/сеттеры.

У меня был такой момент, когда одновременно в дтошке было поле и хэш этого поля, который вычислялся в рантайме. Ну чо, подумал я, это же computed свойство, сейчас запилю геттер вместо отдельного поля. А фиг там плавал, ПМ сказал, что это непрозрачно, неочевидно, и вообще дтошка должна быть простой как плака, и что лучше сетать хэш в специальном слое под названием «converters» (да, mapstruct не юзали, писали конвертеры руками, наследуясь от какого-то google commons класса)

Во-вторых многие фреймворки требуют именно геттеров/сеттеров и не будут работать с полями.

Вопрос был про дтошки, с ними работает jackson и public поля отлично переваривает

В-третьих, и это самое важное, нередко нужно узнать, кто изменяет или запрашивает заданное поле. Если есть геттер/сеттер, просто ставишь туда брякпоинт и всё

Хороший аргумент, thk

Fizzika ()

1. Getter/Setter. Добавляются на случай, если в геттер-сеттеры нужно будет добавить какую-то логику позже.

2. Lombok - говно, используйте AutoValue.

3. java 8. Все может очень сильно зависеть от лицензий на серверах. Скажите спасибо, что у вас там не какой-нибудь старинный RHEL с java6.

4. Ехал singleton через singleton. Все так. Если вам хочется ООП ради ООП - то это так не работает. Если ООП поможет упростить задачу - предлагайте конкретные решения.

5. Также не пишутся никакие sql-триггеры. Если можно что-то улучшить - надо улучшать.


Резюме.

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

trex6 ★★★★★ ()
Ответ на: комментарий от Legioner

8-ка будет поддерживаться вечно

Да, про поддержку я и не думал, спасибо всем, кто на это указал :)

Да, это потенциальная проблема. Опять же тебе лучше спрашивать у тех, кто за это отвечает, а не на лоре.

Ну я спросил, мне сказали, «проставь чейнджсет следующим числом». Ну вроде норм, но костыль. И такие потенциальные проблемы могут много где возникать (даже в исходниках лора наименование чейнджсетов похожее)

Fizzika ()
Ответ на: комментарий от ya-betmen

, жидкобаза её немного облегчает.

Я вот не понимаю нафиг она нужна, ну есть кейс что тесты пишутся против h2 базы, или любой другой «игрушечной» субд. Но смысл тестировать что-то против другой БД? Одни проблемы, начиная с native query.

Я так и не понял глубинный смысл liquibase, на прошлой работе использовались sql в shell, ничем не хуже.

Aber ★★★★ ()

Я просто мимокрокодил

Почему бы не сделать просто public филды

Потому что геттер/сеттер позволяет потом добавить какую-то дополнительную логику без поломки контракта.

в одном проекте у нас были и idшники, и uuidшники! Зочем?

Есть разные причины иметь int id в качестве pk. Например банально чтобы обеспечить выборку в порядке вставки, т.е. для запросов «последние 10 строк» и т.п.

всё как-то связано с масштабированием и немного с безопастностью

С масштабированием оно связано, когда id не используется, потому что uuid можно генерировать без блокировки. Если у тебя много «писателей» то глобальный лок на последовательность id станет узким местом. Для безопасности uuid полезен тем, что если пользователь зарегался и видит свой id=5435, то он сразу может предположить, что всего у тебя ~5000 пользователей. Причем id = 1..100 это с высокой вероятностью какие-то админы, разрабы, тестировщики и т.д. которых нужно ломать, пытаться заинжектить им пустой пароль и т.п.

no-such-file ★★★★★ ()
Ответ на: комментарий от Irben

Автор ничего не сказал про среду, в которой крутятся приложения. Возможно там банально не поднять 11ую джаву (старый application server).

Ну тут, думаю, не в среде дело: облако в aws, openjdk, jenkins

Если там SOAPы во все поля

К счастью, нет, у нас REST. Кстати, а кто-то использует SOAP в новых проектах в 2020 году?

Fizzika ()
Ответ на: комментарий от Fizzika

Пока тебе до синьора далеко. Вот будет пара факапов с убытками в пару лимонов баксов на проде и станешь не то что про аккуратность кода, так и про правильную расцветку в редакторе и шрифты нотации читать.

peregrine ★★★★★ ()
Ответ на: комментарий от peregrine

Вот будет пара факапов

Вот тут кстати да, на одном проекте не использовался liquibase для создания структуры бд, а был включён ddl-auto в хибернейт. Поначалу было весело, но потом надо было добавить каскадное удаление для FK. И да, старый fk hibernate не дропал, новый не создавал. Просто же так дропнуть по имени в скрипте - да там имя нечитаемое hibernate сгенерировал, на локалхосте дропнешь, а на деве что?

В итоге пришлось мне писать хранимку для постгреса, которая дропала констрейт по имени поля, на который он ссылается.

Было весело, конечно, но с тех пор я на своей шкуре прочувствовал, почему ddl-auto это зло, и что уж лучше писать структуру таблиц руками в xml

Fizzika ()
Ответ на: комментарий от anonymous

Ты жаба джун о 4 месяцев а уже получаешь 300кк/нс и знаешь намного больше чем все эти остальные старперы.

Да я понимаю, что мои познания джавы довольно ограничены, выводы импульсивны и категоричны, а сам я даже пороху не нюхал и на серьёзных щах судить о чём-то плохо получается))

Но юношеский максимализм это в общем-то хорошая штука, и я его полностью терять не хочу

Fizzika ()
Ответ на: комментарий от trex6

Если ООП поможет упростить задачу - предлагайте конкретные решения.

Опыта часто не хватает. Вот думаешь, что сейчас сделаешь этот кусок нешаблонно и будет дофига круто - делаешь, через 2 часа нифига не работает, кое-как допиливаешь, через час смотришь, а там такое УГ получилось, что уж лучше бы сделал в более традиционном виде.

Думалку пытаюсь включать перед тем как сделать, конечно, и часто в голове всё стройно и круто, но только начинаешь реализовывать, и получается УГ

Резюме.

Спасибо, учту :)

Fizzika ()

Постоянно в дтошках вижу одну и туже картину. Куча private полей, и к каждому из них геттер и сеттер. Больше ничего в классе нету. Я не понимаю, нафига строить тут типа «инкапсуляцию», если класс ничего семантически не инкапсулирует? Почему бы не сделать просто public филды?

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

doctorx ★★★ ()
Ответ на: комментарий от Legioner

Во-первых иногда нужны нетривиальные геттеры/сеттеры. Возможно в будущем

Ага, году так в 2077-м. Если карта ляжет. И фаза луны подходящая будет. Чушь полная. Они либо никогда не оказываются нужны, либо изначально нетривиальные, либо отсутствуют в принципе.

Во-вторых многие фреймворки требуют именно геттеров/сеттеров

Потому что их писали мудаки, не осилившие хотя бы Effective Java прочитать.

В-третьих, и это самое важное, нередко нужно узнать, кто изменяет или запрашивает заданное поле. Если есть геттер/сеттер, просто ставишь туда брякпоинт и всё.

А на самом деле просто right-click -> find usages.

В-четвёртых так принято.

Не принято. Разве что среди писателей фреймворков из «во-вторых».

То, что ты видишь, называется анемичная модель и это правильный подход.

А «нетривиальные геттеры/сеттеры» — это ещё анемичная модель, или уже не очень?

korvin_ ★★★★★ ()
Ответ на: комментарий от Fizzika

в голове всё стройно и круто, но только начинаешь реализовывать, и получается УГ

Так и должно быть. Пробуйте новое, зарабатывайте опыт. В какой-то момент все начнет получаться с первого раза.

trex6 ★★★★★ ()
Ответ на: комментарий от korvin_

Ага, году так в 2077-м. Если карта ляжет. И фаза луны подходящая будет. Чушь полная. Они либо никогда не оказываются нужны, либо изначально нетривиальные, либо отсутствуют в принципе.

У меня такое не раз бывало.

Потому что их писали мудаки, не осилившие хотя бы Effective Java прочитать.

Это эмоции. Переписывать фреймворки, потому, что тебе какая-то мелочь не понравилась, глупо.

А на самом деле просто right-click -> find usages.

Я про рантайм. Найдёшь ты 10 использований и что дальше? Пойдёшь по каждому из 10 и там будешь тыкать find usages? А в рантайме ты останавливаешься и видишь весь стек-трейс со всеми значениями переменных и тебе уже более-менее понятно, что происходит.

Правда некоторые мудацкие фреймворки меняют значения полей через reflection, даже когда есть getter/setter. Повбывав бы.

А «нетривиальные геттеры/сеттеры» — это ещё анемичная модель, или уже не очень?

Анемичная модель это высокоуровневый архитектурный подход. От того, что у тебя будет несколько нетривиальных геттеров, архитектура не поменяется. К тому же структура классов часто диктуется теми же самыми фреймворками. Если у тебя этот класс сериализуется в JSON, гораздо разумней написать простой геттер, чем мудохаться с какими-то кастомными сериализаторами.

Legioner ★★★★★ ()
Последнее исправление: Legioner (всего исправлений: 1)

Ты просто пока Джун и ещё не прочуял на собственной шкуре, что такое искать 100500 обращений не к геттеру/сеттеру а к переменной, когда вдруг потребуется сделать допил - например, сохранение объекта в бд при вызове сеттера или синхронизацию потоков при вызове геттера.
Г/с реально тру, очень выручает в тыще случаев от разделения логики до внедрения обработки в тела методов

Про Яву 8 все просто - никто не использует Явы 9,10,12 и тп - там мало реально нужного в большинстве проектов (ибо все было уже в Яве 6, а в Яве 8 стало ещё и удобно).
Все используют Явы 8 и 11 - это лтс (8 уже за бабло, так что по хорошему пора бы на 11 переходить). Ява не про беганье между версиями, гонкой за релизом и т.п. - тут все стабильно работает годами и в целом выбор платформы зависит просто от статуса ее текущей лтсности

Уиды в Яве … да пофигу что использовать - я гоняю уиды потому что я могу сгенерить уид ДО записи в БД без подключения к ней (с шансом успеха стремящемся к бесконечности). Если есть постоянное подключение - ид эффективней. Юзай чо хочешь

rukez ()

Хорошо набросил, годно.

По пунктам:

  1. Так принято в яве. Старый-добрый POJO.

  2. За Lombok надо убивать, ящитаю

  3. Ъ-джависты переходят на следующую LTS версию, когда заканчивается поддержка старой. Ну, а то, что вы старье используете в зависимостях, это недостаток вашего проекта.

  4. Это тебе к Егору.

  5. У нас как-то были целочисленные id в качестве ключа. Не поверишь, они через 12 лет кончились. Пришлось базу мигрировать на новые.

Также не пишутся никакие sql-триггеры, вся логика прописывается в коде.

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

cocucka ★★★ ()
Ответ на: комментарий от stevejobs

все было хорошо, пока не пришёл стиви

В серьезном ынтерпрайзе бывают требования к качеству написанного кода с 11 девятками.

после 7 девяток годовой даунтайм падает ниже секунды, что полностью маскируется сетевыми задержками, поэтому даже 5 девяток мало кто перешагивает

Если на проде в банке ключевая часть инфраструктуры падает то там доходит до того, что покупают платную поддержку от Oracle, RedHat и IBM

не доходит. платная поддержка это необходимый минимум, без неё и до 4х девяток сложно добраться, да и вообще в энтерпрайз не пустят

и чинят бессонными ночами за огромные бабки

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

xavaco5033 ()
Ответ на: комментарий от ya-betmen

нет, на тестовых инстансах данные чистились иногда, но только в нереплицируемых служебных таблицах. в остальном все по-взрослому — частью релиза был sql скрипт, который инкрементил версию до нужной и с вот этими апдейтами база жила годами, пока кто-нибудь не грохал физический сервак

xavaco5033 ()
Ответ на: комментарий от xavaco5033

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

ya-betmen ★★★★★ ()
Последнее исправление: ya-betmen (всего исправлений: 1)
Ответ на: комментарий от ya-betmen

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

xavaco5033 ()
Ответ на: комментарий от Legioner

Это эмоции. Переписывать фреймворки, потому, что тебе какая-то мелочь не понравилась, глупо.

Я не говорил, что их нужно переписывать.

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

Всегда есть вариант писать юнит-тесты.

Правда некоторые мудацкие фреймворки меняют значения полей через reflection, даже когда есть getter/setter. Повбывав бы.

Это эмоции, перепиши. )

К тому же структура классов часто диктуется теми же самыми фреймворками.

Можно ж не использовать (такие) фреймворки.

Если у тебя этот класс сериализуется в JSON, гораздо разумней написать простой геттер, чем мудохаться с какими-то кастомными сериализаторами.

Jackson прекрасно сериализует публичные поля. Думаю, GSON тоже.

korvin_ ★★★★★ ()

Во всех трёх проектах (и это не легаси говно, с нуля все написаны в 2020) используется java 8.

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

Norgat ★★★★★ ()
Ответ на: комментарий от ya-betmen

Сколько тестовых серверов у вас было? Как отслеживали версии баз на них?

Я поясню что имею ввиду. Можно просто все организовать без liquibase, sql файлы с ченджсетами именованными например датой 20201025.sql, изменения применяются через какой-нибудь cli типа psql для postgres, где обращение к psql спрятано вызовом функции:

apply-sql '1.0/20201024.sql'

все это запускается через самописный apply-db.sh в 100-200 строк. В эти 200 строк уместится вставка мета инфы о перемененных файлах. Все абсолютно прозрачно.

Я не понял что нового привнес liquibase, ну ок, не зависит от ОС, можно на винде использовать и… все.

Отвечая на твои вопросы, там где это было и работало, были две тестовых базы, test, preprod, плюс базы на машинах разработчиков.

Я просто сейчас работаю на проекте с liquibase, и я понимаю что он вообще мне не пригодится. Никогда эту штуку в свой проект я не возьму, она ничем не помогает.
В ряде проектов для тестов используется h2 база и мне это не нравится, т.к. там база не полная, сложные вещи требуют raw-sql и такие ченджсеты не применяются к h2. Плюс ты должен помнить что где-то тут есть raw-sql и его нельзя протестировать против h2 базы, и с этой успокаивающей инфой закоммитить как есть и пойти лечь спасть.

Aber ★★★★ ()
Последнее исправление: Aber (всего исправлений: 2)
Ответ на: комментарий от Irben

У Java же обратная совместимость, не? Просто изменить версию Java и пересобрать проект? Из ломающего я помню только то, что рефлексию ломали вводя модули, но и то решается одним ключом запуска.

KivApple ★★★★★ ()
Ответ на: комментарий от KivApple

Я помню как 4-е месяца спустя после релиза java9, в Eclipse не работали некоторые функции рефакторинга при использовании новой java. Баги были, там было активное обсуждение и никто не был уверен как это правильно пофиксить ничего не сломав. Тогда я перешел на IDEA.

Или вот:

Spring Boot 1.5 can be used with the version 8 of java. In order to use Java9 you need SpringBoot 2.0. In order to use Java11 you need SpringBoot 2.1.X, as you mentioned.

В Java следят за обратной совместимостью, но Spring и IDE специфичные тулы, они опираются на тонкости реализации jvm, лезут во внутренности рантайма, в пакеты sun.* на которые контракты обратной совместимости не распространяются. Плюс бывают фиксы меняющие поведение, например год или два назад был фикс в реализации Stream api.

Aber ★★★★ ()
Последнее исправление: Aber (всего исправлений: 2)