Alura > Cursos de Programação > Cursos de PHP > Conteúdos de PHP > Primeiras aulas do curso Object Calisthenics: exercitando a Orientação a Objetos

Object Calisthenics: exercitando a Orientação a Objetos

Orientação a Objetos - Apresentação

Sejam muito bem-vindos à Alura, meu nome é Vinicius Dias, eu vou guiar vocês nesse treinamento de object calisthenics, que é um nome difícil de falar, mas vamos entender que na prática as regras e os exercícios não são tão difíceis assim.

Então, neste treinamento vamos aprender bastante coisa legal, vamos utilizar muito da orientação a objetos. Então antes de continuar neste treinamento eu preciso que você domine bastante a orientação a objetos, preciso que você pelo menos conheça os princípios SOLID, porque quando vamos implementando, exercitando algumas dessas regras aqui acabamos precisando desse conceito um pouco mais enraizado da programação orientada a objetos.

E também é interessante que você conheça, que você entenda o que são testes automatizados e testes de unidade, porque nesse treinamento vamos dar uma olhada em alguns testes passando, testes falhando. Só para conseguirmos executar algum código.

O projeto deste treinamento vou te apresentar no próximo vídeo, mas preciso desses pré-requisitos de você. E acho válido citar que todas as regras ensinadas aqui são agnósticas de linguagem. O que vamos aprender serve para php, Java, Csharp, Ruby, Python e qualquer outra linguagem que suporte o paradigma orientado a objetos.

Tudo que você aprender aqui é aplicável muito provavelmente na sua linguagem favorita, a menos que ela não suporte orientação a objetos. Então, se durante este treinamento você ficar com alguma dúvida, não hesite, você pode recorrer ao fórum, abrir uma dúvida lá, e eu tento responder pessoalmente sempre que possível. Mas quando não consigo, nossa comunidade de alunos, moderadores e instrutores é muito solícita e alguém com certeza vai te ajudar.

Este treinamento é de um conteúdo bem rápido, bem curto, mas que mudou minha vida como programador, eu mudei minha forma de codificar depois que conheci esses conceitos, então espero que você goste bastante também e que tire bastante proveito.

Mais uma vez, sejam muito bem-vindos, e chega de falação, te espero no próximo vídeo para você conhecer o projeto que vamos utilizar.

Orientação a Objetos - Apresentando o projeto

Bem-vindos de volta, e agora que já entendemos o que precisamos saber para continuar com esse treinamento, vamos dar uma olhada no projeto. Então, só para que você entenda o que esse projeto faz e caso você queira traduzir para uma outra linguagem, fazer em uma linguagem diferente esse treinamento, você já vai entender tudo que tem aqui.

Vamos lá. Vamos trabalhar em um projeto numa espécie de escola online, então temos alunos. De forma bastante semelhante da Alura, só que com algumas particularidades aqui. Vamos ter um aluno, nesse aluno já começamos a ter alguns problemas de cara, mas vamos lá. Temos um e-mail desse aluno que está aqui como string, uma data de nascimento, esse bd é de birthdate.

Os vídeos que esse aluno já assistiu. E temos o primeiro nome, o último nome, rua, número, bairro, cidade, Estado e país. Ou seja, os dados do endereço. E isso tudo estamos recebendo e inicializando no construtor, sendo que o e-mail tem uma regra relacionada, validamos se esse e-mail está correto. Só verificamos se está no formato válido de e-mail.

Temos um método para recuperar o nome completo. Tem o primeiro nome, espaço, segundo nome. Temos aqui vários getters. Temos a possibilidade de assistir um vídeo, então assistimos um vídeo em determinada data. Adicionamos isso em um mapa. E nesse ponto, caso você traduza para alguma linguagem diferente, cada linguagem vai implementar um mapa de uma forma. Então talvez isso mude de uma linguagem para outra.

E nós temos um método que verifica se um aluno tem ou não acesso à plataforma em si. Para o aluno ter acesso à plataforma, o primeiro vídeo que ele assistiu não pode ter mais do que 90 dias. Ou seja, se eu assistir um vídeo hoje, daqui 90 dias perco acesso à plataforma. Então preciso assistir todos os cursos, todos os vídeos necessários dessa plataforma dentro de 90 dias.

Essa é nossa regra de negócios do aluno aqui. De novo, você pode traduzir isso para alguma outra linguagem caso você queira, e vamos dar uma olhada no que temos sobre os vídeos. O vídeo em si tem uma visibilidade, que pode ser ou público ou privado, e para manter essa consistência temos um método checkIfVisibilityIsValidAndUpdateIt.

Ou seja, verifique se a visibilidade é válida e atualize. Então, na hora de atualizar a visibilidade, ou seja, isso é um método setter, eu poderia chamar de set visibility, mas nesse método setter eu simplesmente verifico se o que estou recebendo é público ou é privado e defino a visibilidade. Caso contrário estou lançando uma exceção aqui. Sem segredo nenhum.

E estou pegando, um vídeo tem um limite de idade. Ou seja, esse vídeo só pode ser assistido por pessoas de 16 anos ou mais, de 14 anos ou mais. Então consigo definir um limite de idade aqui sendo um inteiro. Mas beleza, vou ter um repositório de vídeos, onde posso adicionar vídeos e buscar os vídeos para determinado aluno.

Com isso tenho uma representação em me para não ter que acessar bancos de dados, etc. E só tenho um array, um vetor de vídeos, e nesse vetor de vídeos eu adiciono, ou seja, posso ter vários vídeos adicionados, e na hora de buscar os vídeos para um aluno tudo que faço é pego a data de hoje, verifico se a data de limite desse vídeo é menor do que a idade do aluno.

Então calculo a idade do aluno baseado na data de nascimento, fazendo a diferença com a data de hoje, e aí calculo o número de anos. Já conseguimos ver nesse projeto pequeno alguns problemas que temos, certo? Imagino que você consiga ver isso.

Vamos atacar esses problemas durante o treinamento, mas para executarmos algum código, tenho aqui alguns testes de unidade. São poucos testes, talvez incrementemos, talvez não. Mas temos um teste de aluno, que verifica todas as regras, e para isso repare que precisei de um método setup aqui.

Verifico todas as regras. Um aluno sem nenhum vídeo assistido pode acessar a plataforma, um aluno que assistiu seu primeiro vídeo antes de 90 dias, ou seja, no meu caso há 89 dias ele assistiu o primeiro vídeo, então ele ainda tem acesso. Um aluno com vários vídeos tem acesso. Agora, um aluno que assistiu o primeiro vídeo há 90 dias ou mais não vai ter acesso, estou verificando aqui que ele não vai poder ter acesso e caso ele tenha outros vídeos assistidos continuo garantindo que ele não tenha acesso desde que o primeiro seja há 90 dias ou mais.

Então tenho aqui alguns testes para garantir isso, tenho meus testes do repositório, aquele repositório em memória verificando que realmente estou buscando apenas os vídeos dentro da faixa etária daquele aluno. Por exemplo, um aluno que tem 19 anos, criei um aluno com 19 anos, ele só vai poder acessar os vídeos que tenham o limite de idade, não pode ser de 21 nem de 20, então só de 19, 18 e 17, porque para esses vídeos ele tem acesso, com isso tenho três vídeos sendo exibidos.

Passei rápido. Tem o teste do vídeo em si, onde simplesmente altero visibilidade e garanto que tudo está funcionando. Passei rápido no projeto porque espero que você já entenda todo esse código, espero que você já tenha aqueles conhecimentos que eu comentei. Só que quero passar, quis passar no projeto para você entender tudo antes de modificar, para você ter uma visão do todo antes de sair modificando.

E a primeira coisa que vamos modificar é justamente esse método. Primeiro já vemos de cara que tem alguma coisa errada com ele, talvez não saibamos o que. Aqui dentro vamos falar sobre os problemas desse método, o que ele traz de problema e o que podemos resolver. Algumas formas são possíveis e vamos ver algumas delas. No próximo vídeo começamos finalmente colocando a mão na massa.

Orientação a Objetos - Publicando um vídeo

Bem-vindos de volta. Vamos dar uma olhada no que precisamos fazer para publicar um vídeo. Um vídeo pode ser, como comentei, público ou privado, e estou representando isso internamente como inteiro. Eu poderia representar de alguma forma, como por exemplo verdadeiro se é público, mas aí talvez eu possa ter outras visibilidades no futuro.

Enfim, isso não importa, o que importa é que estou representando a estrutura de vídeos como público e privado, com inteiro, e para alterar a visibilidade preciso passar um inteiro por parâmetro para esse método, como se fosse um método setter. Então vamos falar dos problemas dessa abordagem.

Primeiro, para eu vir no meu teste de vídeo, por exemplo, e alterar a visibilidade, tornar esse vídeo público, inclusive vou até renomear esse método para MakingAVideoPublicMustWork, ou seja, tornar um vídeo público deve funcionar. Estou tornando um vídeo público, tenho um vídeo, quero publicá-lo.

E o que acontece? Repare como estou falando. Quero publicar um vídeo. Isso não está bem expressado no meu código, não estou expressando, não estou falando tornar um vídeo público, publicar um vídeo, não estou falando nada parecido com isso, então isso já é um problema, temos essa distância entre o que estou fazendo e o que estou escrevendo.

Caso você já tenha assistido o curso de ddd, por exemplo, você sabe que isso traz problemas de comunicação. Enfim, continuando. Para que eu altere, para que eu publique um vídeo, preciso ter o conhecimento da estrutura interna dessa classe. Preciso saber que existem duas constantes que fazem menção à visibilidade de um vídeo, preciso saber que isso é um inteiro para passar aqui para esse vídeo.

Para eu recuperar esse valor preciso ter acesso a esse inteiro também e saber que o número 1 significa público, que o número 2 significa privado, ou de novo acessar esse dado. Então de novo, posso acabar tendo repetição de código.

Ou seja, se eu for mudar a visibilidade somente se um vídeo for privado, por exemplo, eu precisaria vir no meu vídeo, fazer um if vídeo getVisibility, eu precisaria verificar se é vídeo privado. E aí só a partir disso eu faria a publicação.

Repare que tenho muitos problemas. Vamos corrigir vários desses problemas de uma forma só. Eu quero tornar minha API, minha interface dessa classe pública, mas natural. Então o que quero fazer com o vídeo? Quero publicar o vídeo, certo? então vou expor o método publish, que significa publicar.

Vou colocar ele como primeiro método aqui e vou criar um método publish. O que vou fazer? Como comentei, tenho essa regra, só publico o vídeo se ele for privado ainda, se ele já for público não preciso fazer nada. Então posso realizar essa verificação ou não. No meu caso nem vou fazer.

O que vou fazer aqui? Vou dizer que a visibilidade desse vídeo é public. Então, com isso tenho uma interface mais simples, estou publicando meu vídeo, sei que vou publicar, e sei aqui dentro que adicionar essa verificação private igual visibility, é inútil, eu não preciso dela. Mas por que eu sei? Porque estou dentro dessa classe, conheço a estrutura interna dela.

Então sei que essa verificação não é necessária porque sem ela mal nenhum acontece. Com isso tenho a certeza da simplicidade do meu método. Vou dizer que ele não precisa retornar nada. E como já dizia Leonardo Da Vinci, a simplicidade é o mais alto grau de complexidade, então mantenho meu método simples, só que o principal é que a minha API está muito mais clara.

Não preciso verificar se o parâmetro que está sendo enviado é correto, até porque não estou recebendo mais parâmetro nenhum, repare que isso é muito simples, e com isso elimino a necessidade desse if, o meu método fica muito mais simples. Simplesmente estou publicando.

E que outra vantagem isso traz? Não faz sentido depois que um vídeo for público torná-lo privado de novo. No nosso caso, na nossa escola online isso não pode acontecer. E se pudesse? Eu poderia ter um método, um pubf unpublish, ou seja, despublicar, ou então makeItPrivate, eu poderia ter algo assim que mudaria a visibilidade para private. Sem problema nenhum.

Só que a minha regra de negócios na minha empresa não permite isso. Então não preciso desse método. Obviamente eu deveria remover esse método, exclui-lo, só que não vou fazer, vou deixar ele aqui por motivos de histórico, mas você pode ir de cara e excluir esse método. Vou deixar ele aqui por motivos de histórico para compararmos isso com isso, que é bem mais simples.

Vamos lá, o que vou fazer agora? Vou mudar, ao invés de chamar esse método todo aqui, vou publicar meu vídeo. E agora consigo garantir, continuo garantindo que meu vídeo é público. Posso rodar esse teste e garantir que tudo continua passando. Sei que não rodei antes, mas ele estava passando antes. Então agora ele continua passando. Todos os testes passaram, que no meu caso é um só.

Com isso, conseguimos fazer uma refatoração muito simples, mas que torna a API do nosso código muito mais legível. Essa simples modificação aqui faz parte de uma das regras que vamos comentar durante esse treinamento. Só que como já mostrei a mão na massa, como já fizemos a parte prática, eu volto no próximo vídeo para falar da teoria por trás disso.

Sobre o curso Object Calisthenics: exercitando a Orientação a Objetos

O curso Object Calisthenics: exercitando a Orientação a Objetos possui 84 minutos de vídeos, em um total de 51 atividades. Gostou? Conheça nossos outros cursos de PHP em Programação, ou leia nossos artigos de Programação.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda PHP acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas