Salve, Deus, beleza? Continuamos essa saga aqui no Domain do RuneDesign. Agora vamos virar a chave, um novo capítulo. Tenho certeza que muitos de vocês querem ver como a gente vai trabalhar com os agregados, então chegou a hora de trabalhar com a persistência. Como já foi dito por mim e também pelo Vernon, os repositórios que vão ser responsáveis por persistir os agregados. Então, agora a gente tem a ideia de que de um agregado ele é complexo, porque ele tem várias camadas, ele tem ali a camada da sessão e também dos lugares. Eu posso ter muitos objetos envolvidos. Então, independente do que eu fizer aqui, quem que vai fazer a persistência no banco de dados vai ser o nosso repositório. Quem vai fazer a persistência no banco de dados vai ser o nosso repositório. Então, nesse repositório, é lá que a gente vai ter aquelas operações de consultar, que está vindo lá do banco de dados, ou de criar, atualizar e excluir, que a persistência a gente está armazenando no banco. No repositório, a gente não tem aquelas operações ali que estão no agregado. A única incumbência desse cara é salvar. Então daqui a pouco a gente vai criar lá um reservar. Eu não tenho reservar no repositório. Eu vou ter só esses métodos aqui. Consultar eu posso ter consultar pelo ID, consultar por tal coisa, consultar por tal coisa. Não tem regra de negócio. A gente só está preocupado com armazenamento. Armazenamento no banco de dados, armazenamento no arquivo ou aonde quer que seja. E na hora que você vai fazer esse armazenamento aqui, esse armazenamento aqui, a escolha da sua biblioteca de persistência pode te trazer muita mais eficiência na construção desse repositório ou dele ser um pouco mais verboso. Não tem uma decisão, primeiro, isso aqui é um disclaimer, o que eu vou mostrar daqui para frente não significa que é a maneira correta ou que é a maneira que você necessariamente tem que fazer, mas o que eu vou apontar aqui são as vantagens e desvantagens. Você tem que estar ciente dessa decisão que você vai tomar no seu projeto. A princípio, o agregado tem um formato que pouco tem alguma semelhança com o banco de dados. A gente está trabalhando com orientação a objetos, o banco de dados vai trabalhar lá com os registros. Então, de certa forma, eu vou ter que pegar o evento, o event session, o event spot, e organizar as tabelas, quantas tabelas que eu acho que sejam necessárias, o formato e tudo mais. Então, acaba que toda vez que eu salvo, faço uma mudança lá no banco de dados ou que eu consulto, eu tenho que fazer uma conversão do agregado para o formato do banco ou do banco para o formato do agregado. Então, a gente acaba criando uma espécie de um mapeador, ou de um mapper. Esse cara vai ser justamente isso aqui. Acho que eu tinha feito aqui, mas dá para... deixa eu ver se eu consigo recuperar ele. Eu tinha feito ele aqui e tinha apagado. Acho que eu apaguei com o CTRL Z. Então a gente acaba criando um EventMapper com dois métodos estáticos. Normalmente se faz assim, static to domain. Eu recebo aqui qualquer coisa que vai vir lá do banco de dados e devolvo a instância do agregado. Tem outro método, toPersistence, que eu recebo o agregado e vou converter ali para o formato da biblioteca de persistência que eu tenho. Então, isso aqui é utilizado dentro do repositório. Dependendo da biblioteca que a gente escolher, dependendo da biblioteca que a gente escolher, nós podemos basicamente abstrair esse mapeador. Dependendo da biblioteca, eu consigo pegar a minha modelagem rica, do jeito que ela está, e mandar ela lá para o banco de dados, sem criar essa camada de mapeamento. Então, a nossa ideia aqui, o que eu vou mostrar para vocês, vai ser justamente tirando isso, tá? Eu não quero trabalhar com mapeador. Não é porque ele está errado, mas é justamente para mostrar uma maneira eficiente, porque esse mapeador aqui é bem visível. Acho que vocês já devem ter imaginado, poxa, eu preciso pegar o objeto ali e converter lá para a minha biblioteca XPTO, quando pego do banco de dados, se eu tiver ali o meu ORM da vida, tem o formatozinho dele que eu vou ter que fazer uma modelagem para ele e converter para o meu agregado. Então, muitas vezes, dependendo da lib que você tiver, você acaba tendo que modelar um event model para a sua biblioteca XPTO. No caso do JavaScript, é muito utilizado os decorators. Ah, isso aqui é uma entidade. Aí coloca-se o campo 1, campo 2, campo 3, e por aí vai. Aí eu vou ter que criar também um event section model, normalmente eu estou chamando de model aqui para não ter colisão com o conceito de entidade. Aí eu crio os campos lá também e acabo criando um event spot model. Então, olha só, nesse cenário em que a gente tem um mapeador aqui e uma biblioteca dessas famosas, independente da sua linguagem de programação, eu teria que ter o meu agregado já, com a minha modelagem rica, e o meu modelo anêmico, que é o que o meu ORM está pedindo, além do meu mapeador. Então, aqui no toDomain eu receberia, não preciso receber necessariamente um parâmetro, eu receberia ele tudo que é necessário para poder pegar do meu modelo anêmico e converter para o meu modelo rico, porque eu estou retornando aqui o evento. Já aqui na persistência, eu pego o meu agregado e converso ali para o meu modelo anêmico. Então, isso aqui pode representar uma ineficiência para a gente poder trabalhar, porque toda vez você vai ter que fazer isso ali, cada entidade vai ter que ter mais uma classe, a gente pensa assim, poxa, está fazendo uma repetição. Mas muitas vezes não tem o que fazer. A escolha do projeto foi aquele ORM que foi mais conveniente por vários motivos. A gente precisa entender também que às vezes não tem a decisão que a gente gostaria que fosse. Então tem que trabalhar. Então a gente gostaria que fosse. Então, tem que trabalhar. Então, deixo já esse aviso. Mas o que eu quero fazer aqui é mostrar como que você pode identificar se você pode ser mais eficiente ou não, se você puder escolher a sua biblioteca. Então, eu fiz aqui um apanhado de algumas linguagens. Se eu não incluir aqui a sua linguagem, me desculpe, porque não tem como incluir todas. Incluir aqui também, principalmente, do próprio JavaScript. Se você tiver alguma dúvida, só mandar aí que a gente pode fazer uma análise também. Mas, normalmente, lá na documentação você consegue essa informação. Então, para JavaScript, a gente tem aqui essas bibliotecas que são as mais famosas, Cicolize, Prisma, Type.orm, Next, Bookshelf e Micro.orm. Para Python, coloquei aqui o Django.orm, mas a gente tem vários também, mas o Django é o framework mais popular. Para Ruby, temos lá o próprio Rails com o seu RM dele. Para Java, temos o Hibernate, muito famoso. Para PHP, Doctrine Eloquent. Claro que tem vários, mas esses aqui são os mais famosos. E para .NET, WntFramework. Beleza. Basicamente, esses ORMs, eles se dividem em Active Record versus Data Mapper. São duas abordagens para que a gente possa modelar os dados. O Active Record, considerado por muitos até um antipatter, mas isso aí vai em outra discussão, é quando a gente acaba criando lá os nossos modelos, por exemplo, modelo de usuário, ou criarei lá o meu modelo de evento, estendendo de um módulo. Extends módulo. Então, quando a gente tem a instância desse evento, já tem todas as operações para salvar, para poder atualizar, para poder consultar, tudo está embutido na própria classe. Então, se mistura dados com as operações no banco de dados. Então, a gente acopla a nossa entidade, as operações do banco. Então, todo mundo que está aqui como Active Record vai trabalhar nesse modelo com a sua devida peculiaridade com a linguagem de programação. Eu deixo só o Next, não sei se vocês conhecem esse camaradinho aqui, que ele não trabalha nem com DataMap ou ActiveRecord, aquele tipo de biblioteca mais de baixo nível, que a gente acaba fazendo as queries, não ali diretamente posso fazer, no baixo nível, mas a gente vai fazer um insert ali, via orientação objeto, nesse caso aqui, acaba que a gente tem também que fazer o mapeamento, não tem que fazer um novo model, mas eu tenho que pegar o agregado e fazer ali o posicionamento das questões do insert, fazer o update, quando eu estou consultando, tem que pegar todos os dados e fazer ali o posicionamento das questões do insert, fazer o update. Quando eu estou consultando, tenho que pegar todos os dados e montar o meu agregado. Acaba que a gente tem que fazer essa programação mais na mão. Mas aí que está a questão, quando a gente tem um RN que trabalha com o Data Mapper, aí vai facilitar muito mais a nossa vida. Por quê? Porque o Data Mapper vai fazer com que a gente tenha as nossas classes das entidades como sendo entidades burrinhas. Você pode colocá-la todos os dados e etc. E ela vai ter um mapeamento que é uma opção de você colocar dentro da própria classe, com annotations, com decorator, dependendo da linguagem de programação, mas a gente pode separar num outro arquivo e deixar a classe pura, com a própria linguagem de programação. Então, o DataMapper cai muito bem com o DDD, de programação. Então, o DataMapper cai muito bem com o DDD porque eu posso pegar essa classe da maneira que ela está mapeando com o meu ORM de DataMapper, vou conseguir salvar sem ter que criar mais um módulo e sem ter que criar um mapeador. que criar mais um model e sem ter que criar um mapeador. Então a escolha, se você puder escolher, escolha um data mapper. Mas aí também vem uma outra questão, que às vezes você pode ter uma biblioteca com data mapper ali e ela tem uma certa forma de organizar os dados, que você tem que tomar cuidado para poder trabalhar com objetos de valores, você vai ter que criar um tipo de mapeamento personalizado, algumas coisas assim. Então, dê uma testada para ver se esse Data Mapper que você está escolhendo é flexível para fazer as suas adaptações necessárias. Mas aqui eu cito três que já são muito maduros, que a gente consegue fazer, que é o Hibernate do Java, o Ant Framework do .NET e o Doctrine do PHP. Esses caras aqui já têm anos e anos e anos trabalhando com data mappers, já são muito maduros, têm uma comunidade muito grande, então é muito simples para poder fazer essas adaptações. Então, no caso do JavaScript, a gente vai escolher o micro-URM, porque apesar do Type-URM ter até uma comunidade maior e ter o Data Mapper também, aqui a gente não tem, eu coloquei o asterisco justamente porque a gente não tem aqui um camaradinha, que é o Unit of Work, que vai ajudar a gente nos nossos processos de negócios. Inclusive, esse pattern aqui é um pattern que está lá no livro do Martin Fowler. Eu não sei se em algum outro caso aqui no curso já foi falado sobre ele. Mas o TypeURM trabalha com o Data Mapper, com o Active Record. É uma biblioteca mista, você pode ativar um lado ou outro, mas o Data Mapper aqui não tem o Unit of Work. Então, o MicroRM sai na frente. O MicroRM é inspirado no Hibernate, no Doctrine. É um projeto que tem crescido muito e já está maduro o suficiente para a gente poder usar nas nossas aplicações e permite que a gente use com os nossos agregados limpinhos, sem ter nada focado em persistência. Então, fica esse disclaimer aí. Isso aqui é muito importante. Mapeie o seu ORM, se você puder escolher, ótimo. Se não puder escolher, o trabalho é esse mesmo. Então, se você estiver no JavaScript, estiver com o SQLize, com o Prisma, com o Bookshelf, etc., você vai ter que ter o seu mapeador lá. Não dá para trabalhar diretamente. Beleza? Então, nesse capítulo aqui, a gente vai abrir a mente em relação a essa questão de mapeamento, entidade relacional, a gente vai ver como que vai ser fácil criar os repositórios. Então, pessoal, vamos mais uma mini saga aqui. É isso aí. Até a próxima.