Сучасна диджитал-освіта для дітей — безоплатне заняття в GoITeens ×
Mazda CX 5
×

Приклади хорошого коду: де знайти? (java)

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

Всім доброго дня!

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

Можливо в когось є на приміті цікаві проекти або ж ще щось.

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Ага, класи з парою тисяч рядків та сотнями методів. Дуже хороший код.

Нет такого, каждый разраб хвалит свое болото (основной язык программирования) и обсирает код-конвеншены других языков.

Я однажды показывал код на C++ (довольно простой) из опенсорса бывалым джава разрабам, они его так обосрали, прям мама не горюй, особенно им не понравилось сравние string-ов через оператор ‘==‘ )))

сравние string-ов через оператор ‘==‘

тому що є == а є equals
приплюснутим цього не понять,
крім того String літерал геть не такий як в хрестах...

1) на наших проектах в Javi порівнюється спочатку ==, а потім equal, тобто спочатку якщо не посилання на той же об"єкт, то далі перевіряється вміст
2) в С++ не знаю, що і як, бо є Qt і його методи, напр. compare(), під капот не заглядав
3) в С, як правило нема особливої потреби порівнювати стоки, а якщо є, то можна strcmp або власна реальзація,
4) в Rust ==, що в нього під капотом, не заглядав

P.S.
в Javi все на кучі.... а в чьом сакральний смисл вопроса

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

?

сколько из подобных сравнений не переходило на equal?

В джаве это будет 99,99%, потому что при сравнивании строк, именно строк, в 99,99% это будут строки, которые прошли обработку, т.е. динамически сгенерированные, у которых нет представления в пуле.
Исключение — это если вы будете перебирать заранее определенные наборы строк, в какихто бизнес-константных коллекциях, но это уже специфика бизнес-логики. Но для джавы в целом сравнение объектов через == это антипаттерн.

equals автоматом включает проверку == внутри.

причом тут «они снижают производительность кода»,
детка, это Джава!!!

тут тре розуміти, які типи даних: такі, що зберігаються безпосередньо в пам"яті (примітивні типи), чи такі, що лише зсилку.

P.S.
коротко
== is identity.
.equals() is equality.

P.P.S.
Як тут згадували, про хешкод. Може тут більше буде інформації для розуміння.
habr.com/post/168195
stackoverflow.com/...​-and-equals-with-hashcode

В мене нема статистики. Проект великий і підтримка його може бути в несподіваному місці, від патчка linux kernela до переписування скриптів зборки (не кажучи про С\С++\Java кодфікс).
В мене була потреба імплементації equals для певного класу об"єктів. Тому відповідаю як то є в Javi на відміну від C++.
Якщо хочеш мати повну картину, почитай, про std::string, про оператор присвоєння, про конструктор створення та контструктор копіювання.
Далі прочитай про об"єкт String в Java. Про примітивні типи. Далі про модель пам"яті Java при роботі з строчними типами. Чим відрізняється створений літерал від об"єкту створеноного в рантаймі як new або стрінг білдером. Далі прочитай про порівняння, як воно працює, що таке оператор присвоєння, і ==, equal та hashMap(). Як це працює для примітивних типів та об"єктів. Може тоді перестанеш задавати тупі питання.
Бо один дурень може задати стільки питань, що сотня мудреців не зможе відповісти.

я не пойму, зачем ты мне столько пишешь

ок. досвідос.

т.е. по факту вы 2 раза сравниваете адреса

так ти нічого і не поняв, однозначно «приплюснутий»

у тебя в проекте перед equals везде стоит еще явная проверка на ==

да никто явно == не использует, ибо он и так внутри иквалс. Или ты про три такта процессора на это сравнение?

В джаве это будет 99,99%,

Комипилятор достаточно умен. Одинаковые строковые константы в рамках одной компиляции скорей всего будут ссылаться на один и тот же объект.

Какой смысл в коде программы сравнивать константы?

Шта?

Такаяже как и не строковых. За счет этого самого == перформанс такойже как и сравнение интовых констант. Строки могут быть удобнее, например, в вебе, и не только.

