/
evsyukov.s
/
DiceGame
Обзор
Документация
Войти
/
evsyukov.s
/
DiceGame
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
src/DicePoker.Core/Services/RecordsManagementService.cs
114 строк
6 KB
evsyukov.s
Декомпозиция файла Program.cs
20 дек 2025, 02:54
20 дек 2025, 02:54
56ab8a4
Код
Авторство
О чём код?
using DicePoker.Core.Data.Abstractions; namespace DicePoker.Core.Services { /// <summary> /// Сервис для управления таблицей рекордов (бизнес-логика уровня сервисов). /// Использует репозиторий IRecordsRepository для абстракции работы с хранилищем. /// Реализует бизнес-логику: сортировка рекордов, фильтрация Top-N, расчет статистики. /// </summary> /// <remarks> /// Конструктор, инициализирует сервис с указанным репозиторием и количеством рекордов в топе. /// </remarks> public sealed class RecordsManagementService(IRecordsRepository repository, int topCount = 10) { /// <summary>Репозиторий для работы с хранилищем рекордов</summary> private readonly IRecordsRepository _repository = repository ?? throw new ArgumentNullException(nameof(repository)); /// <summary>Количество записей в топ-N рекордов (по умолчанию 10)</summary> private readonly int _topCount = topCount > 0 ? topCount : throw new ArgumentOutOfRangeException(nameof(topCount)); /// <summary> /// Функция, получает топ-N рекордов с применением бизнес-логики сортировки и фильтрации. /// Рекорды сортируются по очкам (убывание), затем по имени игрока (возрастание). /// </summary> public async Task<IReadOnlyList<RecordEntry>> GetTopRecordsAsync() { // Получаем все рекорды из репозитория IReadOnlyList<RecordEntry> allRecords = await _repository.GetAllAsync(); // Бизнес-логика: сортировка по очкам (убывание), затем по имени (возрастание) return [.. allRecords .OrderByDescending(r => r.Score) .ThenBy(r => r.PlayerName) .Take(_topCount)]; } /// <summary> /// Функция, добавляет новый рекорд и обновляет список, сохраняя только топ-N. /// Применяет бизнес-логику: валидация имени, сортировка, фильтрация топ-N. /// </summary> public async Task AddRecordAsync(string playerName, int score) { // Валидируем имя игрока if (string.IsNullOrWhiteSpace(playerName)) { throw new ArgumentException("Player name cannot be empty", nameof(playerName)); } // Создаем новый рекорд с очищенным именем RecordEntry entry = new(playerName.Trim(), score); // Получаем текущие рекорды IReadOnlyList<RecordEntry> currentRecords = await _repository.GetAllAsync(); List<RecordEntry> updatedRecords = [.. currentRecords]; updatedRecords.Add(entry); // Бизнес-логика: оставляем только топ-N, отсортированные по очкам и имени List<RecordEntry> topRecords = [.. updatedRecords .OrderByDescending(r => r.Score) .ThenBy(r => r.PlayerName) .Take(_topCount)]; // Сохраняем обновленный список рекордов в репозиторий await _repository.SaveAllAsync(topRecords); } /// <summary> /// Очищает всю таблицу рекордов. /// </summary> public Task ClearRecordsAsync() { return _repository.ClearAsync(); } /// <summary> /// Функция, получает статистику по таблице рекордов. /// Включает общее количество записей, наивысший счет, средний счет и имя лидера. /// </summary> public async Task<RecordsStatistics> GetStatisticsAsync() { // Получаем все рекорды IReadOnlyList<RecordEntry> records = await _repository.GetAllAsync(); // Если рекордов нет, возвращаем пустую статистику if (records.Count == 0) { return new RecordsStatistics(0, 0, 0, null); } // Вычисляем статистику: количество, максимум, среднее, лидер return new RecordsStatistics( TotalRecords: records.Count, HighestScore: records.Max(r => r.Score), AverageScore: (int)records.Average(r => r.Score), TopPlayer: records.OrderByDescending(r => r.Score).First().PlayerName ); } } /// <summary> /// Статистика таблицы рекордов. /// Содержит информацию об общем количестве записей, максимальном счете, среднем счете и лидере. /// </summary> /// <param name="TotalRecords">Общее количество рекордов в таблице.</param> /// <param name="HighestScore">Наивысший счет среди всех рекордов.</param> /// <param name="AverageScore">Средний счет всех рекордов (целое число).</param> /// <param name="TopPlayer">Имя игрока, набравшего наивысший счет (лидер), или null если рекордов нет.</param> public sealed record RecordsStatistics( int TotalRecords, int HighestScore, int AverageScore, string? TopPlayer ); }