Initial commit: Complete Software Architecture course with 11 modules
- Added comprehensive course structure with 11 modules - Included theoretical content, practical examples, and tasks - Multi-language code examples (Java, Rust, Node.js, Python) - Detailed analysis of architectural approaches and trade-offs - Complete caching strategies documentation - Architecture examples from real-world systems (Twitter, Netflix, Uber) - Structured navigation and learning path - Ready for educational use
This commit is contained in:
commit
15e744da49
107 files changed
+61762
No files matched your search
@@ -0,0 +1,552 @@
|
||||
# Архитектурные стили и паттерны
|
||||
|
||||
## Навигация
|
||||
- [🏠 Главная страница курса](../../../README.md)
|
||||
- [📚 Модуль 1](../README.md)
|
||||
|
||||
---
|
||||
|
||||
## Монолитная архитектура
|
||||
|
||||
### Определение
|
||||
**Монолитная архитектура** — это архитектурный стиль, при котором все компоненты приложения объединены в единое развертываемое приложение.
|
||||
|
||||
### Характеристики
|
||||
- **Единое развертывание** — все компоненты развертываются вместе
|
||||
- **Общая база данных** — все модули используют одну БД
|
||||
- **Единый технологический стек** — один язык, один фреймворк
|
||||
- **Прямые вызовы** — компоненты вызывают друг друга напрямую
|
||||
|
||||
### Пример реализации
|
||||
```java
|
||||
// Монолитное приложение e-commerce
|
||||
@SpringBootApplication
|
||||
public class EcommerceApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(EcommerceApplication.class, args);
|
||||
}
|
||||
}
|
||||
|
||||
// Все контроллеры в одном приложении
|
||||
@RestController
|
||||
@RequestMapping("/api")
|
||||
public class EcommerceController {
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@Autowired
|
||||
private OrderService orderService;
|
||||
|
||||
@Autowired
|
||||
private PaymentService paymentService;
|
||||
|
||||
@PostMapping("/orders")
|
||||
public ResponseEntity<Order> createOrder(@RequestBody CreateOrderRequest request) {
|
||||
// Вся логика в одном месте
|
||||
User user = userService.findById(request.getUserId());
|
||||
Order order = orderService.createOrder(request);
|
||||
PaymentResult payment = paymentService.processPayment(order);
|
||||
return ResponseEntity.ok(order);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Преимущества
|
||||
- **Простота разработки** — легко начать проект
|
||||
- **Простота тестирования** — все в одном процессе
|
||||
- **Простота развертывания** — один артефакт
|
||||
- **Производительность** — нет сетевых вызовов
|
||||
|
||||
### Недостатки
|
||||
- **Сложность масштабирования** — нужно масштабировать все приложение
|
||||
- **Технологические ограничения** — привязанность к одному стеку
|
||||
- **Риск сбоев** — падение одного компонента влияет на все
|
||||
- **Сложность команд** — команды работают над одним кодом
|
||||
|
||||
## Микросервисная архитектура
|
||||
|
||||
### Определение
|
||||
**Микросервисная архитектура** — это архитектурный стиль, при котором приложение разбивается на множество небольших, независимых сервисов.
|
||||
|
||||
### Характеристики
|
||||
- **Независимые сервисы** — каждый сервис работает автономно
|
||||
- **Отдельные базы данных** — каждый сервис имеет свою БД
|
||||
- **Разные технологии** — сервисы могут использовать разные стеки
|
||||
- **Сетевое взаимодействие** — сервисы общаются по сети
|
||||
|
||||
### Пример реализации
|
||||
```java
|
||||
// User Service
|
||||
@RestController
|
||||
@RequestMapping("/api/users")
|
||||
public class UserController {
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public ResponseEntity<User> getUser(@PathVariable Long id) {
|
||||
return ResponseEntity.ok(userService.findById(id));
|
||||
}
|
||||
}
|
||||
|
||||
// Order Service
|
||||
@RestController
|
||||
@RequestMapping("/api/orders")
|
||||
public class OrderController {
|
||||
@Autowired
|
||||
private OrderService orderService;
|
||||
|
||||
@Autowired
|
||||
private UserServiceClient userServiceClient;
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<Order> createOrder(@RequestBody CreateOrderRequest request) {
|
||||
// Вызов внешнего сервиса
|
||||
User user = userServiceClient.getUser(request.getUserId());
|
||||
Order order = orderService.createOrder(request);
|
||||
return ResponseEntity.ok(order);
|
||||
}
|
||||
}
|
||||
|
||||
// Payment Service
|
||||
@RestController
|
||||
@RequestMapping("/api/payments")
|
||||
public class PaymentController {
|
||||
@Autowired
|
||||
private PaymentService paymentService;
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<PaymentResult> processPayment(@RequestBody PaymentRequest request) {
|
||||
PaymentResult result = paymentService.processPayment(request);
|
||||
return ResponseEntity.ok(result);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Преимущества
|
||||
- **Независимое масштабирование** — каждый сервис масштабируется отдельно
|
||||
- **Технологическое разнообразие** — разные технологии для разных задач
|
||||
- **Независимые команды** — команды работают над разными сервисами
|
||||
- **Отказоустойчивость** — падение одного сервиса не влияет на другие
|
||||
|
||||
### Недостатки
|
||||
- **Сложность разработки** — нужно управлять множеством сервисов
|
||||
- **Сетевая задержка** — вызовы между сервисами медленнее
|
||||
- **Сложность тестирования** — нужно тестировать интеграции
|
||||
- **Сложность развертывания** — нужно координировать развертывание
|
||||
|
||||
## Event-Driven Architecture (EDA)
|
||||
|
||||
### Определение
|
||||
**Event-Driven Architecture** — это архитектурный стиль, основанный на производстве, обнаружении, потреблении и реакции на события.
|
||||
|
||||
### Характеристики
|
||||
- **События** — значимые изменения в системе
|
||||
- **Асинхронность** — события обрабатываются асинхронно
|
||||
- **Слабая связанность** — компоненты не знают друг о друге
|
||||
- **Масштабируемость** — легко добавлять новых потребителей
|
||||
|
||||
### Пример реализации
|
||||
```java
|
||||
// Доменное событие
|
||||
public class OrderCreatedEvent {
|
||||
private final String orderId;
|
||||
private final String customerId;
|
||||
private final BigDecimal amount;
|
||||
private final LocalDateTime occurredOn;
|
||||
|
||||
public OrderCreatedEvent(String orderId, String customerId, BigDecimal amount) {
|
||||
this.orderId = orderId;
|
||||
this.customerId = customerId;
|
||||
this.amount = amount;
|
||||
this.occurredOn = LocalDateTime.now();
|
||||
}
|
||||
|
||||
// Геттеры
|
||||
}
|
||||
|
||||
// Публикация события
|
||||
@Service
|
||||
public class OrderService {
|
||||
|
||||
@Autowired
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
public Order createOrder(CreateOrderRequest request) {
|
||||
Order order = new Order(request);
|
||||
order = orderRepository.save(order);
|
||||
|
||||
// Публикация события
|
||||
eventPublisher.publishEvent(new OrderCreatedEvent(
|
||||
order.getId(),
|
||||
order.getCustomerId(),
|
||||
order.getAmount()
|
||||
));
|
||||
|
||||
return order;
|
||||
}
|
||||
}
|
||||
|
||||
// Обработка события
|
||||
@Component
|
||||
public class OrderCreatedEventHandler {
|
||||
|
||||
@Autowired
|
||||
private InventoryService inventoryService;
|
||||
|
||||
@Autowired
|
||||
private NotificationService notificationService;
|
||||
|
||||
@EventListener
|
||||
public void handleOrderCreated(OrderCreatedEvent event) {
|
||||
// Резервирование товара
|
||||
inventoryService.reserveItems(event.getOrderId());
|
||||
|
||||
// Отправка уведомления
|
||||
notificationService.sendOrderConfirmation(event.getCustomerId());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## CQRS (Command Query Responsibility Segregation)
|
||||
|
||||
### Определение
|
||||
**CQRS** — это паттерн, который разделяет операции чтения и записи данных на разные модели.
|
||||
|
||||
### Характеристики
|
||||
- **Разделение команд и запросов** — разные модели для записи и чтения
|
||||
- **Оптимизация** — модели оптимизированы для своих задач
|
||||
- **Масштабируемость** — можно масштабировать чтение и запись отдельно
|
||||
- **Сложность** — увеличивает сложность системы
|
||||
|
||||
### Пример реализации
|
||||
```java
|
||||
// Command Model (Write)
|
||||
@Entity
|
||||
@Table(name = "orders")
|
||||
public class Order {
|
||||
@Id
|
||||
private String id;
|
||||
private String customerId;
|
||||
private OrderStatus status;
|
||||
private BigDecimal amount;
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
// Методы для изменения состояния
|
||||
public void confirm() {
|
||||
this.status = OrderStatus.CONFIRMED;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
this.status = OrderStatus.CANCELLED;
|
||||
}
|
||||
}
|
||||
|
||||
// Query Model (Read)
|
||||
@Entity
|
||||
@Table(name = "order_summaries")
|
||||
public class OrderSummary {
|
||||
@Id
|
||||
private String id;
|
||||
private String customerName;
|
||||
private String customerEmail;
|
||||
private OrderStatus status;
|
||||
private BigDecimal amount;
|
||||
private LocalDateTime createdAt;
|
||||
private int itemCount;
|
||||
|
||||
// Только геттеры для чтения
|
||||
}
|
||||
|
||||
// Command Handler
|
||||
@Service
|
||||
public class OrderCommandHandler {
|
||||
|
||||
@Autowired
|
||||
private OrderRepository orderRepository;
|
||||
|
||||
@Autowired
|
||||
private OrderSummaryRepository orderSummaryRepository;
|
||||
|
||||
public void handle(CreateOrderCommand command) {
|
||||
// Создание заказа
|
||||
Order order = new Order(command);
|
||||
orderRepository.save(order);
|
||||
|
||||
// Обновление read model
|
||||
OrderSummary summary = new OrderSummary(order);
|
||||
orderSummaryRepository.save(summary);
|
||||
}
|
||||
}
|
||||
|
||||
// Query Handler
|
||||
@Service
|
||||
public class OrderQueryHandler {
|
||||
|
||||
@Autowired
|
||||
private OrderSummaryRepository orderSummaryRepository;
|
||||
|
||||
public List<OrderSummary> handle(GetOrdersQuery query) {
|
||||
return orderSummaryRepository.findByCustomerId(query.getCustomerId());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Hexagonal Architecture (Ports and Adapters)
|
||||
|
||||
### Определение
|
||||
**Hexagonal Architecture** — это архитектурный паттерн, который изолирует бизнес-логику от внешних зависимостей.
|
||||
|
||||
### Характеристики
|
||||
- **Порты** — интерфейсы для взаимодействия с внешним миром
|
||||
- **Адаптеры** — реализации портов для конкретных технологий
|
||||
- **Изоляция** — бизнес-логика не зависит от внешних технологий
|
||||
- **Тестируемость** — легко тестировать с mock-объектами
|
||||
|
||||
### Пример реализации
|
||||
```java
|
||||
// Domain Layer (внутренний круг)
|
||||
public class Order {
|
||||
private String id;
|
||||
private String customerId;
|
||||
private OrderStatus status;
|
||||
private BigDecimal amount;
|
||||
|
||||
public void confirm() {
|
||||
this.status = OrderStatus.CONFIRMED;
|
||||
}
|
||||
}
|
||||
|
||||
// Ports (интерфейсы)
|
||||
public interface OrderRepository {
|
||||
void save(Order order);
|
||||
Optional<Order> findById(String id);
|
||||
}
|
||||
|
||||
public interface PaymentService {
|
||||
PaymentResult processPayment(PaymentRequest request);
|
||||
}
|
||||
|
||||
public interface NotificationService {
|
||||
void sendNotification(String recipient, String message);
|
||||
}
|
||||
|
||||
// Application Layer
|
||||
@Service
|
||||
public class OrderService {
|
||||
private final OrderRepository orderRepository;
|
||||
private final PaymentService paymentService;
|
||||
private final NotificationService notificationService;
|
||||
|
||||
public OrderService(OrderRepository orderRepository,
|
||||
PaymentService paymentService,
|
||||
NotificationService notificationService) {
|
||||
this.orderRepository = orderRepository;
|
||||
this.paymentService = paymentService;
|
||||
this.notificationService = notificationService;
|
||||
}
|
||||
|
||||
public void processOrder(Order order) {
|
||||
// Бизнес-логика
|
||||
order.confirm();
|
||||
orderRepository.save(order);
|
||||
|
||||
// Внешние сервисы через порты
|
||||
PaymentResult payment = paymentService.processPayment(
|
||||
new PaymentRequest(order.getAmount())
|
||||
);
|
||||
|
||||
if (payment.isSuccess()) {
|
||||
notificationService.sendNotification(
|
||||
order.getCustomerId(),
|
||||
"Order confirmed"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Adapters (внешний круг)
|
||||
@Repository
|
||||
public class JpaOrderRepository implements OrderRepository {
|
||||
@Override
|
||||
public void save(Order order) {
|
||||
// JPA реализация
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Order> findById(String id) {
|
||||
// JPA реализация
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Component
|
||||
public class StripePaymentService implements PaymentService {
|
||||
@Override
|
||||
public PaymentResult processPayment(PaymentRequest request) {
|
||||
// Stripe API реализация
|
||||
return new PaymentResult(true, "Payment processed");
|
||||
}
|
||||
}
|
||||
|
||||
@Component
|
||||
public class EmailNotificationService implements NotificationService {
|
||||
@Override
|
||||
public void sendNotification(String recipient, String message) {
|
||||
// Email реализация
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Layered Architecture
|
||||
|
||||
### Определение
|
||||
**Layered Architecture** — это архитектурный паттерн, который организует код в горизонтальные слои.
|
||||
|
||||
### Слои
|
||||
1. **Presentation Layer** — пользовательский интерфейс
|
||||
2. **Application Layer** — бизнес-логика приложения
|
||||
3. **Domain Layer** — доменная логика
|
||||
4. **Infrastructure Layer** — внешние зависимости
|
||||
|
||||
### Пример реализации
|
||||
```java
|
||||
// Presentation Layer
|
||||
@RestController
|
||||
@RequestMapping("/api/orders")
|
||||
public class OrderController {
|
||||
|
||||
@Autowired
|
||||
private OrderApplicationService orderService;
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<OrderResponse> createOrder(@RequestBody CreateOrderRequest request) {
|
||||
OrderResponse response = orderService.createOrder(request);
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
}
|
||||
|
||||
// Application Layer
|
||||
@Service
|
||||
public class OrderApplicationService {
|
||||
|
||||
@Autowired
|
||||
private OrderRepository orderRepository;
|
||||
|
||||
@Autowired
|
||||
private PaymentService paymentService;
|
||||
|
||||
public OrderResponse createOrder(CreateOrderRequest request) {
|
||||
// Применение бизнес-правил
|
||||
Order order = new Order(request);
|
||||
|
||||
// Обработка платежа
|
||||
PaymentResult payment = paymentService.processPayment(order);
|
||||
|
||||
if (payment.isSuccess()) {
|
||||
order.confirm();
|
||||
orderRepository.save(order);
|
||||
}
|
||||
|
||||
return OrderResponse.fromOrder(order);
|
||||
}
|
||||
}
|
||||
|
||||
// Domain Layer
|
||||
public class Order {
|
||||
private String id;
|
||||
private String customerId;
|
||||
private OrderStatus status;
|
||||
private BigDecimal amount;
|
||||
|
||||
public void confirm() {
|
||||
if (this.status != OrderStatus.DRAFT) {
|
||||
throw new IllegalStateException("Cannot confirm non-draft order");
|
||||
}
|
||||
this.status = OrderStatus.CONFIRMED;
|
||||
}
|
||||
}
|
||||
|
||||
// Infrastructure Layer
|
||||
@Repository
|
||||
public class JpaOrderRepository implements OrderRepository {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Override
|
||||
public void save(Order order) {
|
||||
entityManager.persist(order);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Serverless Architecture
|
||||
|
||||
### Определение
|
||||
**Serverless Architecture** — это архитектурный стиль, при котором приложение состоит из функций, которые выполняются в ответ на события.
|
||||
|
||||
### Характеристики
|
||||
- **FaaS** — Functions as a Service
|
||||
- **Event-driven** — функции запускаются по событиям
|
||||
- **Auto-scaling** — автоматическое масштабирование
|
||||
- **Pay-per-use** — оплата только за использование
|
||||
|
||||
### Пример реализации
|
||||
```java
|
||||
// AWS Lambda функция
|
||||
public class OrderProcessor implements RequestHandler<OrderEvent, String> {
|
||||
|
||||
@Override
|
||||
public String handleRequest(OrderEvent event, Context context) {
|
||||
// Обработка заказа
|
||||
Order order = processOrder(event);
|
||||
|
||||
// Отправка уведомления
|
||||
sendNotification(order);
|
||||
|
||||
return "Order processed successfully";
|
||||
}
|
||||
|
||||
private Order processOrder(OrderEvent event) {
|
||||
// Логика обработки заказа
|
||||
return new Order(event);
|
||||
}
|
||||
|
||||
private void sendNotification(Order order) {
|
||||
// Отправка уведомления
|
||||
}
|
||||
}
|
||||
|
||||
// Azure Functions
|
||||
@FunctionName("ProcessOrder")
|
||||
public String processOrder(
|
||||
@HttpTrigger(name = "req", methods = {HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS)
|
||||
HttpRequestMessage<Optional<String>> request,
|
||||
ExecutionContext context) {
|
||||
|
||||
String orderData = request.getBody().orElse("");
|
||||
|
||||
// Обработка заказа
|
||||
Order order = processOrderData(orderData);
|
||||
|
||||
return "Order processed: " + order.getId();
|
||||
}
|
||||
```
|
||||
|
||||
## Выбор архитектурного стиля
|
||||
|
||||
### Факторы выбора
|
||||
1. **Размер команды** — маленькая команда → монолит
|
||||
2. **Сложность домена** — сложный домен → микросервисы
|
||||
3. **Требования к масштабированию** — высокие → микросервисы
|
||||
4. **Технологическое разнообразие** — разные технологии → микросервисы
|
||||
5. **Время разработки** — быстрое время → монолит
|
||||
|
||||
### Рекомендации
|
||||
- **Начните с монолита** — для большинства проектов
|
||||
- **Переходите к микросервисам** — когда монолит становится проблемой
|
||||
- **Используйте EDA** — для асинхронной обработки
|
||||
- **Рассмотрите CQRS** — для сложных read/write требований
|
||||
- **Применяйте Hexagonal** — для изоляции бизнес-логики
|
||||
Reference in new issue
Block a user