Одинаковые строковые константы в рамках одной компиляции скорей всего будут ссылаться на один и тот же объект.

"Строковые константы" называются литералы, и они помещаются в пул джвм сразу, и да, они будут одни и тем же объектом, и не скорее всего, а точно. Но. Если вы динамически в рантайме сконкатенируете строку, которая равна по значению какому-нибудь литералу, нифига это не будет один и тот же объект сам собой. Джвм не проверяет все стринги на соответствие какому-то из литералов в пуле.

в джаве в принципе строки нужно сравнивать по содержанию, а не по указателю. Потому что в пул строк автоматически попадают только литералы. можно конечно помещать в пул нужные строки, тогда да, можно и по указателю, но зачем? Ради выигрыша в скорости между .еквалс() и == ? Это абсурд

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

Очень просто — может понадобится проверка по указателю. И тогда где вы возьмете проверку по указателю если скажем, у вас оператор == для объектов уже де-факто перегружен?

Не нужно бы было во-первых, самим городить методы проверки

Стоп-стоп-стоп. Еквалс по умолчанию как раз и возвращает хешкод ссылки. Но вообще-то в 99% как раз таки и нужно городить проверки на равенство самому, потому что это часть бизнес-логики объекта.

на мой взгляд логично «==» использовать для сравнения по содержимому

Тут уже вступает философия джавы — твердое «нет» перегрузке операторов. Исключение только для + в стрингах.

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

Скала делает. О каких «современных» языках речь ?

Топикстартер, Роман Черниш похоже пропал.

При чем тут тогда современные языки?

Коментар порушує правила спільноти і видалений модераторами.

В kotlin тоже строки сравнивают оператором ==. Для сравнения по ссылке есть оператор ===.

🎉🍺👍🚂💯🤔🎂✔️☕👺😎

Приклади хорошого коду: де знайти? (java)
(java)

ніде

А как Вам мой проект? Что скажете, может есть предложения для его улучшения?

А пользоваться поиском по форуму не пробовали? Буквально пару недель назад на форуме был совершенно аналогичный вопрос
dou.ua/forums/topic/25765

сьогодні натрапив на чарт з якісними великими проектами lgtm.com/...​-logic/aeron/context:java

у Spring код довольно ровный и главное неплохо откоментированный
советую покурить что то что идеологически интересно из ихнего

«Ихний» встречается и у Булгакова, и у Зощенко, и у Горького, и у Бунина, и у Пришвина, и у Шкловского, и у Л. Андреева, и У Чуковского, и у Л. Толстого, у Чехова, у Достоевского, Тургенева, Лескова, не говоря уже о наших современниках.

thequestion.ru/...​vtor-sdelal-tak-namerenno

ru.wiktionary.org/wiki/Обсуждение:ихний

Його не існує. Навіть в сорцах самої жаби код бюрократично вірний, але від того він ближчий до запитів паралельного всесвіту, де люди мають ідеальну логіку та ідеальну бескінечну пам′ять.

Не віриш — сразу підкажу тему: багатопотокові задачі із множинними блокуваннями потоків, по декілька блокувань на один потік одночасно. Я не кажу що то неможливо. Лише те, що код точно не назвеш гарним, а спроби в ньому розібратися можуть закінчитися клінікою.

Существует, я приводил ссылку.

Извини, не заметил, пока играл в домино с настоящим мужчиной, Богом и Санта-Клаусом.

В сорцях самої жаби теж були оригінальні місця (хз, може й залишилися).
А про реалізацію багатопоточності в жабі було кілька статей з критикою поточної реалізації (але там більше з точки зору архітектури ніж якості коду).

на гітхабі забанили? :)
github.com/amaembo/streamex
github.com/google/guava
з андроїд
github.com/...​ON/Lightweight-Stream-API (напевне найвилизаніший код зі 100% покриттям тестами що я бачив, та приймав участь у розвитку)
github.com/koush/ion
github.com/nickbutcher/plaid

У меня есть хороший проект. sonarcloud.io/...​ard?id=javadev_pt-backend

