Ótimo conteúdo, professor. Gostaria de saber como funcionaria a atualização de dados seguindo essa arquitetura. Por exemplo, ao receber novos valores para determinados campos, como devo fazer essa criação do objeto?
@DelPieroJoga104 жыл бұрын
queria sua opinião a respeito da aplicação do Single Responsibility Principle aplicado nesse projeto : github.com/tgmarinho/gobarber-api-gostack11/blob/master/src/modules/users/services/CreateUserService.spec.ts onde cada classe "service" possui apenas um método execute. Seria melhor ter feito por função em vez de usar uma classe só para isso? se sim, como eu conseguiria injetar dependecia sem ser por classe? vlwww
@_prototype55324 жыл бұрын
UP! Responde ai professor!! também quero saber
3 жыл бұрын
A partir desse momento a função que você deseja chamar precisa receber suas dependências como parâmetro. Uma forma de contornar isso é criar uma função que recebe como parâmetro as dependências, ela vai chamar a função "original" passando as dependências e retorna pra ti um callback que você pode chamar apenas com os valores que precisa. Segue um exemplo: pastebin.com/hP4sYknH
@felipemoreira42863 жыл бұрын
Obrigado por compartilhar aqui no youtube todo seu conhecimento adquirido durantes anos de estudo e dedicação! Eu vejo como algo muito nobre da sua parte, parabéns pelo trabalho! Estou buscando aprender com os melhores e entender como melhor meu código e evoluir na programação, e esses videos estão ajudando muito!
@igorlmfs4 жыл бұрын
Gostei bastante professor, encontrei algumas vantagens na implementação com Either e como eu fazia habitualmente. Apesar do código ter ficado um pouco mais extenso, o que não é um problema, acho que os erros específicos separados em cada camada com o uso do Either trouxeram uma semântica bem boa, me parece bem agradável e fácil de entender. Definitivamente vou migrar para algo parecido em um próximo projeto, haha. Valeu por essa sequência de vídeos, mostrou uma solução bem elegante para um impasse que eu já tinha faz alguns anos, nunca fiquei totalmente satisfeito com as soluções que eu encontrava por aí e nem com as que tentei propor (cheguei em algo que julgava satisfatório, mas, não gostava muito da semântica do código, pelo fato de parecer ser um GO-TO direto para as controllers, hahaha).
@otaviolemos4 жыл бұрын
Boa Igor! Eu fiquei contente com essa implementação também. Pretendo seguir esse padrão nos meus projetos, inclusive na plataforma theWiseDev. Se em algum momento eu vislumbrar uma melhoria, faço outro vídeo... 😄
@gabrieloliveiranet3 ай бұрын
Either não seria over engineering? Na minha percepção o código parece mais lento, mas na prática ele não está substituindo o try catch?
@tdias252 жыл бұрын
Curti muito essa abordagem na primeira vez que li o artigo do khalil, só ficava com pé atrás na da verbosidade (muitos IFs) e da observabilidade, porque usar logs com exceptions é um pouco mais "fácil", agora dei uma revisitada nele porque tô começando um projeto pessoal do zero e o objetivo é testar algumas técnicas, uma delas é não usar exceptions, eu também tirei o Result, mas tô vendo como fica mudar as nomenclaturas de "left" para "error" | "isError()" e do right para "isOk()" ou "isSucess()" e "value()", pensei também em trazer o Result.combine() retornando um array de erros porque é muito útil agrupar todos os erros juntos e passar pra frente ao invés de fazer um trabalho mais manual para cada um (óbvio que tem cenários que separado vai ser melhor) Seguindo essa abordagem no controller eu tenho uma HttpResponseFactory, que usa generics de acordo com o retorno do UseCase, lá eu mapeio o código http correto e a mensagem do erro. Somado à isso, todos os meus erros de domínio tem um pai que facilita meu trabalho pra mapear pra http, por exemplo: InvalidDomainArgumentError pode facilmente virar um erro 400, UnexpectedDomainError pode virar 500, e assim vai, daí eu não preciso mapear todos os erros dos Value Objects ou Use Cases manualmente. Na questão das possíveis exceptions de baixo nível, camada de infra etc, eu uso só um try catch que fica antes de chamar o controller, assim eu consigo converter qualquer erro em um Internal Server Error e fazer o log disso, nenhum controller se preocupa com try/catch Video Excelente como sempre!
@ClevertonHeusner4 жыл бұрын
Quando sai um curso de clean architecture?
@otaviolemos4 жыл бұрын
Ano que vem! :) Precisamos desenvolver um mvp da plataforma www.thewisedev.com.br O curso começarei a gravar semana que vem, provavelmente...
@ClevertonHeusner4 жыл бұрын
@@otaviolemos Ótimo.
@pauloafpjunior4 жыл бұрын
Ficou muito top. Ansioso para ver o código completo.
@otaviolemos4 жыл бұрын
Obrigado Paulo! Fiquei contente com o resultado também. Vou ver se coloco até semana que vem... (no vídeo de quinta eu falo sobre comunicação com o banco na Clean Architecture)...
@pauloafpjunior4 жыл бұрын
@@otaviolemos que legal
@matheusdasilvabraga7194 жыл бұрын
Olá, percebi que são feitas duas validações: controller e domínio. Não estaria duplicando a mesma validação entre camadas? Na minha visão as camadas de baixo nível fariam o tratamento dos erros gerados pelo domínio, por mais simples que seja. Parabéns pelo conteúdo!
@otaviolemos4 жыл бұрын
Matheus, as validações do email e do nome são feitas apenas na camada de domínio. No controlador apenas verifico se o dado vem no body da requisição. Repara que são tipos diferentes de validação: um é semântico e outro apenas de existência ou não do dado. Ou seja, não há duplicação: são validações de natureza diversa...
@brunoluz68764 жыл бұрын
Show professor! E aumentar o tamanho da fonte é Show++ (ajuda muito) ! Uma pergunta: No minuto 3:30, seria uma boa opção retornar uma lista de erros ao invés de um erro por vez ? Digo isso pois os dois parâmetros pedem vir errados e o usuário já fica sabendo de uma vez, economizando assim algumas requests.
@otaviolemos4 жыл бұрын
Obrigado Bruno! Então cara, eu prefiro deixar assim, lidar com um erro de cada vez. Não se esqueça de que no front-end provavelmente haverá uma pré-validação simples no JS para não entrarem dados esdrúxulos. De qualquer forma assim a gente mantém a consistência do domínio nele mesmo. Repare também que eu deixei as validações do Email e do Name como método estáticos e públicos. Dessa forma alguém pode reusar essas validações em outro lugar do sistema. Email.validate(string) valida se a string é um email válido, por exemplo...
@pauloCosteira4 жыл бұрын
Esta vídeo aula faz parte de um curso? Tem alguma playlist? Onde encontro seus cursos? Tem a mesma pegada do Rodrigo Manguinho
@otaviolemos4 жыл бұрын
Opa, respondi lá no LinkedIn... 😄
@evertonverton64282 жыл бұрын
Eu acho q tem muita coisa dentro deste controller. O prof poderia colocar alguns deste use cases,como o send email, como um servico de app e transferir esta orquestracao para o usecase principal ai o controller so ficara responsavel pelo pela parte de http. Ate porque se vc quiser usar estes user case em outro vai ter de repetir esta orquestracao.
@otaviolemos2 жыл бұрын
Sim, eu já fiz isso faz um bom tempo. Tenho um caso de uso que chama dois sub-casos de uso. Aí essa lógica foi transferida para o caso de uso. Aqui o controlador github.com/otaviolemos/twd-clean-architecture-api/blob/master/src/web-controllers/register-user-controller.ts E o caso de uso github.com/otaviolemos/twd-clean-architecture-api/blob/master/src/usecases/register-and-send-email/register-and-send-email.ts
@evertonverton64282 жыл бұрын
@@otaviolemos O video e de 2020 kk
@FernandoCezarChaves4 жыл бұрын
Po que massa essa implementação com o Either, usei ele a um tempo atras no java e gostava bastante de como as coisas eram retornadas
@otaviolemos4 жыл бұрын
Opa, tá na mão: export type Either = Left | Right; export class Left { readonly value: L; constructor(value: L) { this.value = value; } isLeft(): this is Left { return true; } isRight(): this is Right { return false; } } export class Right { readonly value: A; constructor(value: A) { this.value = value; } isLeft(): this is Left { return false; } isRight(): this is Right { return true; } } export const left = (l: L): Either => { return new Left(l); }; export const right = (a: A): Either => { return new Right(a); };
@devaguia4 жыл бұрын
Excelente vídeo professor, e falando em tratamentos nas camadas, me surgiu uma dúvida: Qual a relação da Clean Architecture para a Onion Archictecture e a Hexagonal Archictecture, são variações da mesma coisa certo, quais pontos elas mais se diferenciam ?
@otaviolemos4 жыл бұрын
São arquiteturas similares! Veja, segundo o próprio Robert Martin, que propôs a CA: “Over the last several decades we’ve seen a whole range of ideas regarding the architecture of systems. These include: • Hexagonal Architecture (also known as Ports and Adapters), developed by Alistair Cockburn, and adopted by Steve Freeman and Nat Pryce in their wonderful book Growing Object Oriented Software with Tests • DCI from James Coplien and Trygve Reenskaug • BCE, introduced by Ivar Jacobson from his book Object Oriented Software Engineering: A Use-Case Driven Approach Although these architectures all vary somewhat in their details, they are very similar.”
@pauloafpjunior4 жыл бұрын
Professor, vendo seu vídeo novamente, duas perguntas me vieram: (i) no método _exists_ , do repositório de usuário, você valida novamente se o email é válido ou confia no que o caso de uso passou? e (ii) ainda no repositório de usuário, o método _add_ verifica se o usuário já existe antes de adicioná-lo na base de dados?
@otaviolemos4 жыл бұрын
Opa, vamos lá. (i) não faço validação de novo no exists pois se eu consegui criar um objeto User é porque os dados estão válidos (e acredito que isso não é responsabilidade do repositório que só deve recuperar e gravar dados); (ii) o add da mesma forma não verifica novamente se usuário está lá: só tenta adicioná-lo no repositório.
@pauloafpjunior4 жыл бұрын
@@otaviolemos entendido. Obrigado
@felipegoncalves70163 жыл бұрын
Muito legal a implementação... Fica bem claro de onde cada erro esta vindo. Vale a pena usar o Either para erros não tratados ? Por exemplo, ter uma classe de erro "genérica" para uma determinada camada da aplicação (repositories, por exemplo) e usar um try catch devolvendo essa classe de erro caso algo de errado aconteça ali ? Outro ponto, em uma função que faz uso de outra função que também utiliza o Either, devo declarar na assinatura o erro que pode retornar da função "de baixo" ?
@otaviolemos3 жыл бұрын
Fala Felipe, beleza? Eu acho que eu falo mais sobre isso no vídeo sobre a API em Clean Architecture e Node.js. De qualquer maneira na Imersão Clean Architecture vai ter esse assunto também (estou usando essa estratégia na aplicação que utilizarei).
@leandromartins69352 ай бұрын
Gostei da abordagem mas acho que o codigo acaba adotando um over engeneering... em alguns casos menos é mais
@Thelimbers72 жыл бұрын
Github repository?
@igorlmfs4 жыл бұрын
Professor, mudando de assunto completamente, sei que você está usando node.js e javascript como linguagem. Mas, você já deu uma olhada no Benchmark do PHP com Swoole? Ele tem uma ideia parecida com o event loop do Node.JS, mas, me parece que ele é consideravelmente mais performático. Parece que é muito utilizado por empresas chinesas, como o Baidu (tipo o Google de lá) e a Tencent (que atua em vários segmentos, games...). Até me assustei com o quanto ele é mais rápido que o Node.JS em alguns benchmarks.
@hansschenker4 жыл бұрын
Es possible que facer esto presentation tambien in ingles! Es un muy buen exemplo por architectura solide! You have more than you show: kzbin.info/www/bejne/n5abq4ilnamijLs