Какие знаешь архитектурные паттерны в Spring?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Архитектурные паттерны в Spring
Spring Framework поддерживает и применяет множество архитектурных паттернов, которые помогают организовать код и построить масштабируемые приложения. Рассмотрим основные архитектурные паттерны, используемые в Spring.
1. Dependency Injection (DI) паттерн
Dependency Injection — основной паттерн Spring, позволяющий создавать слабо связанный код. Spring контейнер управляет созданием и внедрением зависимостей.
import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Autowired;
@Component
public class UserRepository {
public User findById(Long id) {
return new User(id, "John");
}
}
@Component
public class UserService {
private final UserRepository repository;
@Autowired
public UserService(UserRepository repository) {
this.repository = repository;
}
public User getUser(Long id) {
return repository.findById(id);
}
}
2. Inversion of Control (IoC) паттерн
Inversion of Control — паттерн, при котором Spring контейнер берёт на себя управление жизненным циклом объектов вместо приложения.
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Bean;
@Configuration
public class AppConfig {
@Bean
public UserRepository userRepository() {
return new UserRepository();
}
@Bean
public UserService userService(UserRepository repository) {
return new UserService(repository);
}
}
public class Main {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserService service = context.getBean(UserService.class);
service.getUser(1L);
}
}
3. Layered Architecture (многоуровневая архитектура)
Layered Architecture — разделение приложения на слои: Presentation, Business Logic, Persistence, Database.
// Presentation Layer (Controller)
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/users/{id}")
public UserDTO getUser(Long id) {
return userService.getUserDTO(id);
}
}
// Business Logic Layer (Service)
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final UserRepository repository;
public UserService(UserRepository repository) {
this.repository = repository;
}
public UserDTO getUserDTO(Long id) {
User user = repository.findById(id);
return new UserDTO(user.getId(), user.getName());
}
}
// Persistence Layer (Repository)
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
4. Domain-Driven Design (DDD) паттерн
Domain-Driven Design — проектирование на основе предметной области, отделение бизнес-логики от технических деталей.
// Domain Entity
public class User {
private Long id;
private String name;
private String email;
public User(Long id, String name, String email) {
this.id = id;
this.name = name;
this.email = email;
}
public boolean isValidEmail() {
return email.contains("@");
}
}
// Domain Service
import org.springframework.stereotype.Service;
@Service
public class UserDomainService {
public void registerUser(User user) {
if (!user.isValidEmail()) {
throw new IllegalArgumentException("Invalid email");
}
}
}
// Application Service
import org.springframework.stereotype.Service;
@Service
public class UserApplicationService {
private final UserRepository repository;
private final UserDomainService domainService;
public UserApplicationService(UserRepository repository, UserDomainService domainService) {
this.repository = repository;
this.domainService = domainService;
}
public void register(User user) {
domainService.registerUser(user);
repository.save(user);
}
}
5. MVC (Model-View-Controller) паттерн
MVC — разделение приложения на три компонента: модель, представление и контроллер.
// Model
public class User {
private Long id;
private String name;
}
// Controller
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class UserController {
private final UserService userService;
@GetMapping("/user/{id}")
public String getUser(Long id, Model model) {
User user = userService.findById(id);
model.addAttribute("user", user);
return "user-detail"; // View name
}
}
// View (user-detail.html)
/*
<html>
<body>
<h1>User: [[${user.name}]]</h1>
</body>
</html>
*/
6. SOLID принципы в Spring
SOLID — набор принципов для написания хорошего кода:
// Single Responsibility Principle
@Service
public class UserValidationService {
public boolean isValidEmail(String email) {
return email.contains("@");
}
}
// Open/Closed Principle
public interface UserNotifier {
void notify(User user);
}
@Component
public class EmailNotifier implements UserNotifier {
@Override
public void notify(User user) {
System.out.println("Email sent to " + user.getEmail());
}
}
@Component
public class SmsNotifier implements UserNotifier {
@Override
public void notify(User user) {
System.out.println("SMS sent to " + user.getPhone());
}
}
// Liskov Substitution Principle
@Service
public class NotificationService {
private final List<UserNotifier> notifiers;
public void notifyUser(User user) {
for (UserNotifier notifier : notifiers) {
notifier.notify(user);
}
}
}
// Dependency Inversion Principle
@Service
public class UserRegistrationService {
private final UserRepository repository;
private final UserValidationService validationService;
public UserRegistrationService(UserRepository repository, UserValidationService validationService) {
this.repository = repository;
this.validationService = validationService;
}
}
7. Hexagonal Architecture (Ports & Adapters)
Hexagonal Architecture — бизнес-логика в центре, все внешние системы подключаются через адаптеры.
// Core Domain
public class Order {
private Long id;
private List<Item> items;
public BigDecimal calculateTotal() {
return items.stream()
.map(Item::getPrice)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
}
// Port (Interface)
public interface PaymentPort {
void charge(BigDecimal amount);
}
// Adapter (Implementation)
import org.springframework.stereotype.Component;
@Component
public class StripePaymentAdapter implements PaymentPort {
@Override
public void charge(BigDecimal amount) {
System.out.println("Charging " + amount + " via Stripe");
}
}
// Application Service
import org.springframework.stereotype.Service;
@Service
public class OrderService {
private final PaymentPort paymentPort;
public OrderService(PaymentPort paymentPort) {
this.paymentPort = paymentPort;
}
public void processOrder(Order order) {
BigDecimal total = order.calculateTotal();
paymentPort.charge(total);
}
}
8. Microservices архитектура
Microservices — разделение приложения на независимые сервисы, взаимодействующие между собой.
// Spring Boot Microservice
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class UserMicroservice {
public static void main(String[] args) {
SpringApplication.run(UserMicroservice.class, args);
}
}
// Service с REST API
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@RestController
public class UserRestController {
private final UserService userService;
@PostMapping("/api/users")
public UserDTO createUser(@RequestBody CreateUserRequest request) {
return userService.create(request);
}
}
Сравнение архитектурных паттернов
| Паттерн | Назначение | Сложность |
|---|---|---|
| Layered | Базовая структура приложения | Низкая |
| DDD | Сложные бизнес-домены | Высокая |
| Hexagonal | Отделение бизнес-логики | Средняя |
| Microservices | Масштабируемые системы | Высокая |
| MVC | Веб-приложения | Низкая |
Рекомендации
- Используйте DI и IoC как основу
- Применяйте Layered Architecture для стандартных приложений
- Переходите к DDD для сложных бизнес-логик
- Рассмотрите Hexagonal Architecture для большей гибкости
- Используйте Microservices только когда действительно нужна масштабируемость