В чем разница между паттернами Active Record и Data Mapper?

Ответ

Это два разных подхода к организации слоя доступа к данным (ORM).

Active Record — это когда объект бизнес-логики «знает», как сохранить себя в БД. Объект содержит и данные, и методы для работы с ними (CRUD).

// Пример с Eloquent (Laravel), который реализует Active Record
$user = new User();
$user->name = 'Иван';
$user->email = 'ivan@example.com';
$user->save(); // Объект сам вызывает INSERT

$foundUser = User::find(1); // Статический метод на классе модели
$foundUser->delete();

Плюсы: Простота и скорость разработки для CRUD-операций. Минусы: Нарушение принципа единой ответственности (SRP), бизнес-логика тесно связана с БД, что усложняет тестирование и поддержку в сложных доменах.

Data Mapper — это слой, который полностью отделяет бизнес-объект (сущность) от механизма его сохранения. Сущность ничего не знает о БД. За преобразование объекта в строки таблицы и обратно отвечает отдельный класс-маппер.

// Пример с Doctrine, который реализует Data Mapper
// 1. Сущность — простой POPO (Plain Old PHP Object)
class User {
    private $id;
    private $name;
    // ... геттеры и сеттеры, без логики сохранения
}

// 2. Работа через EntityManager (маппер)
$user = new User();
$user->setName('Иван');

$entityManager->persist($user); // Сообщаем мапперу о новом объекте
$entityManager->flush(); // Маппер синхронизирует состояние объектов с БД (выполняет INSERT)

$foundUser = $entityManager->find(User::class, 1); // Маппер загружает данные и создает объект
$entityManager->remove($foundUser);
$entityManager->flush();

Плюсы: Чистая архитектура, строгое разделение ответственности, бизнес-логика легко тестируется (можно использовать моки для маппера). Минусы: Большая начальная сложность, больше шаблонного кода.

Вывод: Active Record отлично подходит для простых приложений и быстрого прототипирования. Data Mapper — для сложных предметных областей, где важны чистая архитектура, тестируемость и гибкость.

Ответ 18+ 🔞

А, ну вот, опять про эти ваши ORM-подходы. Слушай, давай я тебе на пальцах объясню, а то тут такие термины, что волосы дыбом встают. Представь себе двух чуваков, которые пытаются заказать пиццу.

Active Record — это как будто ты сам звонишь в пиццерию. Ты (объект) знаешь, как себя «сохранить» (сожрать). У тебя есть номер телефона (метод save()), ты сам набираешь, заказываешь, говоришь адрес. Всё в одном флаконе.

// Типа Eloquent из Laravel — классический актив-рекорд
$user = new User();
$user->name = 'Иван';
$user->email = 'ivan@example.com';
$user->save(); // Сам позвонил, сам заказал, молодчина

$foundUser = User::find(1); // Нашёл себя в базе через статический метод, как в телефонной книжке
$foundUser->delete(); // И сам же удалил запись, типа «отменил заказ»

Плюсы: Быстро, просто, не надо никого просить. Для мелких задач — вообще огонь. Хуй с горы — и готово. Минусы: Но представь, если тебе надо не просто пиццу, а целый банкет организовать. Ты уже будешь не только звонить, но и договариваться о доставке, рассчитывать скидки, вести переписку с менеджером. Вся эта ебала с бизнес-логикой налипает на тебя, как дерьмо на подошву. Тестировать такое — просто пиздец, потому что ты не можешь проверить свою логику, не позвонив в реальную пиццерину (то есть не дернув базу). Нарушение принципа единой ответственности — ты теперь и заказчик, и курьер, и оператор кол-центра, ёпта.

А теперь Data Mapper — это уже другой уровень. Ты — важный босс (сущность), у тебя есть личный помощник (маппер). Ты ему: «Хочу пиццу». И всё. Ты даже не знаешь, в какую пиццерию он звонит, по какому номеру и как он там договаривается. Ты просто получаешь пиццу.

// Допустим, Doctrine — это как раз про это
// 1. Ты — просто объект, чистый и пушистый. Никаких знаний о базе.
class User {
    private $id;
    private $name;
    // ... только геттеры-сеттеры, никакой логики сохранения
}

// 2. А вот твой верный помощник-маппер (EntityManager)
$user = new User();
$user->setName('Иван');

$entityManager->persist($user); // Ты шепчешь помощнику: «Запомни, мне надо пиццу»
$entityManager->flush(); // Помощник идёт и делает всё сам: звонит, заказывает, решает проблемы

$foundUser = $entityManager->find(User::class, 1); // Помощник принёс тебя из базы, отреставрировал
$entityManager->remove($foundUser);
$entityManager->flush(); // И удалил по твоей просьбе

Плюсы: Архитектура — чище некуда. Ты занимаешься только своими прямыми обязанностями (быть пользователем). Тестировать — одно удовольствие: можешь на насмешить помощника (мок) и проверять свою логику, не трогая базу. Для сложных систем, где бизнес-логика — это овердохуища правил, это единственный адекватный путь. Минусы: Но это, блядь, как нанять личного дворецкого. Больше кода, больше сущностей, нужно сначала настроить этого помощника, объяснить ему, где что лежит. Для простой задачи «заказать одну пиццу на вечер» — это стрельба из пушки по воробьям, мартышлюшка какая-то.

Итог, чувак:

  • Active Record — это когда ты сам всё делаешь. Быстро, но если проект разрастётся, станет пиздопроебибна каша. Идеально для лендингов, админок, прототипов — там, где логика проще пареной репы.
  • Data Mapper — это когда у тебя есть штат помощников. Сначала возни больше, зато потом, когда у тебя не пицца, а целый кейтеринг на тысячу человек, ты не сойдёшь с ума. Выбор для серьёзных корпоративных или высоконагруженных штук, где важна гибкость и чистота кода.

Вот и вся философия. Выбирай по задаче, а не потому, что модно.