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:
Alexander Abakumov committed 2025-09-09 22:08:07 +03:00
commit 15e744da49
107 files changed
+61762

No files matched your search

@@ -0,0 +1,280 @@
# Architecture Decision Records (ADR)
## Навигация
- [🏠 Главная страница курса](../../../README.md)
- [📚 Модуль 7](../README.md)
---
## Что такое ADR
**Architecture Decision Record (ADR)** — документ, который фиксирует важное архитектурное решение, принятое в проекте.
## Структура ADR
### 1. Статус
- **Proposed** — предложено
- **Accepted** — принято
- **Deprecated** — устарело
- **Superseded** — заменено
### 2. Контекст
- Описание ситуации
- Проблема, которую нужно решить
- Ограничения и требования
### 3. Решение
- Описание принятого решения
- Обоснование выбора
- Альтернативы, которые рассматривались
### 4. Последствия
- Положительные последствия
- Отрицательные последствия
- Риски и митигации
## Пример ADR
**Технический пример - Advanced ADR Management:**
```markdown
# ADR-001: Использование микросервисной архитектуры
## Статус
Принято
## Дата
2024-01-15
## Контекст
Наша система электронной коммерции растет и становится сложнее. Монолитная архитектура создает следующие проблемы:
- Сложность развертывания изменений
- Технологическая привязка к одному стеку
- Сложность масштабирования отдельных компонентов
- Риск каскадных отказов
Команда разработки увеличилась до 15 человек, и мы планируем дальнейший рост.
## Решение
Мы решили перейти к микросервисной архитектуре со следующими принципами:
- Каждый сервис отвечает за один бизнес-домен
- Сервисы независимо развертываются
- Сервисы имеют собственные базы данных
- Коммуникация через REST API и события
## Альтернативы
1. **Модульный монолит** — разделение на модули внутри одного приложения
2. **SOA** — сервисно-ориентированная архитектура
3. **Оставить монолит** — продолжить развитие текущей архитектуры
## Последствия
### Положительные
- Независимое развертывание сервисов
- Возможность использования разных технологий
- Лучшая масштабируемость
- Изоляция отказов
### Отрицательные
- Увеличение сложности системы
- Проблемы с распределенными транзакциями
- Сложность мониторинга
- Overhead коммуникации
### Риски
- **Сложность отладки** — митигация через distributed tracing
- **Проблемы с данными** — митигация через event sourcing
- **Сетевые задержки** — митигация через кэширование
## Реализация
- Начать с выделения User Service
- Использовать API Gateway для маршрутизации
- Настроить мониторинг и логирование
- Постепенно выделять остальные сервисы
## Метрики успеха
- Время развертывания: < 5 минут
- Время восстановления: < 30 минут
- Доступность: > 99.9%
- Производительность: P95 < 200ms
```
**Технический пример - ADR Management System:**
```java
// ADR Management Service
@Service
public class ADRManagementService {
@Autowired
private ADRRepository adrRepository;
@Autowired
private NotificationService notificationService;
@Autowired
private VersionControlService versionControlService;
public ADR createADR(CreateADRRequest request) {
// Валидация
validateADRRequest(request);
// Создание ADR
ADR adr = ADR.builder()
.id(generateADRId())
.title(request.getTitle())
.status(ADRStatus.PROPOSED)
.context(request.getContext())
.decision(request.getDecision())
.alternatives(request.getAlternatives())
.consequences(request.getConsequences())
.author(request.getAuthor())
.createdDate(LocalDateTime.now())
.build();
// Сохранение в БД
adr = adrRepository.save(adr);
// Создание файла в Git
createADRFile(adr);
// Уведомление команды
notifyTeamAboutNewADR(adr);
return adr;
}
public ADR updateADRStatus(Long adrId, ADRStatus newStatus, String comment) {
ADR adr = adrRepository.findById(adrId)
.orElseThrow(() -> new ADRNotFoundException("ADR not found"));
// Проверяем права на изменение статуса
validateStatusChangePermission(adr, newStatus);
// Обновляем статус
adr.setStatus(newStatus);
adr.setLastModified(LocalDateTime.now());
adr.setStatusComment(comment);
adr = adrRepository.save(adr);
// Обновляем файл в Git
updateADRFile(adr);
// Уведомляем команду об изменении
notifyTeamAboutStatusChange(adr);
return adr;
}
public List<ADR> getADRsByStatus(ADRStatus status) {
return adrRepository.findByStatus(status);
}
public List<ADR> getADRsByDomain(String domain) {
return adrRepository.findByDomain(domain);
}
public ADRImpactAnalysis analyzeImpact(Long adrId) {
ADR adr = adrRepository.findById(adrId)
.orElseThrow(() -> new ADRNotFoundException("ADR not found"));
return ADRImpactAnalysis.builder()
.affectedServices(analyzeAffectedServices(adr))
.requiredChanges(analyzeRequiredChanges(adr))
.estimatedEffort(estimateEffort(adr))
.risks(identifyRisks(adr))
.build();
}
@Scheduled(cron = "0 0 9 * * MON") // Каждый понедельник в 9:00
public void reviewADRs() {
List<ADR> proposedADRs = getADRsByStatus(ADRStatus.PROPOSED);
for (ADR adr : proposedADRs) {
if (isADRStale(adr)) {
notifyTeamAboutStaleADR(adr);
}
}
// Генерируем отчет по ADR
generateADRReport();
}
private void createADRFile(ADR adr) {
String fileName = String.format("adr/%04d-%s.md", adr.getId(),
adr.getTitle().toLowerCase().replaceAll("\\s+", "-"));
String content = generateADRMarkdown(adr);
versionControlService.createFile(fileName, content,
String.format("Add ADR-%d: %s", adr.getId(), adr.getTitle()));
}
private void updateADRFile(ADR adr) {
String fileName = String.format("adr/%04d-%s.md", adr.getId(),
adr.getTitle().toLowerCase().replaceAll("\\s+", "-"));
String content = generateADRMarkdown(adr);
versionControlService.updateFile(fileName, content,
String.format("Update ADR-%d: %s", adr.getId(), adr.getTitle()));
}
private String generateADRMarkdown(ADR adr) {
StringBuilder markdown = new StringBuilder();
markdown.append(String.format("# ADR-%d: %s\n\n", adr.getId(), adr.getTitle()));
markdown.append("## Статус\n");
markdown.append(adr.getStatus().getDisplayName()).append("\n\n");
markdown.append("## Дата\n");
markdown.append(adr.getCreatedDate().format(DateTimeFormatter.ISO_LOCAL_DATE)).append("\n\n");
markdown.append("## Контекст\n");
markdown.append(adr.getContext()).append("\n\n");
markdown.append("## Решение\n");
markdown.append(adr.getDecision()).append("\n\n");
markdown.append("## Альтернативы\n");
markdown.append(adr.getAlternatives()).append("\n\n");
markdown.append("## Последствия\n");
markdown.append(adr.getConsequences()).append("\n\n");
if (adr.getStatusComment() != null) {
markdown.append("## Комментарии\n");
markdown.append(adr.getStatusComment()).append("\n\n");
}
return markdown.toString();
}
}
```
## Лучшие практики ADR
### 1. Ведите ADR для всех важных решений
- Технологические решения
- Архитектурные паттерны
- Интеграционные решения
- Операционные решения
### 2. Обновляйте статус ADR
- Отслеживайте изменения
- Документируйте причины изменений
- Архивируйте устаревшие ADR
### 3. Используйте шаблоны
- Стандартизируйте структуру
- Обеспечивайте консистентность
- Упрощайте создание новых ADR
## Заключение
ADR являются важным инструментом документирования архитектурных решений:
1. **Фиксация решений** — записывают важные архитектурные выборы
2. **Контекст и обоснование** — объясняют почему было принято решение
3. **Отслеживание изменений** — показывают эволюцию архитектуры
4. **Обучение команды** — помогают новым участникам понять решения
Правильное ведение ADR значительно улучшает понимание архитектуры проекта и облегчает принятие будущих решений.