Добавить комментарий

Breaking Down Design Patterns: Active Record

Lately, I've been studying design patterns and architectural approaches, and I'm gradually starting to notice that many things I've been using in Laravel for years actually have specific names.

One of these patterns is  Active Record.

In short, the idea behind Active Record is that an object represents data from the database and also knows how to work with that database.

This is exactly the approach used by Eloquent ORM in Laravel.

How it works in Laravel

For example, let's say we have a User model:

class User extends Model
{
}

We can retrieve a user and modify it directly through the model:

$user = User::find(10);
 
$user->name = 'John';
$user->save();

Here, User is responsible for several things at once: it represents the user, contains its data, and provides methods for working with the database such as find(), save(), delete(), and so on.

The basic idea can be illustrated like this:

User
├── user data
├── business logic
└── database operations

That's the main idea behind Active Record.

Active Record vs Data Mapper

Another common approach is Data Mapper. In this case, the domain object doesn't need to know how it is persisted in the database.

Conceptually, the code might look like this:

$user = $userRepository->findById(10);
 
$user->changeName('John');
 
$entityManager->flush();

Here, User is responsible for its data and behavior, while a separate mechanism — such as a Repository, EntityManager, or Data Mapper — handles persistence.

So the difference can be summarized like this:

Active Record:

User
├── data
└── database operations


Data Mapper:

User
└── data and behavior

Data Mapper / EntityManager
└── database operations

In PHP, Doctrine ORM, which is commonly used with Symfony, is a good example of the Data Mapper approach.

What are the pros and cons?

The main advantage of Active Record is simplicity. For typical CRUD applications, it's very convenient to write:

$product = Product::find($id);
 
$product->price = 100;
$product->save();

There is no need to create additional abstractions just to persist a simple entity.

However, this approach also has a downside. As the business logic becomes more complex, models can gradually turn into very large classes responsible for data, persistence, and parts of the business logic at the same time.

That's why Laravel applications often combine Eloquent with Service Layer, Repository, and other patterns, distributing responsibilities between different layers.

In the end, I would summarize the difference like this:

Active Record — the object knows how to save itself.
Data Mapper — the object doesn't know how it is persisted.

And I think this is one of those cases where understanding the pattern helps you understand the architecture behind a framework, rather than simply memorizing Eloquent methods.

CAPTCHA
Защита от спама
Target Image