/
yulka
/
domashki
Обзор
Документация
Войти
/
yulka
/
domashki
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
Program.cs
207 строк
9 KB
Полина Сидорова
Чистый код с 4 методами SOLID
20 фев 2026, 10:39
Верифицирован
20 фев 2026, 10:39
86c0260
Код
Авторство
О чём код?
using System; using System.Collections.Generic; using System.Linq; using System.Threading; public enum Priority { Low, Medium, High } public class TaskItem { public int Id { get; set; } public string Title { get; set; } = ""; public Priority Priority { get; set; } = Priority.Low; public string Category { get; set; } = ""; public DateTime DueDate { get; set; } = DateTime.MinValue; public DateTime? CompletedDate { get; private set; } = null; public bool IsOverdue => DueDate != DateTime.MinValue && (CompletedDate == null ? DueDate < DateTime.Now : CompletedDate > DueDate); public string CompletedState => CompletedDate == null ? "Активна" : (IsOverdue ? "Завершена, Просрочена ⚠️" : "Завершена ✅"); public void MarkCompleted(DateTime when) => CompletedDate = when; } // LSP: ИЕРАРХИЯ ФИЛЬТРОВ public interface ITaskFilter { bool Matches(TaskItem task); } public abstract class TaskFilterBase : ITaskFilter { public bool Matches(TaskItem task) => task != null && IsMatch(task); protected abstract bool IsMatch(TaskItem task); } public class PriorityFilter : TaskFilterBase { private readonly Priority _p; public PriorityFilter(Priority p) => _p = p; protected override bool IsMatch(TaskItem task) => task.Priority == _p; } public class CategoryFilter : TaskFilterBase { private readonly string _c; public CategoryFilter(string c) => _c = c; protected override bool IsMatch(TaskItem task) => string.Equals(task.Category, _c, StringComparison.OrdinalIgnoreCase); } public class DueDateFilter : TaskFilterBase { private readonly DateTime _l; public DueDateFilter(DateTime l) => _l = l; protected override bool IsMatch(TaskItem task) => task.DueDate != DateTime.MinValue && task.DueDate <= _l; } public class ActiveTasksFilter : TaskFilterBase { protected override bool IsMatch(TaskItem task) => task.CompletedDate == null; } public class OverdueTasksFilter : TaskFilterBase { protected override bool IsMatch(TaskItem task) => task.IsOverdue; } public class AllTasksFilter : ITaskFilter { public bool Matches(TaskItem task) => task != null; } // SRP & ISP: ИНТЕРФЕЙСЫ И СЕРВИСЫ public interface ITaskRepository { void Add(TaskItem task); void Remove(int id); TaskItem? GetById(int id); IEnumerable<TaskItem> GetAll(); } public interface ITaskValidator { void Validate(TaskItem task, ITaskRepository repo); } public interface ITaskService // Операции изменения { void AddTask(TaskItem task); void CompleteTask(int id); void RemoveTask(int id); void RescheduleTask(int id, DateTime newDate); } public interface ITaskQueryService // Операции чтения { IEnumerable<TaskItem> GetTasks(ITaskFilter? filter = null); } // РЕАЛИЗАЦИЯ (DIP: Зависимость от абстракций) public class TaskValidator : ITaskValidator { public void Validate(TaskItem task, ITaskRepository repo) { if (task.Id <= 0) throw new ArgumentException("ID должен быть положительным числом"); if (string.IsNullOrWhiteSpace(task.Title)) throw new ArgumentException("Название не может быть пустым"); if (task.DueDate != DateTime.MinValue && task.DueDate.Date < DateTime.Now.Date) throw new ArgumentException("Срок выполнения не может быть в прошлом"); if (repo.GetById(task.Id) != null) throw new ArgumentException($"В списке уже есть задача с id = {task.Id}"); } } public class InMemoryRepository : ITaskRepository { private readonly List<TaskItem> _tasks = new(); public void Add(TaskItem task) => _tasks.Add(task); public void Remove(int id) => _tasks.RemoveAll(t => t.Id == id); public TaskItem? GetById(int id) => _tasks.FirstOrDefault(t => t.Id == id); public IEnumerable<TaskItem> GetAll() => _tasks; } public class TaskManagerService : ITaskService, ITaskQueryService { private readonly ITaskRepository _repo; private readonly ITaskValidator _validator; public event Action<TaskItem>? TaskAdded; public event Action<TaskItem>? TaskRemoved; public event Action<TaskItem>? TaskCompleted; public event Action<TaskItem>? TaskOverdue; public TaskManagerService(ITaskRepository repo, ITaskValidator validator) { _repo = repo; _validator = validator; } public void AddTask(TaskItem task) { _validator.Validate(task, _repo); _repo.Add(task); TaskAdded?.Invoke(task); } public void RemoveTask(int id) { var task = _repo.GetById(id); if (task != null) { _repo.Remove(id); TaskRemoved?.Invoke(task); } } public void CompleteTask(int id) { var task = _repo.GetById(id) ?? throw new ArgumentException("Не найдена"); task.MarkCompleted(DateTime.Now); TaskCompleted?.Invoke(task); if (task.IsOverdue) TaskOverdue?.Invoke(task); } public void RescheduleTask(int id, DateTime date) { var task = _repo.GetById(id) ?? throw new ArgumentException("Не найдена"); if (date < DateTime.Now) throw new ArgumentException("Срок в прошлом"); task.DueDate = date; } public IEnumerable<TaskItem> GetTasks(ITaskFilter? filter = null) { var f = filter ?? new AllTasksFilter(); return _repo.GetAll().Where(f.Matches) .OrderBy(t => t.DueDate == DateTime.MinValue ? DateTime.MaxValue : t.DueDate) .ThenBy(t => t.Priority).ToList(); } } public class Program { static void Main() { Console.OutputEncoding = System.Text.Encoding.Unicode; var service = new TaskManagerService(new InMemoryRepository(), new TaskValidator()); service.TaskAdded += (t) => Console.WriteLine($"✅ Добавлена задача: {t.Title} [{t.Category} {t.Priority}]"); service.TaskCompleted += (t) => Console.WriteLine($"🎉 Завершена задача: {t.Title}"); service.TaskOverdue += (t) => Console.WriteLine($"⚠️ Просрочена задача: {t.Title}"); service.TaskRemoved += (t) => Console.WriteLine($"❌ Удалена задача: {t.Title}"); Console.WriteLine("=== Добавление задач ==="); service.AddTask(new TaskItem { Id = 2, Title = "Закончить проект", Priority = Priority.High, Category = "Работа", DueDate = DateTime.Now }); Thread.Sleep(100); service.AddTask(new TaskItem { Id = 3, Title = "Купить продукты", Priority = Priority.Medium, Category = "Личное", DueDate = DateTime.Now.AddDays(1) }); service.AddTask(new TaskItem { Id = 1, Title = "Прочитать книгу", Priority = Priority.Low, Category = "Образование", DueDate = DateTime.Now.AddDays(14) }); service.AddTask(new TaskItem { Id = 5, Title = "Подготовить презентацию", Priority = Priority.High, Category = "Работа", DueDate = DateTime.Now.AddDays(10) }); Console.WriteLine("\n=== Все задачи ==="); foreach (var t in service.GetTasks()) Console.WriteLine($"- {t.Title} [{t.Category} {t.Priority}] - Due: {t.DueDate} ({t.CompletedState})"); Console.WriteLine("\n=== Задачи с высоким приоритетом ==="); foreach (var t in service.GetTasks(new PriorityFilter(Priority.High))) Console.WriteLine($"- {t.Title} [{t.Category}]"); Console.WriteLine("\n=== Завершение задачи ==="); service.CompleteTask(2); service.CompleteTask(5); Console.WriteLine("\n=== Активные задачи ==="); foreach (var t in service.GetTasks(new ActiveTasksFilter())) Console.WriteLine($"- {t.Title} [{t.CompletedState}]"); Console.WriteLine("\n=== Удаление задачи ==="); service.RemoveTask(1); Console.WriteLine("\n=== Просроченные задачи ==="); foreach (var t in service.GetTasks(new OverdueTasksFilter())) Console.WriteLine($"- {t.Title} (Due: {t.DueDate:dd.MM.yyyy})"); Console.WriteLine("\n=== Перенос срока задачи ==="); service.RescheduleTask(2, DateTime.Now.AddDays(10)); Console.WriteLine("Срок задачи перенесен"); Console.WriteLine("\n=== Итоговый список ==="); foreach (var t in service.GetTasks()) Console.WriteLine($"- {t.Title} (IsOverdue: {t.IsOverdue})"); } }