ORM: Data Mapper vs Active Record
ORM significa Object-Relational Mapping , ou seja, a técnica que transforma Objetos de OOP em linhas no banco de dados e vice-versa.
Existem dois padrões:
- Active Record : O próprio registro (entidade) pode alterar ativamente o banco de dados
- Mapeador de dados : existe um objeto externo que persiste nas entidades
registro ativo
Como mencionei anteriormente, a própria entidade pode ser criada, atualizada ou excluída. Em PHP, por exemplo, o Eloquent é um Active Record ORM desenvolvido pela comunidade Laravel.
final class UserCreator
{
public function create(UserInformation $userInfo): void
{
$address = Address::createFrom($userInfo->address());
$address->save() # Address is stored in the database
$user = User::createFrom($userInfo->user());
$user->address = $address; // Set relationship
$user->save(); # User is stored in the database
}
}
No mapeador de dados, precisamos de uma classe externa que atualize o banco de dados. Em PHP, por exemplo, o Doctrine é o Data Mapper ORM de fato para Symfony.
final class UserCreator
{
public function __construct(
private EntityManager $entityManager,
) {}
public function create(UserInformation $userInfo): void
{
$address = Address::createFrom($userInfo->address());
$user = User::createFrom($userInfo->user());
$user->address = $address; # Set relationship
# We persist all objects we want to update
$this->entityManager->persist($address);
$this->entityManager->persist($user);
# Finally, flushing the entity manager will execute the SQLs
$this->entityManager->flush();
}
}
Embora, se você der uma olhada em ambos os snippets, poderá ver que o Data Mapper já está usando uma dependência externa ( Entity Managerobjeto) que é estranho e claro, é mais difícil se você decidir introduzir alguns testes na UserCreatorclasse, enquanto isso na Active Recordclasse, as entidades estão se salvando, então não temos nenhuma dependência à primeira vista, mas isso não é totalmente verdade, a própria entidade tem conhecimento do banco de dados e será difícil escrever alguns testes se usarmos a entidade diretamente User.
Padrão de repositório
O padrão de repositório é um padrão de design que oculta a lógica do banco de dados em uma nova classe, expondo apenas os métodos que queremos fornecer ao usuário.
Para isso, precisamos criar uma interface e uma classe que irá implementar a interface onde iremos descartar toda a lógica.
# App/User/Domain
interface UserRepository
{
public function save(UserInformation $userInfo): void;
}
~~~~
# App/User/Infrastructure
final class ActiveRecordUserRepository implements UserRepository
{
public function save(UserInformation $userInfo): void
{
$address = Address::createFrom($userInfo->address());
$address->save()
$user = User::createFrom($userInfo->user());
$user->address = $address;
$user->save();
}
}
final class DataMapperUserRepository implements UserRepository
{
public function __construct(
private EntityManager $entityManager,
) {}
public function create(UserInformation $userInfo): void
{
$address = Address::createFrom($userInfo->address());
$user = User::createFrom($userInfo->user());
$user->address = $address;
$this->entityManager->persist($address);
$this->entityManager->persist($user);
$this->entityManager->flush();
}
}
final class UserCreator
{
public function __construct(
private UserRepository $userRepository,
) {}
public function create(UserInformation $userInfo): void
{
$this->userRepository->save($userInfo);
}
}





































![O que é uma lista vinculada, afinal? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)