в первом открытом класе

if (allExerciseEnNames.isEmpty()) {
return „10”;
}

магия...

10 это значение по умолчанию.

Можно создать константу DEFAULT_VALUE = 10.

DEFAULT_VALUE

это чтоб враги не просекли для чего она

В этом смысл числа 10 для этого кода — значение по-умолчанию.

в Вашем коде 10 не число, а строка

А лапки саме такі в коді, як в тебе в коменті? Чи то DOU вийожується із автоформатуванням?

Код доступен, можете сами посмотреть.

💪🍺👍🍭💯🎁✔️🎂🍦😎

Да, строка должна быть.

Там ещё много интересного. JavaScript можете посмотреть.

Проблема в том, что вы не понимаете, что вам хотят сказать, что то, что вы написали — плохо. А если вы это написали, вам на это указали, а вы не в курсе, о чем вам сказали, то с вероятностью в 146% в вашем коде есть еще 100500 ошибок.

И на этом этапе никому уже не интересно, что там еще джаваскрипт есть.

Я не считаю этот код плохим.

Я не считаю

И что дальше? То, что вы что-то не считаете, объективную реальность не меняет.

А в объективной реальности у вас в коде мэджик намберы.
en.wikipedia.org/...​agic_number_(programming

The term magic number or magic constant refers to the anti-pattern of using numbers directly in source code.

Magic number легко исправить. Я предложил решение.
Scrutinizer оценивает качество кода в 9.78.
Очень хороший результат, я считаю.

Magic number легко исправить.

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

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

Хотите — читайте и исправляйте свое детище, хотите — трусите дальше своими 9.78.

А что исправлять если нет конкретики. Я его проверял PVS studio ещё.

Да все, начиная от стилистики и названий методов через _ кончая длиной методов и разбиением классов по пакетам. В сам функционал я не всматривался. Вы должны сами искать, как улучшить свой код, а не заниматься самоуспокоением через авточеки разные

Почитайте хотябы какието конвешны, хорошие практики, чтоли.

Та да. Нужно обязательно почитать.

Ну как-бы да. Мне, например, режет глаза энамы обозванные вот так goal_title_2

Так словарь называется,


    public enum DictionaryName {
        exercise_name,
        exercise_description,
        exercise_bodypart_name,
        exercise_equipment_type_name,
        user_type,
        goal_title,
        goal_title_2,
        email_subject,
        email_text
    }

Можно в верхний регистр перевести.

Ок. Я понял. Только, пожалуйста, не пишите что inUserEmails.get(0).setResetToken("re-" + UUID.randomUUID().toString().replace("-", ""));
это хороший код.

Можно переделать. Мне нужен был уникальный токен с префиксом «re-». А какое ваше решение этой задачи?

Можно переделать.

Да всем пофиг. Вам тут построчно приводят примеры вашего хренового кода, а вы рассказываете про какие-то метрики.
Срачик на доу — вот самая показательная метрика.

Очень даже хороший код.

Можно в верхний регистр перевести

Т.е. вы заявляете, что пишете хороший код, не читав джава код конвеншнов. Смело, чо

Буду рад почитать

джава код конвеншнов

Пришлите ссылку пожалуйста.

Не надо ссылок. Пускай он их перепишет и запостит. Ссылки ото ещё открывать. Ещё, желательно, на русском :)

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

Очень надеюсь, что твоё подозрение верно.

Вы пишите на джаве и не способны самостоятельно найти джава код конвеншн? Это равносильно провалу теста на проф. пригодность.

У меня есть проекты, для которых запускается чекстайл как для кода так и для тестов. Вот пример: github.com/javadev/underscore-java

Ви просто забули закрутити гайки в чекстайлі...Дефолтні правила особливо нічого не ловлять.

а в чём сакральный смысл числа 10? Почему не 100500?
Причём в виде строки...

Там ключ для значения в таблице. Лучше переделать на sequence.

у Вас код зависит от данных в таблице???

