[MÚSICA] [MÚSICA] Olá! Bem vindo ao Curso de Orientação a Objetos com Java. Eu sou Clovis Fernandes. Hoje iremos falar sobre identificação de dependência. Geral, as dependências mais complexas, visando aplicar uma nova técnica, novo príncipio chamado Law of Demeter, Lei de Demeter. Anteriormente nós identificamos acoplamento alto devido ao uso de getters e setters de classe, que permitiam expor os dados internos pulando o encapsulamento. Na aula de hoje, nós iremos mostrar que getter e setter quando devolvem algum objeto, não apenas dado, tipo string, int, double, quando ele devolve algum objeto que é atributo de algum relacionamento dentro da aplicação, isso também causa acoplamento indevido e indesejado, muito grande por sinal. Para isso nós vamos usar, aquele princípio, tell don't ask, que foi mostrado anteriormente, que continua se aplicando, a técnica de delegação, ou redirecionamento e esse novo princípio que a gente costuma chamar de LoD. Law of Demeter, para resolver esse acoplamento que ocorre, devido ao acesso a objetos através de getters, expõe objetos indevidamente. A ideia dessa aula é meramente levantar e apontar esses problemas, nós não vamos mostrar ainda a Law of Demeter, nós vamos apenas mostrar, que essa exposição dos objetos de classes da aplicação, não é uma coisa boa, nós vamos mostrar que isso é mau, é muito ruim para o projeto, porque causa dependências indevidas, dependências desnecessárias. Como a gente havia falado, até agora nós mostramos o uso inadequado de getters de estruturas de dados, de getters de atributos do tipo int, string, double. Nós queremos examinar hoje o que pode acontecer, quando o getter devolve objeto de uma outra classe da aplicação, eu não estou falando de classes que são do próprio Java, como por exemplo, string, é uma classe do próprio Java, não, isso aí é uma classe que te ajuda a desenvolver e você não tem o que fazer, porque ela é dada, ela é imposta pela linguagem. Então, se eu tenho uma outra estrutura de dados também como BigDecimal, por exemplo, que eu vou usar para demonstrar depois, não tem o que fazer, então a exposição de objetos que são usados como básicos para a linguagem Java, isso não nos interessa, o que nos interessa aqui é o getter que devolve objetos de classes que eu estou projetando na minha aplicação, que são da minha aplicação. Eu vou usar como exemplo sistema de logística, que eu estou chamando de SL, que faz o calculo do frete, e para isso ele precisa calcular o peso total da mercadoria, é isso que eu vou exemplificar. Eu tenho a classe Frete aqui, ela é uma classe que tem o construtor, tem objeto do tipo PedidoVenda, internamente tem uma variável de instância que então é do tipo pedido, e quando o construtor é executado, ele coloca esse parâmetro, esse objeto PedidoVenda pedido, e tenho o método getPesoMedida, que volta o peso BigDecimal, que é uma estrutura de dados parecida com o double, o integer, mas é uma classe, ela se chama BigDecimal, porque ela ajuda você a trabalhar com números muito grandes, se você trabalha com integer ou double, pouco tempo isso esgota o tamanho máximo na máquina, e com BigDecimal, o número pode ficar até tamanho extremamente, excepcionalmente grande. A função da getPesoPedido, como está marcado aí, é obter o peso total do pedido, para isso ele cria uma variável pesoTotal e inicializa como BigDecimal 0, zerado. Aí seguida tem uma lista, que é seguida através de for, que eu acesso da classe Pedido, o getItens e devolve uma lista de itens de pedido, então eu tenho pedido e aí eu tenho uma lista de itens de pedido, normalmente estes itens vão de 0, se não tem itens nenhum até 10 por exemplo, 20 dependendo do tamanho da nota do pedido que você está fazendo, e aí fica personalizado cada item de pedido aí dessa lista que o getItens devolve. Bom aí tem uma expressão apenas ali dentro que é o pesoTotal igual a pesoTotal.add, pesoTotal tinha começado com 0, eu vou somar agora com pesoTotal de cada item, aí eu vou acumulando, ele é acumuladores. Aí eu pego o item e mando a mensagem getProduto, então com isso item getProduto me volta produto, então lembrem-se que eu tenho a classe Frete, a classe pedido, que está associada a pedido, o pedido está associado a item de pedido, cada item de pedido tem produto, então eu acesso o produto aqui. Aí eu mando, pegar o peso, o getPeso é método da classe produto, ele vai me voltar o peso BigDecimal do produto que eu estou olhando naquele momento, aí ele multiplica isso com a quantidade, multiply aí é método de BigDecimal, passa como parâmetro o getQuantidade de item, item é do ItemPedido, então tem a quantidade, então estou sendo exposto aqui no caso, a getter também, no final ele devolve o peso total. Relembrando então que o objetivo dessa classe é obter o peso total do pedido, isso é importante, porque quando a gente for refaturar, aperfeiçoar, tirar as dependências indevidas que existem aqui, isso vai ser importante, a considerar. As classes que estão envolvidas aqui de cara, aquelas que aparecem como classe, é a PedidoVenda, está lá no construtor, está na variável de instância também, o BigDecimal, o ItemPedido, então a gente tem essas 3 classes que estão, explicitamente aparecem no trecho do código, PedidoVenda, BigDecimal e Item pedido. A BigDecimal, como eu havia dito não vamos considerar porque ela é uma classe da linguagem Java, do pacote Java, então não nos interessa aqui. Será que são apenas essas classes que o Frete depende? Quando nós vimos, logo quando eu mostrei a classe Frete, não é bem isso não é? Ficou alguma coisa escondida ali, nós temos aqui, 4 getters, pedido getItens, item getProduto getProduto, depois o getPeso e o getQuantidade, item getQuantidade, então são 4 getters que nós temos aqui. O getItens, ele é getter da classe Produto e ele volta uma lista de itens de pedido, que podem ser de 0 a número qualquer que eu vou exemplificar que vai ser de 0 a 10. O getProduto, ele é getter da classe ItemPedido e ele volta o produto que está associado aquele item de pedido, já o getPeso, ele volta alguma coisa BigDecimal, ele é da classe Produto, o getQuantidade ele também volta BigDecimal, poderia não ser, nesse exemplo ele volta BigDecimal, e ele é da classe ItemPedido. Então vocês percebam que nós falamos de classe Produto, ItemPedido, Venda, e Frete, dessa forma, a classe Frete, ela depende explicitamente da PedidoVenda, por que é que é explicitamente? Porque a variável de instância PedidoVenda, está lá explicitamente Frete, ele passa o valor, quem é o pedido naquele momento pelo construtor, então explicitamente existe uma dependência. Já as outras classes ItemPedido e Produto, elas aparecem de maneira indireta, através do PedidoVenda, então a gente chama que isso é uma dependência implícita, é uma dependência que ficou ali escondida, que apareceu e provavelmente ela é indevida, como nós vamos mostrar. Gostaria de ressaltar getPesoMedida que é o nome do método da classe Frete que nós estamos examinando, ele é falso getter, ele só tem lá get ali, mas na verdade ele é falso getter, porque no fundo ele está fazendo muita coisa, nós vamos ver que depois isso é inadequado, mas ele está fazendo muita coisa que não corresponde a simples get, que é simplesmente voltar o valor de uma determinada variável ou voltar determinado objeto. Qual é o problema que nós estamos vendo nessa classe Frete? Os dados estão expostos também, eles não são dados do tipo string, Double int. Mas eles são dados de relacionamento. São classes, são objetos de classes da minha aplicação. Mas são os dados então que estão explicitamente expostos. Nós temos algo, o getItens que ele me volta uma lista de itens de produto. Então ItemProduto está exposto. Quer dizer, todos os objetos do tipo ItemProduto que está naquela lista estão expostos. Através do getProduto, eu tenho objeto que está exposto que é o produto. Então isso também não é uma coisa boa. O getPeso que retorna algo do tipo big decimal e pertence à classe produto, ele esta expondo o valor do peso do produto. Mas no caso, devido à característica especial da classe produto, ele é tipo de uma classe que a gente chama de repositório de dados. Não tem muito problema do dado peso ser exposto porque a classe foi construída exatamente para isso: para manter valores do produto e serem expostos para quem necessita. Pode ser feito de alguma outra maneira, aplicando o princípio do "Tell, don't ask"? Pode. Mas você acaba querendo fazer alguma coisa que faz perder muito mais tempo e não tendo retorno muito grande. No caso dessa característica esse getPeso não é considerado get, getter, vamos dizer assim maléfico. O getQuantidade é get da classe itemProduto. O valor que ele devolve é o BigDecimal também mas poderia ser int, por exemplo. Estou mostrando agora para vocês o diagrama de classes, incluindo as dependências, desse sistema que gira ao redor do frete. Então nós examinamos que tem 4 classes: a própria classe frete e tem uma dependência explícita com o PedidoVenda ali no getPeso Pedido de Frete. Claramente ele faz uso do getItems e existem 3 dependências implícitas que eu diria sim que são ocorrem por causa da dependência com a classe pedido venda que é o getProduto de item pedido, o getQuantidade de item pedido. Por causa desse acesso à classe itemPedido, por causa do getProduto, o frete também depende da classe produto, o getPeso, diretamente. Obviamente, como eu estou mostrando aí, esse é o antes, os dados estão expostos para a classe frete. Essas 3 classes, PedidoVenda, ItemPedido e Produto. Isso não é uma coisa boa. Então aplicando essa, o princípio "Tell, don't ask", a Law of Demeter e o redirecionamento e delegação, a gente elimina essas dependências, tanto as explícitas quanto a implícita. Eu não vou mais precisar saber a informação por exemplo do getItems para frete. Eu vou resolver isso usando o "Tell, don't ask". Eu ordeno para o pedido venda obter para mim o peso. O peso total, é isso que eu quero que seja feito. O que acabamos de mostrar é que o uso indevido do getter que acaba expondo indevidamente tanto dados corriqueiros como do tipo double ou objetos de classes da minha aplicação, isso não é uma coisa boa. Isso causa essa dependência desnecessária. Então, no exemplo que nós mostramos, nós tínhamos 4 dependências explícitas. Nós podemos eliminar essas 4 dependências explícitas assim dessa forma. Na verdade ficar só com uma dependência boa, mas uma dependência boa, não uma dependência ruim. Com isso a gente conclui a nossa aula de hoje, tendo identificado esses acoplamentos que são altos e que se multiplicados por outros métodos e outras classes, tornam o nosso sistema muito complexo e muito difícil depois de mudar e aperfeiçoar. Até a próxima aula. [MÚSICA] [MÚSICA]