Salve, Deus, beleza? Continua nossa saga aqui no Domain Dreaming Design. Agora vamos falar aqui do bendito do cara que eu venho falando já há várias aulas. Se você não conhece, poxa, cadê esse Unit of Work? Então vamos falar sobre esse cara. Esse Unit of Work é um pattern proposto pelo Martin Fowler, por isso que eu estou aqui com o site dele aberto. proposto pelo Martin Fowler, por isso que eu estou aqui com o site dele aberto. Inclusive, esse aqui é um pequeno trecho que você vai encontrar lá no livro de Patterns of Enterprise Application Architecture. Eu não sei se alguém já recomendou esse livro aqui no MBA. Provavelmente sim. Se sim, eu estou recomendando de novo que esse, ele vai te dar uma visão sobre uma série de padrões para poder resolver uma série de problemas no desenvolvimento, uma série de padrões de projetos para que você possa resolver problemas no software. E o Unit of Work é um padrão fantástico, um dos padrões que eu mais gosto de trabalhar de forma geral na tecnologia, porque ele vai permitir que nós otimizemos a comunicação com o storage. Não precisa ser necessariamente banco de dados, não. Pode ser que você está salvando um arquivo lá. Unit of Work pode ser implementado com qualquer tipo de armazenamento. Mas a gente precisa entender a ideia. Num cenário, vamos pegar aqui a nossa aplicação. Imagina lá o caso do evento em si. Evento a gente não separou em três entidades. Não tem evento, eventSession e eventSpot. Isso acabou fazendo com que nós tenhamos três tabelas. Portanto, na hora de fazer a persistência, a gente tem que trabalhar com o modo transação, porque no mínimo a gente vai ter três inserts sendo executados. Se a gente não habilitar o modo transação, o modo atômico para poder trabalhar, e a última transação, que é do spot falhar, eu posso ter cadastrado o evento e a session, e os spots não. Então, eu não tenho consistência nessa operação. Mas, se a gente não estivesse trabalhando com esse Unit of Work, o que ia acabar acontecendo? Eu faço um insert lá dos eventos. Ou seja, fiz uma comunicação com o banco de dados, volto, faço alguma outra coisa, faço alguma outra coisa, faço mais um insert para a sessão, e faço os inserts lá. Tudo bem que aqui poderia ser um insert só, mas... Eu fiz aqui mais um insert para o spot. Com os ORMs esse entendimento é muito importante pra entender a eficiência da operação os ORMs de Active Record, eles vão fazer essa operação de forma separada, então eles vão comunicando com o banco de dados, vai e volta vai e volta, vai e volta você pode estar fazendo uma operação de negócio que vai no banco de dados várias vezes e a gente tem ali uma latência de comunicação com o banco às vezes até uma latência maior se o banco de dados está numa outra rede, enfim, a gente tem esses cenários então isso aqui é muito ruim, isso torna o nosso processo de negócio lento imagine que milhares ou milhões de pessoas estejam acessando essa aplicação ao mesmo tempo. Quanto mais a gente estiver fazendo comunicação com o banco de dados, mais lento vai ser a resposta da nossa aplicação também. Quanto mais tempo a gente está mantendo aquele processo de negócio ativo, estou consumindo processamento, memória, as threads do servidor web, enfim. Então, o Unit of Work vem justamente para ajudar nesse ponto. Ao invés de a gente ficar fazendo essas operações ali toda hora no banco, quando eu quero salvar, já mando lá para o banco? Não, a gente não vai fazer isso. A primeira coisa que a gente vai fazer. Nós vamos criar uma classe que vai manter três listas de objetos. Na verdade, pode-se manter quantas listas você quiser, dependendo até do conceito, porque o Unit of Work hoje foi muito expandido, ele foi muito otimizado. Mas olhando aqui para a classe que o Martin Fowler está expondo, esse aqui é o diagrama da classe do Unit of Work, a gente vai ter como registrar um novo objeto, um objeto Dury, que é um objeto que a gente vai tender a salvar esse cara, que ele já foi sujo, ele já foi criado, e a gente fez alguma manipulação nele. Eu posso tirar esse objeto, lembra aquele clean que a gente está fazendo láulação nele, eu posso tirar esse objeto. Lembra aquele clean que a gente está fazendo lá com o microRM? Então, eu posso tirar esse objeto ali da lista de objetos e posso incluir também o objeto para ser excluído. Então, falando a grosso modo, bem a grosseiro mesmo, eu tenho um unit of work. Se você quiser criar um unit of work na mão, você vai ter lá um new entities, um during entities e um deleted ou removed entities. Então, toda vez que você faz um persist, como a gente está fazendo aqui dentro do repositório, quando você faz um persist, ou quando você faz um remove, na verdade você não está fazendo nada no banco de dados, você só está incluindo ali naquela listinha. Então, ele mantém essa listinha desses objetos, ele tem que ter um conhecimento apurado sobre eles, ele tem que saber como que ele apurado sobre eles, ele tem que saber como que ele vai tanto mandar isso para o storage quando ele vai recuperar, e o segredo está no flush, que normalmente os frameworks acabam implementando, mas a gente poderia chamar isso aqui de commit também. Então não confunda esse commit aqui com o fechamento de uma transação do banco de dados. Não. No commit ou no flush, nós vamos percorrer, vou fazer ali um for para poder pegar os objetos, os new entities. Vou fazer mais um for para os objetos doing e um removed. Então, aqui no flush que ele ele vai abrir o modo transação, no caso de pegando um banco de dados convencional, ele vai abrir o modo transação, vai fazer um BEGIN TRANSACTION, abrir o modo transacional, e depois ele vai fazer o COMMIT lá. Então, é por isso que a gente não precisa se preocupar a princípio em ficar fazendo abertura desse modo transacional, quando a gente lida com vários objetos. Foi lá naquele caso do teste no repositório de eventos que eu criei tanto o partner aqui, eu adicionei o partner, adicionei depois o evento no repositório dele, e aí que eu fiz o flush. Então, se falhar aquela operação ali, ela é descartada. Então, o Unit of Work está otimizando isso, porque ele descarrega tudo de uma vez só. Então, ele entende ali quais objetos têm que ser criados, os que têm que ser atualizados, os que têm que ser removidos, e ele manda de uma vez só. Se não aconteceu, pronto, eu tenho a consistência da minha operação garantida, porque ela vai ser totalmente revertida. Então, o que é interessante para esse UnitOfWork, que é onde eu estava aqui, é que na hora que eu tenho, por exemplo, um find, que eu queira buscar uma entidade aqui que eu passo qual que é o entity class, um id qualquer. Às vezes tem muita gente que não se toca e dá erro em teste porque ele está mantendo na memória. Você acabou de criar um registro lá, a sua entidade continua aqui, você tem lá o customer. Então, quando você faz um find, o in-house of work vai ver peraí, esse objeto está sendo geren aqui, você tem o AllCustomer. Então, quando você faz um Find, o InventoryOffWork, vai ver, peraí, esse objeto está sendo gerenciado por mim, ele já está aqui no meu registro? Ah, deixa eu pegar ele e retornar. Às vezes você precisa pegar uma nova referência, e aí tem métodos como Refresh, Reload, cada lib vai ter o seu próprio modo. Mas esse rastreamento aqui vai nos ajudar a tornar o nosso processo de negócio mais simples, porque aqui, qualquer application service, eu chamo esse Unit of Work e só chamo um flush ali, um commit, como a gente definir. E ainda, como eu tenho esses agregados mantidos na memória, eu consigo pegar todo mundo que está ali e ver os eventos que eles dispararam. E a partir desses eventos, nós podemos chamar os ouvintes desses eventos e propagar esses eventos para outros subdomínios. Que aí são os eventos de integração que a gente vai entrar daqui a pouco. Então, a vantagem dele é justamente otimizar o nosso processo de negócio, mas também ele mantém essa lista ali e eu posso fazer outras coisas. A gente pode fazer uma infinidade de coisas. Se você utiliza outro ORM da vida, coisas. A gente pode fazer uma infinidade de coisas. Se você utiliza outro ORM da vida, que eu já falei que não tem nada errado de você usar um outro ORM, mas cuidado, quando você vê ali um bronze, pô, tô pegando aqui um caso de um Cicolize da vida, tá? Do próprio JavaScript. Aí você olha lá e vê uma implementação, você viu o Current of Work, você viu na internet que a gente está fazendo o Current of Work, que é só fazer um Begin e um Transaction. Não é. Você tem um conhecimento apurado dos objetos e organizá-los ali na memória para que você possa, numa tacada só, fazer essa persistência e ainda ter essa inteligência de fazer a busca, não bater lá no banco de dados. Então, a gente acaba tendo um cache também. Então, isso aqui, posso até falar assim, esse unit of work aqui, unit of work, a gente fala, né? É um unit of work falsificado, um unit of work do Paraguai, tá? Isso não é unit of work. Acaba que a gente utiliza esse conceito, às vezes, dentro do Application Service, mas para poder deixar claro a intenção. Mas Unite of Work, Unite of Work mesmo, é isso implementado pelo MicroRM, pelo DocTrain, pelo Ranged Framework, pelo Hibernate. Então, esclarecido isso, o que a gente tem que fazer agora é criar aqui uma abstração de Unite of Work justamente para não permitir que o microRM tenha essa interferência direta que a gente quer também, que a nossa camada de aplicação orquestre a regra de negócio, mas com o mínimo de interferência de tecnologia também para deixar isso aqui mais estável. E a tecnologia é que depende da nossa application service e não o contrário. Então, vamos seguindo a nossa saga. É isso aí. E até a próxima.