Сыграл несколько партий, в целом играбельно, но отсутвие предходов и анализа партий сильно лично для меня бросается в глаза, да и сам интерфейс какой-то не удобный, правильно сказали что сырой проект пока-что
Одно дело когда реклама реально полезна, т.е. потенциально ты можешь купить товар и останешься доволен, другое — когда это откровенный развод. Я писал модераторам, скидывал линки на прувы о том что это мошенники, реакции 0. Лично мне бы было стыдно работать над этим, а они ещё и на хабр стать ю запили.
А вы не задумывались, во что бы превратилась компания, если бы все вели себя так как вы, приходили в таком же каком состоянии итд? Вы ничем не лучше остальных людей, и все вот эти рассказы о том что я делаю свою работу так классно, лучше всех, но директор меня не любит звучат по детски(подучить линуху, ну понятно) и как правило далеки от реальности, незаменимых людей нет, в серьезной компании вас бы вышвырнули сразу.
Здравствуйте, я посмотрел ваш код на гитхабе и написал несколько замечаний с рекомендациями, вообщем небольшое такое код-ревью провёл, раз уж вы выложили код на хабр:)
1. для чего в CProductService аннотации @Transactional над самим классом и методами create и update? Они явно лишние на мой взгляд, что касается метода delete, я не помню его поведение в случае попытки удалить несуществующую сущность, по-моему падает эксепшн — что лучше, 2 раза сходить в БД или ловить эксепшны, вопрос спорный, если у кого есть какие мысли — пишите, мне тоже интересно
2.Хьюстон, тут у нас явно проблемы…
a. Почему findAll()? вытаскивать все продукты из БД и бегать по ним стримом на стороне сервера в будущем будет очень жирно, тем более что уже есть метод productRepository.findByName
b.
name.compareTo(x.getName()) == 0
— весьма странное решение, если вы не собираетесь ничего сортировать, достаточно equals или equalsIgnoreCase
с. создавать массив с 1 элементом чтобы его поменять… примерно тоже самое будет выглядеть как-нибудь вот так:
productRepository.findByName(name)
.stream()
.filter(it -> it.getName().equalsIgnoreCase(name))
.findAny()
.orElseThrow(() -> new CProductNotFoundException(name))
Но вообще я не понял смысла этого метода т.к. уже есть findByName, и по сигнатуре они похожи:
public List<CProduct> findByName(String name)
public CProduct findOne(String name) throws CProductNotFoundException
… можно было сделать что-то вроде:
List<CProduct> products = productRepository.findByName(name);
if (products.isEmpty()){
throw new CProductNotFoundException(name);
}
return products.get(0);
но ещё короче было бы сделать всё в репозитории с помощью аннотации Query(nativeQuery = true, ...)
3. пункт 1 и 2 актуальны для всех сервисов как оказалось, т.к. там везде примерно одинаково
4. вообще в моей практике пакет с @RestController'ами всегда так и называли — controller, реже — rest… но это уже на ваше предусмотрение, просто resources я ещё не встречал
5. пакеты названы то в единственном числе, то во множественном — нужно единообразие
6. возвращать из контроллеров ResponseEntity.ok нет смысла, они итак будут по-умолчанию 200, если нужны разные статусы, тогда ок, но можно было бы это делать через @ControllerAdvice, т.к. как правило логика примерно одинакова
7. CHomeResource возвращает статику, можно было бы возвращать чистый html из ресурсов
8. в CMViewRepResource
очень странно что вы возвращаете null, когда у вас есть ResponseEntity, можно возвращать код с ошибкой
9. совсем нет логирования
10. JasperReportService не бин, он не будет инжектиться в CMViewRepResource, будет NPE
11. лучше пользоваться интерфейсами, когда пишите сервисы
Ну вместо бумажный можно и электронные читать, глаза не устают, главное не телефон/монитор.
Ну хороший сон это база, плох тот разработчик, кто не знает базы)
так и где это ваше OpenIDE можно найти(код посмотреть)?
хорошая новость, с удовольствием буду контрибьютить
Напоминает историю, как джуну дали доступ к продовской БД, он там что-то натворил и его уволили через день.
Возможно, более опытный мидл подумал бы и заранее посмотрел, на каком окружении он запускает тесты. А стажеру это не пришло в голову.
Возможно(Очевидно) что более опытный(тот кто ставил задачу) должен был об этом подумать.
Сыграл несколько партий, в целом играбельно, но отсутвие предходов и анализа партий сильно лично для меня бросается в глаза, да и сам интерфейс какой-то не удобный, правильно сказали что сырой проект пока-что
Вот бы ещё такси было нормальным. Иначе функция бесполезна.
Одно дело когда реклама реально полезна, т.е. потенциально ты можешь купить товар и останешься доволен, другое — когда это откровенный развод. Я писал модераторам, скидывал линки на прувы о том что это мошенники, реакции 0. Лично мне бы было стыдно работать над этим, а они ещё и на хабр стать ю запили.
А вы не задумывались, во что бы превратилась компания, если бы все вели себя так как вы, приходили в таком же каком состоянии итд? Вы ничем не лучше остальных людей, и все вот эти рассказы о том что я делаю свою работу так классно, лучше всех, но директор меня не любит звучат по детски(подучить линуху, ну понятно) и как правило далеки от реальности, незаменимых людей нет, в серьезной компании вас бы вышвырнули сразу.
1. для чего в CProductService аннотации @Transactional над самим классом и методами create и update? Они явно лишние на мой взгляд, что касается метода delete, я не помню его поведение в случае попытки удалить несуществующую сущность, по-моему падает эксепшн — что лучше, 2 раза сходить в БД или ловить эксепшны, вопрос спорный, если у кого есть какие мысли — пишите, мне тоже интересно
2.Хьюстон, тут у нас явно проблемы…
a. Почему findAll()? вытаскивать все продукты из БД и бегать по ним стримом на стороне сервера в будущем будет очень жирно, тем более что уже есть метод productRepository.findByName
b. — весьма странное решение, если вы не собираетесь ничего сортировать, достаточно equals или equalsIgnoreCase
с. создавать массив с 1 элементом чтобы его поменять… примерно тоже самое будет выглядеть как-нибудь вот так:
Но вообще я не понял смысла этого метода т.к. уже есть findByName, и по сигнатуре они похожи:
… можно было сделать что-то вроде:
но ещё короче было бы сделать всё в репозитории с помощью аннотации Query(nativeQuery = true, ...)
3. пункт 1 и 2 актуальны для всех сервисов как оказалось, т.к. там везде примерно одинаково
4. вообще в моей практике пакет с @RestController'ами всегда так и называли — controller, реже — rest… но это уже на ваше предусмотрение, просто resources я ещё не встречал
5. пакеты названы то в единственном числе, то во множественном — нужно единообразие
6. возвращать из контроллеров ResponseEntity.ok нет смысла, они итак будут по-умолчанию 200, если нужны разные статусы, тогда ок, но можно было бы это делать через @ControllerAdvice, т.к. как правило логика примерно одинакова
7. CHomeResource возвращает статику, можно было бы возвращать чистый html из ресурсов
8. в CMViewRepResource
очень странно что вы возвращаете null, когда у вас есть ResponseEntity, можно возвращать код с ошибкой
9. совсем нет логирования
10. JasperReportService не бин, он не будет инжектиться в CMViewRepResource, будет NPE
11. лучше пользоваться интерфейсами, когда пишите сервисы