[MÚSICA] [MÚSICA] Olá a todos! Meu nome é Eduardo Guerra. Estamos no curso de padrões de projeto. Nesse hands on eu vou mostrar para vocês o padrão composite. A gente vai fazer exemplo que a gente tem trechos aéreos. Então, como que seria a gente ter aqueles trechos com conexão ou com escala, que vão ter uma certa diferença relação ao trecho aéreo simples. Então, no caso aqui, eu já tenho a minha classe TrechoAereoSimples. O meu trecho aéreo ele tem a origem, tem o destino, quanto custa e a distância. Então, eu tenho simplesmente aqui o construtor e os métodos getters. Vamos ver como é que seria para fazer trecho com escala. Então, eu vou vir aqui. Escala, então, a diferença entre escala e conexão: escala é aquele que o avião pousa, você não sai do avião e ele decola novamente; a conexão é aquele que você tem que normalmente descer no aeroporto e trocar de aeronave. No nosso exemplo aqui, a gente vai ter uma pequena diferença aqui no custo. Quando a gente fizer, por exemplo, uma conexão, a gente vai ter que pagar uma taxa do aeroporto. Não sei se é assim que funciona, mas no nosso exemplo vai ser. Então, a primeira coisa que eu vou fazer é criar o meu teste. Então, eu vou criar aqui: 'TesteTrechosCompostos' e vamos começar a fazer aqui. Adicionar o JUnit ao projeto e mandar brasa. Então eu vou colocar aqui 'trechoComEscala'. Escala seria o mais simples. Então, eu vou criar primeiro dois trechos simples, 'TrechoAereoSimples', 't1 = a new TrechoAereoSimples'. Então, a origem aqui eu vou colocar aqui. Eu vou chutar porque eu não sei os nomes dos aeroportos, eu sei que Guarulhos é GRU. Então, eu vou colocar aqui Fortaleza, o custo vai ser duzentão e a distância, que também eu não sei a distância de cabeça, vai ser aqui 400. Pronto. Eu vou criar aqui o t2, que seria o outro trecho aéreo. Então, por exemplo, Fortaleza-Natal, FOR e NAT. Eu teria aqui custo de 150 e a distância [INAUDÍVEL] Lembrando que aqui tem que ser o t2. Aqui, vamos lá. Eu vou ter aqui 'TrechoAereoComEscala', 'escala = new TrechoAereoComEscala', aí eu passo ali o t1 e o t2. Qual é o meu resultado esperado? Aqui, para facilitar, eu posso até já criar essa classe aqui. Então, cria a classe 'TrechoAereoComEscala'. Aí ficou trecho. Eu quero 'TrechoAereoComEscala' aqui, criar classe, trecho. Aqui eu vou tirar do test e criar lá no source. Aí você pode falar: mais aí então você vai o quê? Você vai herdar aqui do 'TrechoAereoSimples'? Não. O que que eu vou fazer aqui? Eu vou vir no 'TrechoAereoSimples' e vou extrair uma interface, porque se eu criar aqui uma herança, eu simplesmente vou ignorar todos os dados aqui do 'TrechoAereoSimples' e não é isso o que eu quero. Não seria correto fazer dessa forma. Então, eu vou vir aqui e vou fazer assim: Refactor, extract Interface. Então, eu vou marcar aqui todos os métodos get que ele tem e eu vou chamar simplesmente de 'TrechoAereo'. Então, eu criei aqui a interface 'TrechoAereo', dá para mostrar para vocês. E aqui no 'TrechoAereoComEscala' eu vou fazer aqui: implements Trecho Aereo. Ele vai reclamar que não tem os métodos e eu vou adicionar aqui, certo? Olha lá, eu vou fazer cada ainda. Eu salvo aqui, ainda não está OK, ainda eu preciso implementar aqui o meu construtor. Então, eu criei aqui o construtor trecho e trecho dois. Eu vou guardar aqui 'private TrechoAereo t1'. Por que que não podia ser 'TrechoAereoSimples'? Eu posso ter voo com escala e dos trechos dele também tem escala. Não tem problema nenhum. Então, eu tenho que usar aqui realmente abstração. this.t1 = t1 e this.t2 = t2. Aqui poderia ser inicial, final. Então, vamos lá! Agora que eu já fiz compilar aqui, até implementei pouquinho, eu vou voltar para o nosso teste. O que que é o esperado aqui? Qual que é o esperado ali para a origem do trecho com escala? Que a origem seja o primeiro não é? Então, 'escala.getOrigem' tem que ser o GRU, o final tem que ser Natal. Então. 'escala. getDestino' tem que ser o final do último trecho. No caso aqui o valor eu vou somar e a distância eu vou somar também com 'assertEquals'. No caso ali, a distância vai ser 350 escala ponto. Deixa eu ver qual que ficou primeiro se é a distância. Então, não, primeiro é o custo não é? escala.getCusto 350 e ponto get Distância vai ser 600. Pronto, eu vou rodar aqui. Falhou, não é? Não fiz nada ainda. Então, aqui na minha escala, na hora de retornar a origem, eu vou retornar a origem do t1. Na hora de retornar o destino, eu vou retornar aqui o destino do t2. O custo eu vou somar. Então fica t1 ponto getCusto mais t2 ponto getCusto e aqui na distância eu vou estar somando também, certo? Eu vou ter aqui 't1.getDistância' mais 't2.getDistância', certo? Então, eu vou gravar aqui. Será que vai dar certo agora? Deu sim! Bom, qual vai ser o meu próximo teste? Uma coisa que eu tenho que perceber é o seguinte: olha, ele está indo para Fortaleza e esse aqui está saindo de Fortaleza. E se eu tiver trechos aqui que não se encontrarem não é? Então, eu vou criar aqui 'trechoComEscalaAeroportosDiferentes'. Então, por exemplo, eu imaginei que ele foi aqui para BSB, que é Brasília, e o outro sai de Fortaleza. Na hora que eu criar 'trechoComEscala', é para ele jogar erro. Então, eu vou colocar aqui 'expected' por exemplo 'RuntimeException', que é bom fazer para eu poder criar a minha própria exceção. Eu vou rodar aqui. Não deu erro. O que que eu tenho que fazer? ir lá fazer. Na hora que ele criou o voo aqui. Verificar se o destino do t1 é igual à origem do t2. getOrigem, certo? Então se isto aqui não for verdade eu vou jogar uma exceção. Então eu vou dar aqui throw, new, RuntimeException, certo? Ver se vai dar certo agora. Olha, deu certo. Eu acho que o primeiro teste tem que continuar passando. Então vamos lá. Eu vou criar agora aqui o meu trecho com conexão. Vou chamar TrechoAereo. Bom, na verdade eu posso até fazer assim olha: eu posso aqui tirar este com escalas aqui, certo? Só criar o new e já vai dar o erro. Então aqui trechoComConexao. Então eu vou criar aqui TrechoAereo, new TrechoAereoComConexão. E aí aqui na conexão eu vou querer passar valor a mais. Por exemplo, eu vou passar aqui 80 que vai ser a taxa do aeroporto. Aí isto daqui vai ter que ser somado no custo, de 350 mais 80 tem que dar aqui 430. Então eu salvo, aqui vou ter que criar esta classe. Criar classe. Olha, já adicionou aqui. Vou adicionar return, tá? Aqui eu vou ser esperto, porque o com escala já tem praticamente tudo que eu preciso. Então eu vou apagar tudo isto daqui, aí vou fazer assim e ele estende né, TrechoAereoComEscala. Aí aqui adiciona o construtor, só que aqui eu vou querer ter o tarifaConexão, certo? Que vai ser ali chama ele de super e depois ele gera ali a tarifa da conexão. Muito bem. Então o que eu vou fazer aqui agora é sobrescrever, Override/Implement Methods, ele vai sobrescrever getCusto que é o único que é diferente. É que ele vai delegar ali para a super classe e vai somar uma tarifa ali de conexão. Eu rodo ali, deu certo. Bom, vamos ver se este composite está legal mesmo? Para ver que ele está legal, a gente vai criar composite do composite. Ou seja, a gente vai criar voo que tem escala e aí vai fazer voo que tem conexão, usando este voo sem escala. Será que dá certo? Eu vou usar como base aqui este primeiro. Aqui eu vou até renomear aqui para ficar mais coerente, né? Chamar aqui de 'conexão'. Então eu criei este aqui com escala, agora eu vou criar aqui trecho t3. Ele vai aqui de Natal para Brasília. Ele teria aqui custo aqui no t1 de 300, 250 e a distância de 300, tá? E aí eu vou criar aqui agora uma conexão entre a escala e t3. Note que eu estou usando a escala como trecho aéreo. Como é uma fração aqui eu posso fazer isto. Aqui eu vou colocar cinquentinha aqui no custo da conexão. Então a origem tem que ser GRU, aqui vai ter conexão. Aqui vai ter EscalaEConexão. Então vamos lá. Aqui GRU, final seria BSB, que é o final aqui do trecho 3. O custo ficaria 200, mais 150, mais 250, aqui dá 600. Mais os 50 aqui da conexão daria 650. A distância 400, mais 200, mais trezentos, seria 900. Será que vai dar certo? Não sei não. Vamos ver. Eita, funcionou, que beleza. Então a gente viu aqui o composite, como é que a gente pode ir encadeando as coisas. Imagina aí como que seria complicado você fazer este encadeamento de voo. Então todas estas regras ficou aqui bem enxutinho cada uma as regrinhas de negócio. E como seria complicado, por exemplo, pegar, por exemplo, uma lista de três para fazer esta conta, certo? Então é isto. Espero que com este exemplo vocês tenham podido entender melhor o padrão composite. Muito obrigado. Vejo vocês na próxima aula. [MÚSICA] [MÚSICA]