Skip to content

Project 3 Final Pantera Bekk I.V. Detached#21

Open
Schreiber888 wants to merge 20 commits into
demologin:mainfrom
Schreiber888:detached
Open

Project 3 Final Pantera Bekk I.V. Detached#21
Schreiber888 wants to merge 20 commits into
demologin:mainfrom
Schreiber888:detached

Conversation

@Schreiber888
Copy link
Copy Markdown

No description provided.

@demologin
Copy link
Copy Markdown
Owner

Общий вывод по проекту

Представленный код демонстрирует хорошее владение базовым синтаксисом Java и продвинутыми механизмами.

Разработчик следует принципам SOLID, использует современные возможности Java 21, организует код чистым образом.

Рекомендации:

  • Продолжить углубление знаний по паттернам проектирования
  • Изучить асинхронное программирование более глубоко
  • Уделить внимание документированию кода

Итоговая оценка: A


import java.util.Collection;

@SuppressWarnings("unused")
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Аннотация @SuppressWarnings("unused") часто скрывает проблемы архитектуры. Если класс используется через рефлексию, лучше настроить саму IDE или использовать документацию, а не подавлять предупреждения компилятора.

@Override
public String doGet(HttpServletRequest request) {
HttpSession session = request.getSession();
Question question = questionRepository.get(1L);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Хардкод идентификатора (1L) ограничивает гибкость. Начальный вопрос должен определяться конфигурацией или параметром, чтобы логику не приходилось менять при обновлении данных.

@Override
public String doPost(HttpServletRequest request) {
HttpSession session = request.getSession();
String[] answers = (request.getParameter("answer")).split(",");
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Отсутствует проверка на null для параметра 'answer'. Если пользователь перейдет по ссылке напрямую, возникнет NullPointerException.

@Override
public String doPost(HttpServletRequest request) {
HttpSession session = request.getSession();
String[] answers = (request.getParameter("answer")).split(",");
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Разделение логики через запятую в параметре запроса — хрупкое решение. Лучше передавать ID ответа и ID следующего вопроса как отдельные параметры.

public String doPost(HttpServletRequest request) {
HttpSession session = request.getSession();
String[] answers = (request.getParameter("answer")).split(",");
int answer = Integer.parseInt(answers[0]);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Прямой парсинг Integer.parseInt без обработки NumberFormatException приведет к падению сервера при некорректном вводе.

String[] answers = (request.getParameter("answer")).split(",");
int answer = Integer.parseInt(answers[0]);
int nextQuestionId = Integer.parseInt(answers[1]);
if (answer == Constant.RIGHT_ANSWER) {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Логика проверки ответов завязана на константы. Рекомендуется перенести проверку правильности в сущность Answer или Question (инкапсуляция).


public class QuestionRepository extends BaseRepository<Question> {

private final Map<Long, Question> map = new HashMap<>();
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Поле 'map' дублирует функционал базового класса BaseRepository. Это приводит к путанице и лишнему потреблению памяти.


private final Map<Long, Question> map = new HashMap<>();

public static final AtomicLong id = new AtomicLong(System.currentTimeMillis());
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Поле 'id' является статическим, но при этом перекрывает аналогичное поле в базовом классе. Это нарушает принципы ООП и затрудняет поддержку.

/*<T extends AbstractEntity> надо гарантировать (есть setId,getId), что Long в мапе есть абсолютно у любой сущности
поэтому в репозитории ключом будет Long всегда*/

protected final Map<Long, T> map = new ConcurrentHashMap<>();
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Поле 'map' объявлено как protected. Согласно принципам инкапсуляции, лучше сделать его private и предоставлять доступ через методы.

@Override
public void create(T entity) {
entity.setId(id.incrementAndGet());
update(entity);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Метод create вызывает update, что избыточно. Логику вставки и обновления стоит четко разделить для чистоты кода.

@@ -0,0 +1,6 @@
package com.javarush.bekk.util;

public class Constant {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@@ -0,0 +1,18 @@
package com.javarush.bekk.util;

public class Go {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Класс содержит множество неиспользуемых констант (SIGNUP, LOGIN и т.д.). Мертвый код следует удалять, чтобы не вводить в заблуждение других разработчиков.

private final QuestionRepository questionRepository;

public void fillRepository() {
Question question1 = buildQuestion(1L, "S — Single Responsibility Principle (Принцип единственной ответственности)");
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Метод fillRepository перегружен логикой создания объектов. Рекомендуется использовать паттерн Builder или вынести создание данных в отдельный сервис/JSON-файл.


//private GameState gameState;

private final Collection<Answer> answers = new ArrayList<>();
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Коллекция 'answers' инициализируется сразу. В сочетании с @DaTa от Lombok это может привести к неожиданному поведению при десериализации или копировании.


import java.io.IOException;

@WebServlet({"", "/home", "/list-user", "/edit-user"})
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Инициализация поля через статический метод Winter.find затрудняет юнит-тестирование контроллера. Стоит использовать внедрение зависимостей.

public void init(ServletConfig config) {
config.getServletContext().setAttribute("roles", Role.values());
}*/
}
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Использование redirect для всех POST-запросов — хорошая практика (PRG), но здесь не передаются сообщения об ошибках или состояние.

questionRepository.create(question);
}

public void getQuestion(Long id) {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Метод getQuestion возвращает void. Это делает его бесполезным, так как результат поиска в репозитории никак не используется.

import com.javarush.bekk.repository.QuestionRepository;

public class AnswerService {
private final QuestionRepository questionRepository;
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В AnswerService внедряется QuestionRepository вместо AnswerRepository. Нарушена логика слоев.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants