[MÚSICA] [MÚSICA] Olá a todos. Estamos seguindo aqui a nossa sequência de refatoração. Eh, no último vídeo a gente moveu, não é, esses métodos aqui para esse classe Movie e como eu falei eu estou tendo pouquinho de coceira com esse switch case aqui, que está meio esquisito, está? Se a gente olhar o Movie aqui, claramente tem 3 tipos de filme, não é? E esses 2 métodos aqui, eles dependem bastante, não é, do tipo de filme para retornar o resultado, não é? Eu enxergo isso aqui como uma refatoração pouquinho mais complicada, que a gente chama trocar condicional por polimorfismo, não é? Então, o que é que eu vou fazer? Eu vou criar novo, uma nova classe. Eu vou criar subclasses de Movie, certo? Para, para que elas cada uma, não é? Vai ter uma subclasse CHILDRENS, uma classe REGULAR e a subclasse NEW RELEASE, para que cada uma trate eh, eh, a forma que, que ele lida com isso. E vamos fazer essa migração aqui aos poucos. Está? Antes de fazer isso, o que é que eu vou fazer? Agora, eu não vou poder mais criar, não é? Se eu tiver a subclasse, eu não vou criar mais a classe Movie, eu vou criar uma das subclasses. Então, o que eu vou fazer é criar método fábrica, está? Para me auxiliar nesse processo de criação. A princípio, ele vai simplesmente chamar o construtor, está? Então, eu vou vir aqui, eu vou dar Control C, Control V aqui e vou criar método estático. É public static, eh. Eh, botar assim oh: create Movie, está? Ele vai receber os mesmos, os mesmos parâmetros, está? Ele vai retornar o Movie. Então, na verdade, quem está chamando não precisa saber se é uma classe, se é uma subclasse. Tem que ser Movie. Está? E aí, a princípio, ele vai retornar, não é? return new Movie. Está? Aí, ele passa ali como parâmetro priceCode e o title. Está? Então, à medida que eu for adicionando as subclasses, eu vou passando a retornar elas, eh, quando for priceCode delas. Está? Então feito isso, eu preciso agora fazer pequeno ajuste no meu teste. Está? Para que, ao invés dele vir aqui e chamar esse new Movie, para ele chamar o create Movie. Então, eu vou vir aqui, eu vou modificar o Movie aqui, ele vai chamar o create Movie, está? Eh, eh, onde ele vai estar passando ali o título e o type. Está? Note que, por exemplo, isso daqui, apesar de ter sido uma mudança simples de fazer aqui no teste, é uma mudança de interface. É uma mudança de API, ou seja, a forma que eu crio o filme daqui para a frente, ela é diferente. Está? Então, normalmente, esse tipo de mudança que afeta, não é só interna, que afeta como as outras classes, eh, utilizam, criam a sua classe, elas costumam ter impacto maior. Isso aqui no caso, a gente está observando porque a gente está precisando alterar o teste, não é? Felizmente, a gente tem, criou esse método rentMovie aqui, que facilita isso para a gente, mas, eh, eh, precisamos, a gente precisou alterar o teste para poder fazer isso aqui. Então, vamos, vamos ver se o teste continua funcionando com essa alteração. Okay. Eu vou inclusive vir aqui na classe Movie. Eh, eh. Não, vou deixar ela assim mesmo. Então, a primeira coisa que eu vou fazer, eu vou vir aqui e vou criar uma nova classe, que vai ser a classe do regular. Então, eu vou vir aqui, New Class. Eu vou chamar de regular. Está? A superclasse dele vai ser a classe eh, Movie. Está? Eh, pego uns construtores, abstract, okay. Finish. Está? Então, aqui. Por exemplo, nesse regular, eu não preciso do priceCode. Está? Eu posso passar aqui, direto para ele, o regular, não é? Porque vai ser sempre o regular. Então, aqui eu já posso tirar esse priceCode aqui do meu, da minha classe, está? Então, agora eu vou vir aqui, eu vou, eh, eh. Ver aqui, oh: generate overwrite implement methods. Eu vou colocar aqui na, na minha classe regular os métodos getFrequentRenterPoints e o getAmount, está? E aí, eu vou vir aqui na minha classe Movie, vou, eh, copiar aqui, não é, a lógica, não é. Pegar aqui, eh. Aqui, eu não preciso mais do switch, nem do case. Está? Mais igual 2. Eu posso já começar aqui com 2, não é? Se a quantidade de dias for maior que 2, então ele faz aquela continha ali. Está? E aqui, eu vou dar return thisAmount. Ótimo. Eh, vou salvar, está? Eh, aqui, eu vou voltar na classe Movie, vou ver o FrequentRenterPoints. Para o caso do regular, vai ser sempre 1, não é? Então, eu vou simplesmente, vou vir aqui, vou dar return 1 e vou salvar. Está? Bom, eu já tenho a classe regular. Eu preciso que o meu código utilize essa classe. Então, o que é que eu vou fazer? Eh, aqui, no meu createMovie. Está? Eu vou verificar se o priceCode que ele está passando é igual a regular. Então, ele vai vir aqui e vai dar return new Regular, está? E ele vai eh, colocar o title ali como parâmetro. Será que está funcionando? Está? Então, agora quando ele for regular, ele já vai estar utilizando a minha subclasse. Está? Vamos rodar os testes aqui. Eh, vamos lá, torcer para funcionar. Tudo funcionando, podemos continuar. Uma parte que eu gosto muito na refatoração é deletar código. Está? Então, eu posso vir aqui e destruir todo o case do regular no método getAmount. Está? Aqui no getFrequentRenterPoint, não consigo ainda, certo? Então, eu vou vir aqui, vou salvar. Eh, eh. [SEM_ÁUDIO] Então, seguindo o exemplo, eu vou criar o método, a classe Childrens. Vamos lá. Childrens. Para fazer. Não, vou começar, vou seguir, vez de seguir para o Childrens, vou seguir para New Release. Está? Eh, da mesma forma, eu já vou vir aqui dizer que a classe Movie. Está? Ele, que a superclasse dele é Movie, vou dar finish, está? Aqui, da mesma forma que eu fiz, eu posso dizer aqui que ele eh, que aqui, ele tem, ele recebe como parâmetro o newRelease, está? E posso apagar esse priceCode aqui, certo? Eh, inclusive aqui. Se eu quiser, eu vou fazer pouquinho diferente só para vocês verem como que na refatoração é importante você dar pequenos passinhos onde tudo continua funcionando e só, aos pouquinhos, você vai substituindo. Observe que eu já posso aqui, nesse ponto. Eu já consigo vir aqui na minha classe Movie, já, já colocar aqui para retornar o NewRelease, não é? Então, eh, eh. Se o priceCode for igual a NewRelease, ele já vai retornar aqui new NewRelease com o title ali, igual ao de cima ali. Então, nos casos do NewRelease, ele já está utilizando a subclasse e se eu rodar os testes eles vão estar funcionando. Porquê? Porque ele está passando esse NEW_RELEASE e ele está delegando para a classe Movie, ele está chamando da classe Movie o getAmount e o getFrequentRenterPoints que consideram aqui o NEW_RELEASE. Então, eu vou vir aqui, eu vou copiar aqui, fica até mais fácil do que usar ali o do Eclipse. Está? Então, no meu método getAmount eu vou copiar aqui o que tem aqui no Movie, que é simplesmente a quantidade de dias vezes 3, nesse caso aqui é uma implementação até bem simples, está? E aqui, na minha classe Movie, eu posso colocar esse if aqui com a diferença de que aqui eu vou tirar essa verificação se ele é NEW_RELEASE, porque eu sei que ele é NEW_RELEASE. Então, se for maior do que 1 retorna 2 se não retorna 1, então ficando ali bastante simples, está? Então vou rodar aqui agora. Funcionou e aí então eu posso já remover aqui, eu posso deixar só o return 1 aqui. Aqui, o único caso que ele vai rodar vai ser no caso do CHILDRENS, então eu posso também já excluir tudo ali. Está? Deixando inclusive aqui o igual a 1.5 e posso rodar aqui de novo e vamos ver como é que vai ficar isso daqui. [SEM ÁUDIO] Funcionou, está? A gente pode observar aqui que o return 1, essa implementação ela está igualzinha à do Regular, eu posso deixar esse return 1 como implementação Default, ou seja, nem preciso colocar aqui, só vou sobrescrever isso ali no meu NEW_RELEASE, onde eu tenho comportamento diferente, o teste continua funcionando. Olha que, é muito bom deletar código, é muito bom você sai excluindo tudo e tudo continua funcionando a mesma coisa! É muito bom, muito bom, adoro, adoro deletar código! Bom, está faltando só agora aqui a nossa classe, Childrens. Então, vamos vir aqui, criar a nossa classe Childrens, onde eu vou também colocar como Superclasse aqui a classe Movie. E agora ficou bem fácil. Então vou passar aqui esse, como priceCode aqui o CHILDRENS, e eu posso excluir aqui do meu construtor. Aqui o meu, na minha classe Movie, eu posso simplesmente copiar esse getAmount aqui [SEM ÁUDIO] porque ele já é a implementação do CHILDRENS. Vou salvar aqui. E esse getAmount aqui ele sei lá, não tem mais nada, a partir do momento que vir aqui e colocar aqui, if priceCode igual a CHILDRENS e retornar children aqui, new, new Childrens, com title, eu não preciso mais desse aqui baixo, não é? Eu posso até jogar uma exceção aqui, dar throws new Runtime Exception e falar aqui, não existe esse tipo de filme. Não existe, opa, não existe esse tipo de filme, que é o priceCode que ele está passando ali, não é? Eh, throw. Então, com isso eu posso por exemplo, vir aqui e dizer que a classe Movie é uma classe abstrata agora, porque ninguém vai instanciar o Movie, vai instanciar sempre uma das suas subclasses, não é? Então vou colocar aqui, abstract class Movie e aí eu posso declarar por exemplo, esse método getAmount também como método abstrato, não é? Ou seja, cada filme precisa ter o seu Aquele, aquele seu, o cálculo da quantidade, do seu preço, está? Então vou rodar aqui, para ver se funcionou direitinho. Opa, espera aí. Vamos rodar aqui o teste. Isso, muito bem. E com isso eu percebo que a minha variável priceCode ela não é mais necessária, porque eu não uso, se eu olhar aqui eu não uso ela mais para nada, ela é uma coisa que ficou obsoleta. Então, olha só, agora vai ser a festa de deletar coisas. Eu posso deletar isso daqui, está, eu posso deletar isso daqui, posso deletar esses 2 métodos aqui, não são mais necessários, vou salvar aqui. E aí o que eu vou precisar é simplesmente de eliminar esse parâmetro aqui do construtor da superclasse, que todo o regular é regular, todo o NEW_RELEASE é NEW_RELEASE, então eu não preciso mais de passar isso para a superclasse porque ela não utiliza mais isso para nada, está? Salvo tudo e você pode ver que com essa quantidade de código que eu excluí o teste continua passando com sucesso, está? Então, fizemos aqui não é, uma, claro, fala assim: mas você continua com o if aqui para criar o tipo do filme. Sim, dependemos da forma, eu preciso me ater a isso daqui, porque o resto do meu sistema, no caso, o que o resto do meu sistema aqui? É o teste, ele utiliza aqui esse esse código não é, como base para criar os filmes. Se depois eu refatorar os meus, a minha aplicação como todo, para que ele crie regular, que ao invés de criar filme, não é, eu posso de repente eliminar essa necessidade de eu ter esse esse método de criação aqui, está? Mas a gente vê que ele é bem mais organizado do aquele código que eu tinha antes, não é? Se a gente quer saber como é que funciona determinado tipo de filme, é só eu vir aqui e as regras cada deles são muito claras, não é mais aquela bagunça toda misturada que a gente tinha antes, está? E outra coisa que a gente percebe essa melhoria é que se a gente quiser acrescentar novo tipo de filme, sei lá, filme promocional ou super lançamento como tem algumas locadoras por aí, a gente também é só criar uma nova subclasse e no caso aqui está incluindo ela nesse, nesse método aqui de criação, está certo? Então, essa aula foi isso, sei que foi uma refatoração complicada, o Eclipse não faz ela automática para a gente, mas dá para ver como é que a gente através da refatoração a gente consegue mudar bastante a cara de código. Mas não acabou não, tem mais pedacinho e eu espero você no próximo vídeo para a gente terminar essa refatoração. [MÚSICA]