Mais um vídeo top! Pelo alto nível das discussões nos comentarios, logo dá para perceber a produndidade nos aspectos fundamentais da programação, nos levando a refletir sobre a importância do código limpo, aequitetura limpa, para um software de fácil manutenção e escala. Tem uma frase que esta grudada na minha mente que ouvi lá no canal do Branas ... "...código escrito por alguém se importa...". Trabalhar sozinho com programação é bom, fiz isso por anos a fio, mas trabalhar em equipe e poder criar soluções com propósito para sociedade, é melhor ainda. Muito obrigado por compartilhar seu conhecimento conosco mestre, e elevar o nível do nosso mercado. Sua didatica com TDD é sensacional, se trouxer mais conteudos sobre testes será sucesso total pois é você fera no assunto. Ah, e parabens pelo dia do professor. Abraço, sucesso e Tamo junto!!!
@otaviolemos4 жыл бұрын
Muito obrigado Renan!!! Tmj!!! 😄
@soudouglas4 жыл бұрын
Muito legal a abordagem! Telefone e email são duas coisas que a gente sempre tá lidando dentro dos projetos e que igual você tinha falado, tem um importância grande pro negócio, não faz sentido ter esses valores quando inválidos. Algo interessante é que quando o valor é "só uma string", eu acabo não pensando tanto no formato e comportamento que ela deve ter, mas olhando o seu código e vendo a classe e os testes exclusivos pro email, realmente fica fácil de dar manutenção e fica claro que email não é "só uma string".
@otaviolemos4 жыл бұрын
É isso aí, Douglas: obrigado!
@157157ricardo3 жыл бұрын
Cara, antigamente eu utilizava Controller, Service, Repository e Models para desenvolver os meus sistemas. Essas eram as estruturas bases, mas ainda tinha mais, como: config, Dto, VO, Validation, em fim, pelo que vi não tem muita diferença, claro que a forma que eu utilizava feria tudo que era padrões e abordagem, mas para migrar pra essa abordagem, não tive dificuldades não, porem quando é um projeto pequeno e que eu sei que não é um sistema digno de escalabilidade, CQRS, costumo fazer da forma antiga. Abraços.
@alvaroduartead3 жыл бұрын
Cara vc é mt top! Obrigado estou aprendendo mt com vc! Clean Architecture MAN
@tdias253 жыл бұрын
Otavio, outro excelente vídeo. Sobre a validação que você colocou num método estático, eu costumo criar setters privado pra encapsular a validação e usar eles logo no construtor passando o parametro, dessa forma eu já crio um objeto imutável e qualquer erro já lança exception, o que você acha disso? achei interessante essa abordagem que você tem um arquivo externo com diversas validações, tinha pra mim que "coisas de domínio" deveriam ser "auto suficientes" com suas próprias validações ou, no caso da validação, algum objeto externo pega nosso objeto de domínio e valida ele, não o contrário
@otaviolemos3 жыл бұрын
Eu mudei esse código mais pra frente e deixei a validação na própria classe. 😅
@tdias253 жыл бұрын
@@otaviolemos vou ver kkk, mas por que você decidiu colocar tudo na mesma classe?
@william902493 жыл бұрын
top era esse padrao de validacao que tava querendo
@brunomachadodasilva25564 жыл бұрын
Boa Otávio! uma pergunta, se fosse começar a ler sobre DDD ou Clean Architecture, por qual começaria primeiro?
@otaviolemos4 жыл бұрын
Obrigado Bruno! Eu particularmente não li nenhum título completo de DDD ainda; só estudei aqui e ali, em particular no site do Martin Fowler. Mas já dei uma olhada no livro mais clássico que é o do Eric Evans. Dessa forma, se eu fosse pegar um livro de DDD para ler hoje, seria o do Eric Evans. Sobre Clean Architecture o melhor mesmo é o Clean Architecture do Robert Martin, pai da criança... :D
@barrajr53692 ай бұрын
Sempre que temos campos para validar, precisamos colocar esses campos no value object, por exemplo campo “password” devemos colocar no value object?
@zanderbrasil4 жыл бұрын
Muito bom o vídeo e a implantação professor, porém quando irá disponibilizar o código para consultas?
@otaviolemos4 жыл бұрын
Logo mais Anderson! Preciso remover o convict, estou usando arquivos com dados sensíveis que não podem ser públicos (info para envio de e-mail). Acho que terei que usar variáveis de ambiente para isso...
@vithor95076 ай бұрын
Uma dúvida, e se eu precisar retornar pro usuário exatamente os campos que deram erro na requisição dele? Por exemplo se o campo for “email_cliente”, com as validações sendo fora dos adaptadores eu não tenho como retornar o “email_cliente é inválido”, porque as camadas internas não devem se preocupar com nomenclaturas externas.
@RicardoSantos-wl1bg4 жыл бұрын
Muito Legal! Otávio, vc já utilizou testes para validação de arquitetura tipo o archunit do java? Conheces algum framework semelhante para typescript? Abraço!
@otaviolemos4 жыл бұрын
Não conheço não Ricardo: vou dar uma olhada qualquer hora! Obrigado...
@ygortorresgaleno96544 жыл бұрын
Fala Ótavio, o que vc acha sobre o uso de middlewares de validação? Por exemplo no caso do required fields, criar um middleware somente para verificar essa validação.
@otaviolemos4 жыл бұрын
Então Ygor, eu acho que depende do tipo de validação que você quer fazer. Parece-me que quando a validação é sobre uma regra de negócio do domínio, o melhor é que seja feita nas entidades mesmo e não em middleware. Isso se você está usando algo como a Clean Architecture, e quer que suas regras de negócio fiquem bem separadas e independentes do restante da aplicação. Entende? Não é obrigatório usar Clean Architecture. Mas parece-me que quando se quer usar, a melhor maneira é essa...
@ygortorresgaleno96544 жыл бұрын
@@otaviolemos mas no caso do required fields ele ta na presentation layer que seria o mesmo layer dos middlewares.
@otaviolemos4 жыл бұрын
@@ygortorresgaleno9654 sim: parece-me que esse tipo de validação, para saber se os dados estão presentes, fica ok nas camadas mais externas!
@splhead2 жыл бұрын
Otavio obrigado pelas dicas mas ainda tenho uma dúvida, como ficaria se eu quisesse usar uma biblioteca externa para validação, poderia??? (nesse caso estaria conhecendo/dependendo a camada mais externa???) ou tenho que fazer minhas próprias validações como você fez para evitar isso?
@otaviolemos2 жыл бұрын
Você pode usar mas eu faria isso em camadas mais externas, entende? Aí você já assume nas camadas mais internas que o dado já virá validado.
@agolegario4 жыл бұрын
Olá Otavio Lemos, primeiramente parabéns pelo canal, Para mim prefiro a abordagem apresentada pelo Eric Evans no conceito de Value Object em seu livro; A regra que aplico na modelagem é que um objeto(classe) que não tem identidade então é passível de se tornar um V.O, como por exemplo uma classe Address aonde essa esta composta de varias propriedades primitivas e também outros value object e que certa forma em algum momento irei precisar comparar esse valor contra outro(imutabilidade); Colocar o e-mail e ou nome como value object talvez faça mais sentido quando se esta utilizando java script, do que outras linguagens fortemente tipadas como Java ou C# já que posso definir esse padrão da mesma forma no set da propriedade utilizando uma classe de regra de negocio para tal; Resumindo ao meu entender um value object é uma classe composta por duas ou mais propriedades que podem ser do tipo primitiva ou outros value object e tem o requisito de ser imutável; Referencia: martinfowler.com/bliki/EvansClassification.html
@otaviolemos4 жыл бұрын
Olá Adalberto, não entendi onde, na sua definição, o meu exemplo fere o conceito. No próprio post do Martin Fowler sobre Value Objects ele fala o seguinte: "It's often a good idea to replace common primitives, such as strings, with appropriate value objects. While I can represent a telephone number as a string, turning into a telephone number object makes variables and parameters more explicit (with type checking when the language supports it), a natural focus for validation, and avoiding inapplicable behaviors (such as doing arithmetic on integer id numbers)." martinfowler.com/bliki/ValueObject.html Até onde vi, meu exemplo segue estritamente o conceito de Value Objects do Eric Evans...
@otaviolemos4 жыл бұрын
E obrigado pelo comentário! :)
@zanderbrasil4 жыл бұрын
Então Adalberto eu vi que você citou linguagens como C# acho legal dar uma olhada nesse artigo do Elemar Junior da Eximia.co falando de tipos primitivos e automática de value objects www.eximiaco.tech/pt/2019/09/03/obsessao-por-tipos-primitivos/
@agolegario4 жыл бұрын
@@otaviolemos Value Object: "Objects that matter only as the combination of their attributes. Two value objects with the same values "for all their attributes" are considered equal. I also describe value objects in P of EAA." Não disse que seu exemplo fere o conceito, O que disse é que a regra que aplico para determinar se um objeto será um value object é: 1) Ter mais de 2 propriedades(primitivas, ou de referencia); 2) Necessidade de ser imutável; Nunca tentei pegar uma simples propriedade de referencia como seu exemplo digo "referencia" pois String em Java e C# , são de tipos de referencia não é um tipo primitivo e torna-la um value object, sempre respeitei a regra citada por Evans ao menos no meu entendimento.
@agolegario4 жыл бұрын
@@zanderbrasil Já tinha visto o vídeo também acompanho o trabalho do Elemar, a técnica de utilizar struct é interessante porém com limitações principalmente no contexto de herança, existem bônus e ônus ao contrario das classes que tem seu valor passado por referencia struct são de fato o valor copiado quando atribuídas, isso ajuda a comprimir a carga de memoria em um servidor web por exemplo se utilizado indiscriminadamente.
@adrianoreis72734 жыл бұрын
Muito bom, tambem não gostei muito das validações ficarem no controlador.
@otaviolemos4 жыл бұрын
Melhor assim, né? :)
@matheusmarabesi4 жыл бұрын
Achei muito legal o vídeo, mas fiquei com uma dúvida sobre os erros, por que retornar um erro e não lançar a exceção?
@otaviolemos4 жыл бұрын
A meu ver fica mais explícito na interface do método o tipo de erro que ele pode gerar. Lançar exceção parece-me mais adequado quando é um caso realmente excepcional: acabou a memória; caiu a conexão, etc. Eu falo sobre isso no próximo vídeo que sai terça. Gravei hoje... 😄
@elissonalvessilva88743 жыл бұрын
Otavio Lemos. Pergunta. Em qual camada ficaria uma chamada a serviços externos utilizar clean architecture e DDD ? Ficaria no domain mesmo ?
@tdias253 жыл бұрын
Fala, Elisson, beleza? Não sou o Otavio mas talvez possa deixar meus 2 centavos aqui Pra ser bem genérico, as abstrações desses serviços externos você poderia criar no domínio ou na camada de casos de uso, as classes concretas dessas abstrações (suas chamadas pra serviços externos) você coloca na camada de infraestrutura, que seriam adapters, repositories, etc
@TheCEMFАй бұрын
Bom, seu comentário faz 3 anos... Se você não correu atrás do assunto, fique sabendo que chamadas a serviços externos ocorrem via implementação de gateways na camada de infraestrutura. O contrato em si deve ficar em camadas mais internas.
@paulovieira80653 жыл бұрын
Boa noite Otávio, Uma dúvida sobre os Value Object tem que ser implementados separadamente? Tipo, o exemplo utiliza só dois dados "Nome e E-mail", mas se tivéssemos 10 teria que ser separados?
@otaviolemos3 жыл бұрын
Sim. Mas a vantagem é que você consegue reusar isso entre sistemas. Já estou reusando esse Email em outro aplicativo aqui.
@romuelm3954 жыл бұрын
Muito bom.
@cardeal13893 жыл бұрын
if ( email instanceof InvalidParamError ) { return new InvalidParamError('email') } => Não é redundante esse trecho, porque `email` já seria uma instância da classe `InvalidParamError`, logo só retornar `email` nao seria o suficiente?
@otaviolemos3 жыл бұрын
Tanto faz retornar ele mesmo ou um novo. Criar um novo é mais 'funcional' no sentido de sempre estar criando objetos em vez de repassá-los. Mas aí no caso, tanto faz (se não me engano até já mudei esse código e retorno ele mesmo).
@maurotrindade66923 жыл бұрын
Grande Otávio, muito bom! Vou refatorar um código aqui agora pra aplicar isso! Tenho um caso aqui que isso vai melhorar muito a legibilidade (depois refatoro o resto tbm). Uma dúvida reparei que você não usa o recurso do TypeScript de já declarar e inicializar os atributos direto no construtor. Algum motivo pra isso?
@maurotrindade66923 жыл бұрын
Caso não tenha ficado muito claro estou falando disso: class A { private att: string // declaro... constructor(att: string) { this.att = att // inicio... } print() { console.log(this.att) } } class A { constructor(private att: string) { } // já declara e inicia... print() { console.log(this.att) } }
@maurotrindade66923 жыл бұрын
Esse recurso pode ser usado com public, private, protected ou até com readonly. E eu sempre uso, queria saber se você tem algum motivo pra não usar ou se é realmente só questão de gosto como é o caso do public nos métodos e atributos (que eu não coloco por já ser o padrão).
@otaviolemos3 жыл бұрын
Fala Mauro: eu conheço sim! Eu acho meio esquisito, para falar a verdade. Mas é mais seguro pois se você errar nas atribuições, pode dar pau e, além disso, mais enxuto. Não sei dizer porque não adotei ainda, talvez seja por achar meio confuso. Vamos ver, qualquer dia eu passo a usar... 😅
@otaviolemos3 жыл бұрын
Em particular acho muito estranho aquele {} sem código nenhum... :)
@maurotrindade66923 жыл бұрын
@@otaviolemos ou seja, é mais uma questão de toc msm, kkkkkkk. Mas é isso aí, estilo tem que ser uma coisa mais pessoal ou da equipe msm (só não pode cada um fazer de um jeito quando é equipe). Valeu! Pensei se podia ter algum outro motivo.
@nicolasassisfabrizzi74313 жыл бұрын
Olá novamente professor, excelente conteúdo como sempre, fiquei com uma pequena dúvida com relação à implementação supondo o seguinte: Um cenário mais complexo, digamos um value object de CNPJ, em que uma lib externa talvez seja usada para auxiliar a validação e que, portanto, um adapter deva ser criado para que esse validator seja instanciado no constructor ou no create de CNPJ. Onde realizamos a criação desse value object? Pergunto isso pois, acredito eu, que ficaria meio 'dirty' instanciar tal objeto (injetando a dependência do validator) direto no create ou constructor do objeto que compõe CNPJ. Será que seria um 'pecado' muito grande realizar a criação de CNPJ no use-case e daí passa-lo como argumento no constructor do objeto que o compõe? Obrigado mais uma vez!
@otaviolemos3 жыл бұрын
Eu faria a validação do mesmo jeito que fiz a do e-mail. Mas você pode certamente fazer a validação em outras camadas; não é pecado... :) A única questão é que é uma regra de negócio que ficará deslocada. Se algum dia você quiser reusar o código, não dá pra simplesmente copiar o Value Object, vai ter que fazer as validações nas camadas superiores. Sacou?
@nicolasassisfabrizzi74313 жыл бұрын
@@otaviolemos Perfeitamente, obrigado!
4 жыл бұрын
Acho que esse método é mais correto, sem dúvidas, porém me preocupa ter que fazer instanceof para tipo possível de erro na validação. Se é possível que o programador esqueça de verificar um tipo de erro, ele provavelmente esquecerá
4 жыл бұрын
Estou considerando o caso onde uma validação pode retornar tipos diferentes de erro, por exemplo EmptyField, ou NullField, ou InvalidEmail tudo isso ao mesmo tempo para validação de email, por exemplo
@otaviolemos4 жыл бұрын
@ num próximo vídeo vou mostrar o que considero a melhor implementação nesse caso. Acho que você vai gostar...
@felr1b3 жыл бұрын
não concordei na parte sobre não validar no construtor. a ideia do OO é vc ter objetos válidos de domínio. em tese, se vc valida no construtor vc impede de construir um objeto inválido.
@otaviolemos3 жыл бұрын
O problema de validar no construtor é que você necessariamente precisa lançar exceção se o objeto está inválido. Usando um factory você consegue retornar o erro em vez de lançar exceção.
@felr1b3 жыл бұрын
@@otaviolemos Entendi. Na minha visão, a camada de domínio deveria sim lançar exceções, pois significa que alguma camada anterior não tratou o input. O que não deveria ser exceção é um erro de input numa camada http, por exemplo (pois é algo comum). No mais, obrigado pelo vídeo e pelos conteúdos.
@adoniasalcantara5222 жыл бұрын
O lado bom de lançar exceções é que você pode tratá-las globalmente, de maneira centralizada, ao invés de ficar espalhando pelo código vários if else, instance of e coisa do tipo
@GabrielSilva-ni4jy2 жыл бұрын
@@adoniasalcantara522 inclusive é o que eu faço. Crio erros customizados de acordo com as regras de negócio, e caso dê algum erro, seja no construtor do objeto, seja em outro lugar, lanço esse erro e trato de forma global seja no Express ou qualquer outra lib/framework que eu estiver utilizando.