Ответ
Unit of Work (Единица работы) — это поведенческий паттерн проектирования, который отслеживает все изменения, сделанные с бизнес-объектами в ходе транзакции, и координирует запись этих изменений в источник данных (например, базу данных). Его основная цель — обеспечить целостность данных и минимизировать количество обращений к БД, группируя несколько операций в одну команду.
Аналогия: Представьте, что вы делаете покупки в супермаркете. Unit of Work — это ваша корзина. Вы кладете в нее товары (новые объекты), меняете их (изменяете объекты), убираете обратно на полку (удаляете объекты). Оплата на кассе (Commit) — это момент, когда все изменения применяются разом.
Ключевые обязанности Unit of Work:
- Отслеживание новых объектов, которые должны быть вставлены.
- Отслеживание измененных ("грязных") объектов, которые должны быть обновлены.
- Отслеживание удаленных объектов.
- Управление Identity Map — кэшем, гарантирующим, что один бизнес-объект будет представлен в памяти только одним экземпляром.
- Выполнение всех накопленных операций в правильном порядке (вставки, обновления, удаления) при вызове
commit().
Практическая реализация в .NET с Entity Framework Core:
// DbContext в EF Core является реализацией Unit of Work.
using (var context = new AppDbContext()) // Начало Unit of Work
{
// 1. Отслеживание новой сущности (будет INSERT)
var newAuthor = new Author { Name = "Джон Смит" };
context.Authors.Add(newAuthor);
// 2. Отслеживание изменений сущности (будет UPDATE)
var existingBook = context.Books.First(b => b.Id == 1);
existingBook.Price = 29.99m; // EF Core отслеживает это изменение
// 3. Отслеживание удаления сущности (будет DELETE)
var bookToDelete = context.Books.Find(5);
context.Books.Remove(bookToDelete);
// 4. Все изменения (INSERT, UPDATE, DELETE) выполняются одной транзакцией
// при вызове SaveChanges().
context.SaveChanges(); // Commit Unit of Work
}
Преимущества использования:
- Производительность: Группировка запросов (batch operations) снижает нагрузку на БД.
- Целостность: Все изменения либо применяются вместе (
Commit), либо откатываются (Rollback), что поддерживает согласованность данных. - Упрощение кода: Разработчику не нужно вручную отслеживать, какие объекты изменились и когда их сохранять.
- Снижение риска Deadlock: Правильный порядок операций (например, вставки перед обновлениями) помогает избежать взаимных блокировок.
Паттерн является фундаментальным для большинства ORM, таких как Entity Framework, Hibernate, Doctrine.