Concordo plenamente! a programação funcional geralmente envolve funções puras e imutáveis, o que torna o código mais claro e mais fácil de ler. Juntando tudo isso com a Clean Arch, fica muito show!
@FERNAND0_MEDElR0S Жыл бұрын
Top, Otavio. 👏👏👏🚀🚀
@romulosardinha8600 Жыл бұрын
Tenho algo bem perecido funcionando aqui na empresa. dominio com função pura. e funções que retornam o necessário para os casos de uso continuarem o processo. ficou bom d mais. gosto muito desta abordagem
@janduymomroe Жыл бұрын
Concordo muito com a questão de trazer a validação para as camadas mais externas. Mas mantenho os V.O.s como último bastião da verdade, até pra evitar deslizes na evolução do código quando muda de mãos. Muito boa a contribuição, professor! Inclusive preciso comprar esse seu livro. abs!
@emmanuelnery1567 Жыл бұрын
Concordo, até pq em algumas aplicações podemos ter não só uma API mas também um consumidor de uma fila assíncrona, o que vai forçar a ter essa validação em todas as bordas de entrada.
@joaogabrielulian6067 Жыл бұрын
Muito bom 👏! Interessante abordagem, eu gosto do uso de Value Objectos pois deixam o domínio como única fonte de verdade sobre as regras de negócio (considerando que algumas validações são regras de negócio). Penso que uma abordagem que mesclaria VO com domínio funcional seria ter Entidades com atributos "protegidos" (readonly), dessa forma todo método interno da entidade é estático e retorna um clone, não alterando estado.
@otaviolemos Жыл бұрын
Essa é uma abordagem possível também! Mas ainda acho estranho o dado entrar até na camada de domínio e ser validado só ali.
@joaogabrielulian6067 Жыл бұрын
@@otaviolemos Acho que a ideia não é bem o dado entrar no domínio e ser validado ali, mas o domínio definir as regras do jogo. O domínio vai executar ações partindo de objetos que ele definiu as regras, ao invés de receber tipos primitivos. A validação em si acaba ocorrendo nas camadas superiores, mas seguindo as regras do domínio. Inclusive eu até uso zod ou alguma biblioteca parecida dentro do 'create' do VO. Acho que a maior vantagem do VO é que toda a lógica que usa ele não precisa ter a carga mental de pensar se aquele objeto já foi validado.
@manoellopes211 Жыл бұрын
Bom dia Otávio, parabéns pelo excelente trabalho, sempre agregando demais aqui pra nós pessoas desenvolvedoras. Nos meus projetos, eu crio uma classe pra validação de schema recebendo via injeção de dependência uma interface genérica e crio um adapter dessa interface como um ZodAdapter. Então passo essa classe de validação, um CreaetUserValidation, por exemplo, para o controller e retorno um bad request caso ocorra um erro de validação. Assim posso mockar facilmente e apenas ter um teste de unidade com um erro genérico pra ver se qualquer erro de validação vai ser retornado. Com essa abordagem de middlewares, como ficariam os testes de validação de schema ?
@otaviolemos Жыл бұрын
Eu não acho que precisa de teste. De qualquer maneira, é só criar um teste que usa o schema e dá um parse em dados inválidos, por exemplo, verificando que ele rejeita o dado. Aquela minha função validateRequest pode ser testada tranquilamente já que é uma função pura.
@manoellopes2114 ай бұрын
@@otaviolemos Depois de bastante estudo e alguns testes, acabei chegando à uma solução que pra mim foi bem satisfatória, eu mantive eu queria tirar proveito de toda a usabilidade e robustez do zod para validação de sachema porém sem me acoplar a dependência. Então eu defini uma interface genérica "SchemaValidator" que recebe um tipo T Genérico e declara um método "validate" para validação de dados que recebe dados do tipo unknow. Essa interface não depende de nenhuma biblioteca específica, é apenas uma interface. Dessa forma eu posso criar outras interfaces mais especfícas a partir dessa interface genérica passando o tipo como generics, como uma interface "CreateUserValidator" por exemplo, que seria igual interface SchemaValidator recebendo uma entidade "User" como argumento pro tipo genérico. Dessa forma eu posso criar uma classe concreta como "CreateUserSchemaValidator" por exemplo que implementa a interface CreateUserValidator e apenas essa classe concreta conheceria o zod para definir e validar o esquema de usuário internamente. Outras classes do meu sistema conheceriam apenas interface CreateUserValidator. Dessa forma facilita trocar de biblioteca de validação no futuro, caso seja necessário sem alterar outras partes do sistema mas ainda me permite testar a validação de forma unitária através de mocks ou stubs que implementam a interface CreateUserValidator. Pra mim é importante isolar ao máximo possível de forma a testar a unidade e poder criar mais testes quanto possível.
@rafaelamizes6490 Жыл бұрын
Show de bola! Parabéns, professor. Eu também tenho utilizado uma abordagem semelhante ao implementar Arquitetura Limpa em Dart/Flutter. Uma dúvida: vc acharia válido utilizar um VO para representar um tipo monetário? Quero dizer, na sua estrutura de dados você utilizaria um V.O do tipo "Money" (que agrega tanto o valor quanto a moeda) ou utilizaria dois campos "soltos" para representar o valor e a moeda, por exemplo: "price: decimal" e "currency: string"?
@otaviolemos Жыл бұрын
Legal a sua pergunta porque é exatamente esse exemplo que mostro em outro vídeo sobre modelagem funcional. Ali no livro ele usa um VO mesmo, mas com uma implementação funcional. Dá uma olhada nesse vídeo, mais ou menos no minuto 11:00 (implementação em Clojure): kzbin.info/www/bejne/f4Okc2t9fbtricUsi=sjd_qSW1KohFSNXi
@jorgealegretti4796 Жыл бұрын
Eu achei interessante a abordagem de value objecs do Branas, ele trata como tipos. Acredito que atem em uma abordagem mais funcional isso poderia ser usado, da mesma forma que aceitamos o tipo Date do JS
@otaviolemos Жыл бұрын
Certamente! Eu falei do VO só em termos de validação. Aqui eu mostro um VO em uma modelagem funcional: www.google.com.br/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&ved=2ahUKEwjLqffJqJGBAxXArpUCHREwANgQFnoECBAQAQ&url=https%3A%2F%2Fm.youtube.com%2Fwatch%3Fv%3DIRAB8GHV8Sc&usg=AOvVaw31mOxQpba_pMtkTDJsyKF1&opi=89978449
@thiagobrito2387 Жыл бұрын
Fala, professor, blz? Chegou a ler o livro "data oriented programming" ? Vi uma semelhança entre essa abordagem e a abordagem utilizada no livro
@otaviolemos Жыл бұрын
Massa, ainda não vi não! Valeu!
@DevLJL Жыл бұрын
Eu não abandono o VO em domínios de jeito nenhum. E digo mais, ainda faço a validação no Front, no Request e no Domínio. E se por algum motivo eu tiver que escolher uma das 3 abordagens, fico com o VO no domínio e o resto que se exploda, kkkkkkkkk. Nem todo fluxo parte de um frontend, nem todo fluxo parte de uma request. Eu gosto de olhar para o meu domínio e ter a certeza que tudo que está lá dentro carregado, está validado independente se é um simples telefone, email, um calculo cabeludo.
@otaviolemos Жыл бұрын
É uma abordagem. Se você realmente tem diversos fluxos, vale a pena.
@aristotelescoutinho Жыл бұрын
11:06 Sobre trazer as validações para a borda e V.Os O uso de scheema remete muito a ideia do Design by Contract. Eu não entendo muito, ainda não comprei seu livro 😅(esperando a versão Clojure 😝), mas será que isso anularia a existência de um V.O? Claro, levando em consideração a complexidade do que se queira representar? Obrigado pelo conteúdo!
@otaviolemos Жыл бұрын
Aristóteles, beleza? Gostei do teu nome! :) Então, veja, você pode fazer algo parecido com um VO para algum caso mais complexo, mas o que eu disse é que a parte de validação na criação eu não faria com essa abordagem de supor que o dado virá limpo já, entende? No livro Applied Clojure ele mostra uma abordagem funcional de modelagem de um tipo Money. Achei ótimo e, para falar bem a verdade, bem parecido com a modelagem OO.
@otaviolemos Жыл бұрын
Eu comento ela nesse vídeo aqui: kzbin.info/www/bejne/f4Okc2t9fbtricU
@lucasxciv Жыл бұрын
Acho que a abordagem de domínio rico cria um código mais defensivo, principalmente com a ideia de ter entidades sempre em um estado válido. Nesse exemplo funcional, apesar de ser mais simples, me parece mais suscetível a ter inconsistência no banco de dados.
@otaviolemos Жыл бұрын
Por quê? A mesma diligência que você usa para validar os objetos, você usa para validar o dado entrando na API. Dá na mesma em termos de consistência.
@lucasxciv Жыл бұрын
@@otaviolemos, acho que a possibilidade de criar uma estrutura de dados inválida e persistir é onde está o risco. No caso de domínio rico, por exemplo, mesmo que fosse implementado alguma nova entrada de dados que estivesse inválida/incorreta, o objeto em si não permitiria ser criado/clonado para um estado inválido. Me parece que o próprio objeto conhecer os estados que pode assumir, no nível de código, seria mais seguro. Não sei se isso seria um acoplamento temporal, porque apesar de serem objetos/funções diferentes, a função de validação teria sempre que ser executada primeiro. Enfim, só alguns questionamentos que surgiram vendo esse estilo de arquitetura.