После проведенного голосования, определилась тема для рассмотрения в выходные - MVC.
Приступим'с
Архитектурный шаблон MVC в Java Spring: теория, правила, ошибки
MVC (Model–View–Controller) — это один из фундаментальных архитектурных паттернов в программной инженерии, направленный на разделение приложения на логически независимые компоненты. Его основная цель — изолировать пользовательский интерфейс от бизнес-логики и доступа к данным. В экосистеме Java фреймворк Spring реализует этот шаблон через модуль Spring MVC.
Теория: что такое MVC
Шаблон MVC подразумевает разделение приложения на три слоя:
Model (Модель)
Модель инкапсулирует бизнес-логику и данные приложения. Она может включать:
Сущности базы данных (например, классы с аннотацией @Entity).
Репозитории (@Repository), обеспечивающие доступ к данным.
Сервисный слой (@Service), реализующий бизнес-логику.
DTO (Data Transfer Objects) — объекты для обмена данными между слоями.
View (Представление)
Представление отвечает за отображение информации пользователю. В Spring это обычно:
HTML-шаблоны (например, на Thymeleaf).
JSON-ответы (в случае REST API).
Альтернативные форматы (XML, PDF и пр.).
View должен быть как можно более простым и не содержать бизнес-логики.
Controller (Контроллер)
Контроллер — связующее звено между внешним миром (HTTP-запросами) и внутренними слоями приложения. Он:
Принимает входные данные.
Делегирует выполнение модели.
Выбирает и возвращает подходящее представление.
Контроллеры в Spring создаются с помощью аннотаций @Controller или @RestController.
Жизненный цикл HTTP-запроса в Spring MVC
Роль слоёв в приложении Spring
Контроллер
Контроллер должен быть «тонким» и не содержать бизнес-логики. Его задача — маршрутизировать запросы и собирать данные, необходимые представлению.
Пример (корректный):
@GetMapping("/users")
public List<UserDto> getUsers(Model model) {
return userService.getAllUsers();
}
Неправильный пример (контроллер содержит логику):
@GetMapping("/users")
public List<UserDto> getUsers(Model model) {
List<User> users = userRepository.findAll();
return users.stream()
.map(user -> new UserDto(user.getId(), user.getName()))
.collect(Collectors.toList());
}
Сервисный слой
Сервисный слой содержит бизнес-логику, правила обработки данных, валидацию, логи, обработку ошибок. Он изолирован от HTTP и представления. Сервисы не должны напрямую зависеть от Model, HttpServletRequest или аннотаций Spring MVC.
Пример:
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public List<UserDto> getAllUsers() {
return userRepository.findAll().stream()
.map(user -> new UserDto(user.getId(), user.getName()))
.collect(Collectors.toList());
}
}
Репозиторий
Репозиторий отвечает за доступ к данным. Он инкапсулирует работу с базой и предоставляет CRUD-интерфейс.
public interface UserRepository extends JpaRepository<User, Long> {}
#Java #для_новичков #beginner #on_request #mvc
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
May 31
Распространённые ошибки
1. Логика в контроллерах
Признак: контроллер становится "сервисом", содержащим условия, циклы, доступ к БД. Это нарушает принципы чистой архитектуры и усложняет тестирование.
2. Использование Entity в представлении
Передача @Entity напрямую в шаблон может привести к:
Утечке данных (например, паролей).
Ошибкам LazyInitializationException.
Сильной связанности представления с базой данных.
Решение: использовать DTO или ViewModel.
3. Жёсткая связность между слоями
View не должно зависеть от Repository, а Controller — от Entity. Каждый слой должен взаимодействовать только с соседним.
4. Отсутствие DTO
Использование одной и той же модели во всех сценариях ведёт к путанице и проблемам безопасности. Лучше использовать отдельные классы:
UserCreateRequest
UserResponse
UserUpdateRequest
Рекомендации по проектированию
Структура проекта
Хорошей практикой является разделение кода по слоям:
URL-дизайн
Соблюдайте RESTful-стиль:
GET /users — получить список пользователей.
GET /users/{id} — получить конкретного пользователя.
POST /users — создать.
PUT /users/{id} — обновить.
DELETE /users/{id} — удалить.
Использование DTO
Расширения и адаптации MVC
SPA + API
При использовании Vue, React или Angular, представление полностью переносится на фронтенд. В этом случае Spring работает как REST API с @RestController, и классическая схема MVC трансформируется в «REST + JSON».
Поддержка реактивности
Spring WebFlux реализует неблокирующую модель с Mono и Flux, сохраняя при этом логическую структуру MVC. Подходит для высоконагруженных и асинхронных приложений.
Тестирование компонентов MVC
Контроллеры — @WebMvcTest, MockMvc.
Сервисы — @SpringBootTest или с моками (@MockBean).
Репозитории — @DataJpaTest.
#Java #для_новичков #beginner #on_request #mvc
1. Логика в контроллерах
Признак: контроллер становится "сервисом", содержащим условия, циклы, доступ к БД. Это нарушает принципы чистой архитектуры и усложняет тестирование.
2. Использование Entity в представлении
Передача @Entity напрямую в шаблон может привести к:
Утечке данных (например, паролей).
Ошибкам LazyInitializationException.
Сильной связанности представления с базой данных.
Решение: использовать DTO или ViewModel.
3. Жёсткая связность между слоями
View не должно зависеть от Repository, а Controller — от Entity. Каждый слой должен взаимодействовать только с соседним.
4. Отсутствие DTO
Использование одной и той же модели во всех сценариях ведёт к путанице и проблемам безопасности. Лучше использовать отдельные классы:
UserCreateRequest
UserResponse
UserUpdateRequest
Рекомендации по проектированию
Структура проекта
Хорошей практикой является разделение кода по слоям:
com.example.myapp
├── controller
├── service
│ └── impl
├── repository
├── dto
├── model
├── config
URL-дизайн
Соблюдайте RESTful-стиль:
GET /users — получить список пользователей.
GET /users/{id} — получить конкретного пользователя.
POST /users — создать.
PUT /users/{id} — обновить.
DELETE /users/{id} — удалить.
Использование DTO
public class UserResponse {
private Long id;
private String name;
}
public class UserCreateRequest {
private String name;
private String email;
}
Расширения и адаптации MVC
SPA + API
При использовании Vue, React или Angular, представление полностью переносится на фронтенд. В этом случае Spring работает как REST API с @RestController, и классическая схема MVC трансформируется в «REST + JSON».
Поддержка реактивности
Spring WebFlux реализует неблокирующую модель с Mono и Flux, сохраняя при этом логическую структуру MVC. Подходит для высоконагруженных и асинхронных приложений.
Тестирование компонентов MVC
Контроллеры — @WebMvcTest, MockMvc.
Сервисы — @SpringBootTest или с моками (@MockBean).
Репозитории — @DataJpaTest.
#Java #для_новичков #beginner #on_request #mvc
👍5
May 31