ну из приведенного куска видно что он не зависит а наоборот — выборка из базы будет зависеть от того что выдаст return

я не смотрел код.
Но из того, что ты описал — как раз зависит, т.е. если запись имеет другой id — то выбраться может совсем не та запись (или не выбраться вообще). Далее, как я понял, логика зависит от этой выбранной записи. Т.е. код зависит от значения ключа в БД.
Т.е. где-то в каких-то умных документах по сопровождению проекта должно быть написано, что в БД должна быть запись с ИД=10 и такая и именно такая. Читать всем и учить на зубок перед тем, как вносить изменения!
Код и данные должны быть интуитивно понятны, а не чтобы кто-то, кто работает только с БД, должен догадываться, что под ИД=10 должна быть именно такая запись

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

Правильно, приложение работает ожидаемо и стабильно, только если есть конкретная запись в БД с ИД=10. Иначе каплык. Что это, как не зависимость кода от значения в БД? Если по каким-то причинам БД не может иметь запись с таким ИД, то нужно переписывать код и перекомпилировать проект.

ЗЫ. Как раз дописываю свой цикл статей по поводу построения архитектуры ПО. Скоро тут опубликую, надеюсь :)

Не нужна ему запись с ид 10. Будет и с пустой таблицей работать.

скажите, что делает этот метод и в чём сакральный смысл числа 10 (чтобы я не смотрел код технологии, которую я не знаю)?

Это для создания новой сущности в таблице. 10 не уникальное поле. Оно связано с названием справочника.

Ни хрена не понял. Почему именно 10? Зачем оно вообще нужно в коде? А если 10 уже будет «занято» в таблице? А если кто-то, кто ещё работает с БД, поменяет ИД на 8, а 10 присвоит другой строке?

Нужно быть уверенным, что мы говорим про один и тот же код.
Можем обудить его в гитхабе, если хотитте.

Да я не шарю яву, Вы можете концепцию объяснить?

Нужно добавлять/удалять сущности в/из таблицы Уникальным должен быть составной ключ имя_справочника + dkey. При создании нового поля, если dkey не задан, он вычисляется.

зачем нужно магическое число 10 ?

Это как начальное значение констрейна для генерации id в таблице.

тогда мне непонятно, зачем нужен составной ключ в таком случае.

вы точно хотите знать «логику» автора? Мне уже все понятно, и я вот например — не хочу :)

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

зачем нужен составной ключ, если одна из его составляющих — уникальное сгенерированное число

Г — Дезигн.
Я видел систему, в которой тип ключа — флоат.

Пусть автор объяснит, может, у него какой-то специфический случай :)

Можете закинуть проект на heroku. Есть UI который создаёт сущности для этого кода.

у него какой-то специфический случай :)

"У меня хороший код. А что такое меджик намбер? А что такое код конвеншн? Но у меня хороший код" — это дааа, специфичность случая прям налицо.

Да, у меня хороший код. Я знаю про маджик намберы, код конвеншн, покрытие тестами, CI/CD, Java 11, Spring-boot 2.1.1 и javascript frontend.

Я знаю про маджик намберы, код конвеншн

Ну, да, в этой теме вам о них рассказали, это очевидно. Доу образовательный. До этого вы о них не слышали.

покрытие тестами, CI/CD, Java 11, Spring-boot 2.1.1 и javascript frontend.

... и много других страшных слов ©

Читать вас уже просто смешно

Это работающий проект, который тестировался на heroku для java 11 как компиляция так и запуск. Для CI используется travis-co, для code coverage codecov.io.

ну Вам же сказали, что:

Я считаю его очень хорошим и тесты в нём тоже классные.

и всё, точка. Тем более, что тесты в нём классные!

Тем более, что тесты в нём классные!

Ага, очень классные и красивые — один красный, другой зеленый. Жаль, что нет синего и желтого. Хотя стоп — желтый тест есть, можно @Ignore поставить и тест пожелтеет. Нужна аннотация @IgnoreButBlueColor, тогда вообще красота.

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

Там есть и интеграционные тесты с базой данных.

Там есть и интеграционные тесты с базой данных.

и ещё наверняка компилируется и запускается!

Д-о-о. Особенно после комментария.

то с вероятностью в 146% в вашем коде есть еще 100500 ошибок.

Можете запустить проект у себя. Посоздавать сущности, разобраться в функционале.

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

Возможно есть лучшее решение. У меня такое.

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

Я считаю его очень хорошим и тесты в нём тоже классные. У Вас может быть другое мнение.

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

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

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

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

Это как в бэйсике. Строки нумеруются 10, 20, 30.

Я тоже учил Бейсик в школе.

✔️☕👺🚂👍🍺🎉🎁🐱😎

Может не быть записи с ид=10.

Зато компилится и тесты классные))

Я удивился что lombok, кот. вместе со spring-boot 2.1.1 научился компилировать в java 11. Молодцы.

If you happy and you know it,
.collect(toList())
If you happy and you know it,
.collect(toList())
If you happy and you know it,
And you really want to show it,
If you happy and you know it,
.collect(toList())
.collect(toList())

Вполне живой проект.
Устанавливается на heroku без доп. настроек.

Мы говорили про качество кода.

Спешу вас разочаровать — если проект компилируется и запускается — это не значит, что в нем качественный код.

Буду рад узнать про другие проекты.
github.com/...​ON/Lightweight-Stream-API в этом я тоже участвовал, например.

но вполне рабочий.

Вы читаете вообще, что вам отвечают?

если проект компилируется и запускается — это не значит, что в нем качественный код

Да, я читаю что мне отвечают.
В проекте есть большое количество юнит и интеграционнных тестов.

В проекте есть большое количество юнит и интеграционнных тестов.

Т.е., вы еще и путаете качество кода с количеством тестов?

Есть sonarcloud и scrutinizer (он оценивает качество кода в 9.78).
Очень хороший результат, я считаю.

Мне вот интересно, как автоматическая система оценки кода может понять, что это магическое число там лишнее? Может, это вообще какая-то константа мировоздания, типа постоянной Планка или числа Пи.

Scrutinizer умеет ещё юнит тесты запускать и code coverage считать, но там нельзя запустить postgres, поэтому часть тестов не работают.

поэтому часть тестов не работают.

Но они же классные!

Поддержку postgres для CI нашёл пока только у travis-ci.

Поддержку postgres для CI нашёл пока только у travis-ci.

где искал? Если докер есть, то docker maven plugin и вперед. Перед интеграционными тестами подымаем постгрес, после — убиваем.

Локально я могу проинсталлировать postgres. Для ci хочется внешней конфигурации для базы данных.

Локально я могу проинсталлировать postgres.

 а мне тоже нужно его инсталировать чтобы тесты твои прогнать? Какой версии? Какие настройки?

Для ci хочется внешней конфигурации для базы данных.

так в чем проблема, собственно?

Я запускаю тесты на travis-ci или локально при отладке. Можете тоже их на travis запускать.

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

Может и не идеальный, но вполне рабочий проект.
Для изучания spring-boot вполне годится.

Для изучания spring-boot вполне годится.

что-то мне подсказывает, с маджик-стрингами и привязкой к значениям в БД он противопоказан как пример

Нет привязки к значениям БД. Маджик стринги это чекстайл ошибка. Исправляется легко.

это чекстайл ошибка

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

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

Я предложил этот прект как учебный для изучения spring-boot.

На всякий: всё же сонар(кволити гейт/профайл) можно конфигурировать по своему и в данный момент там далеко не все проверяется, например, есть 300+ «code smell» проблем, которые никоим образом не ловятся с помощью гейта(часть фолс-позитив). Да и в зависимости от проекта эти правила тоже могут розниться :)
+ посмотрел закрытые сонара и я не спец по джаве, но не может ли этот код и вправду выдать NullPointerException?
sonarcloud.io/...​lutions=WONTFIX&types=BUG

Да, может. Там сканирование xlsx файла с данными, нужно добавлять проверки на null + unit тесты. Sonar всё правильно пишет.

Підписатись на коментарі