Primeiras aulas do curso C# Refatoração Parte 2: Refatorações baseadas em Orientação a Objetos.

C# Refatoração Parte 2: Refatorações baseadas em Orientação a Objetos.

Encapsulamento e Orientação a Objetos - Introdução

Tudo bem com vocês? Eu sou Marcelo Oliveira, bem-vindos ao nosso novo curso C#: Refatorando Parte 2, nesta segunda parte do nosso curso nós vamos ver 22 novas técnicas de refatoração, divididos em duas categorias que são, a de organização de dados e a de simplificar condições. Nós vamos começar vendo a técnica para substituir o número mágico ou string mágica, em seguida nós vamos ver como substituir um Array que tem tipos diferentes, por uma classe, por um objeto.

Nós vamos ver também como substituir dados que estão soltos no código por uma classe, por um objeto. Nós vamos ver também como proteger um campo público encapsulando esse campo e vamos ver como encapsular uma coleção protegendo-a contra o acesso indevido, o acesso externo.

Nós vamos ver também como mudar um objeto de valor para referência para podermos utilizar somente uma única instância ao longo de toda a aplicação e também como fazer o inverso, mudar de referência para valor.

Nós vamos ver também como mudar uma associação que está unidirecional para bidirecional, para podermos navegar de um objeto para o outro e navegar de volta para o objeto Inicial e também para fazer a técnica inversa, que é quando temos uma associação dos dois lados e só precisamos de um lado, fazemos a associação ficar unidirecional.

Também vamos ver como duplicar dados observados, que é quando temos por exemplo um formulário em uma aplicação e colocamos toda o código que deveria ser de uma classe, de um modelo, de uma classe do domínio, são informações e são regras de negócio que deveriam estar fora da interface do usuário.

Vamos ver em seguida como substituir código de tipo por classe, criando uma classe nova que vai conter os tipos possíveis do nosso programa, em seguida como substituir um código de tipo por subclasses, onde temos uma hierarquia, subclasses que vão representar, cada subclasse representa um tipo possível desse código.

Nós vamos ver também como substituir um código de tipo por um padrão de projeto, que no caso são State ou Strategy, vamos ver também como substituir uma subclasse por um campo, quando abusamos da orientação a objetos fazemos o contrário, vamos transformar o nosso código numa estrutura muito mais simples, substituindo por campos, vamos ver também como decidir qual técnica utilizar dessas substituições de código utilizando uma tabela de decisões.

Vamos ver também a categoria de simplificação de condições, vamos ver a primeira delas que é a condição complexa que vamos pegar uma expressão que está complicada de ler, vamos transformar isso extraindo um método que vai ser muito mais expressivo para o nosso desenvolvedor.

Também vamos ver como consolidar uma expressão condicional, uma condição aqui que retorna, são várias condições que retornam o mesmo valor, extraímos o método que vai ser expressivo também para poder deixar o nosso código mais claro, também vamos ver como consolidar fragmentos condicionais duplicados, veremos condições que tem fragmentos que são duplicados, vamos extrair esses fragmentos para deixar para fora das nossas condições.

Em seguida vamos ver como remover uma Flag de controle. Essa Flag está sendo como um marcador de que por exemplo encontrou ou não algum valor dentro de uma lista, removemos essa Flag e utilizamos uma técnica chamada de “early return” ou retorno precoce.

Também vamos ver como substituir uma condição alinhada, o que é isso? Na verdade, é aquela escadinha “if else”, “if else”, “if else”, trocamos isso aqui por uma estrutura mais plana, mais simples também utilizando “early returns”.

Também vamos ver como substituir uma condição por polimorfismo, quando temos por exemplo um comando Switch retornando uma série de comportamentos diferentes, no lugar disso, utilizamos subclasses, cada subclasse tendo um comportamento diferente e terminando vamos ver o que?

O objeto nulo, como utilizar um objeto nulo que vai substituir todas aquelas decisões, se o objeto for nulo fazemos isso, se não for nulo fazemos outra coisa, encapsulamos o comportamento de objeto nulo, numa nova classe que vai representar esse tipo de situação.

No final vamos ver como introduzir uma asserção, quando o nosso código pressupõe que alguma coisa é verdadeira, porém ele não checa, ele não verifica se aquilo é verdadeiro ou não, criamos uma condição para poder proteger o resto do nosso código desse método.

Então é isso, esperamos vocês no curso, espero que vocês gostem bastante do curso, não deixem de participar do fórum, qualquer coisa nos falamos muito em breve, muito obrigado e até logo.

Encapsulamento e Orientação a Objetos - Substituir Número Mágico

Tudo bem com vocês? Eu sou o Marcelo Oliveira, bem-vindos ao nosso curso C#: Refatorando Código Parte 2. Na parte dois desse curso nós vamos ver outras técnicas de refatoração, vamos começar com a primeira categoria que são as técnicas para organização de dados. A primeira das técnicas vai ser a número 18, substituir o número mágico, o que significa isso, substituir o número mágico?

Vamos abrir o Visual Studio com a nossa solução, nós temos o projeto de refatoração e dentro da pasta da “Aula1” nós temos a pasta “R18”, com a primeira técnica, temos aqui dentro da pasta “depois” a classe “ICMS”, vamos ver aqui onde nós temos um programa e dentro dele temos um método para calcular o valor de um imposto.

Esse imposto é o ICMS, imposto sobre circulação de mercadorias ou serviços e esse método vai calcular o valor, vai tomar como parâmetro o valor total dos produtos, que no caso vai ser R$1000 e também o estado da Federação, o Estado, a UF, onde está sendo calculado o ICMS, no caso aqui é São Paulo.

Nós vemos aqui dentro do método “CalcularValor” que esse imposto é calculado de acordo com o estado. Se eu tenho, se o estado for São Paulo, então ele vai calcular multiplicando o valor dos produtos por 0.18, caso contrário ele vai multiplicar por 0.15.

O que nós temos no código são esses dois valores decimais, 0.18, 0.15, que eu sei o significado porque fui eu que desenvolvi esse código, então eu conheço o significado deles, mas para um envolvedor que está chegando e não está familiarizado com esse código, ele não vai entender exatamente o sentido desses números, ele pode encontrar dificuldade de entender. Chamamos esse tipo de problema de entendimento de número mágico.

Número mágico é o número que está solto no código sem nenhuma explicação. Vamos utilizar refatoração para substituir esse número mágico por uma constante, que vai dar sentido a esse código, a esse número mágico. Nós temos aqui o 0.15 que eu sei que é alíquota de ICMS, mas não é uma alíquota qualquer, ela é alíquota padrão do ICMS.

Nós vamos substituir esse número utilizando a refatoração do Visual Studio com a tecla “Ctrl + .”, onde eu tenho aqui no menu que abre do meu lado, ele vai abrir aqui algumas opções, eu quero introduzir uma constante para valor 0.15, quando eu clico aqui ele já cria para mim uma constante decimal. Eu vou chamar esse valor aqui como uma constante que é “ALIQUOTA_ICMS_PADRAO”.

Note que ele já substituiu aqui embaixo para mim o valor 0.15 por essa nova constante e eu vou ter que criar também uma constante para alíquota que é calculada para o estado de São Paulo, vamos modificar aqui, vamos selecionar esse valor 0.18 e “Ctrl + .” vamos extrair aqui uma constante, vamos introduzir uma constante para 0,18, clicando no menu introduzir constante e agora vamos batizar essa constante de “ALIQUOTA_ICMS_SP”, que é Estado de São Paulo.

Agora eu tenho resolvido esse problema do número mágico, porque eu substitui por constantes. Agora, note que aqui nessa condição, “If (uf == “SP)” ele vai executar o código aqui dentro. Esse SP é uma string, é uma string literal.

Note que eu também poderia fazer uma refatoração para extrair e introduzir uma constante no lugar do SP, porque ela é uma string literal, nesse caso também se trata de um número mágico, mas na verdade eu tenho uma string mágica, essa string mágica pode ser substituída por uma constante, vamos fazer isso agora selecionando string, clicando “Ctrl + .” extraindo aqui, introduzindo uma constante para SP e agora eu vou substituir aqui por uma constante que eu vou chamar de “UF_SP”, com isso eu também substitui uma string mágica do meu código.

Agora está quase tudo pronto, essa refatoração, porém ainda tem o número aqui que ficou solto, que é esse número “0”, “if (valorProdutos < 0)” o programa vai lançar uma exceção dizendo que o valor dos produtos não pode ser negativo, senão vai dar um erro aqui no nosso cálculo, o que eu poderia fazer?

Substituir o “0” por uma constante, mas note o seguinte, o objetivo dessa refatoração é você substituir o número ou uma string que não tem um significado tão obvio assim. Por exemplo, “SP” pode ser substituído por uma constante, uma string, as alíquotas que eram decimais também foram substituídas, porque são valores que não tem um sentido muito óbvio.

Mas nesse caso nós temos o número “0”, então fica óbvio para quem vê esse código que o número “0” é o valor 0. Eu não preciso dar um sentido, eu não preciso por exemplo extrair esse número 0 e introduzir uma constante dizendo que o 0 é igual a 0, isso aqui é um absurdo, eu não preciso explicar que o 0 é 0. Nesse caso eu vou desfazer essa refatoração “Ctrl+Z”, voltando aqui, eu mantenho o 0 porque ele é óbvio, ele já explica qual é a sua função.

Voltando na nossa apresentação, vamos ver o que foi apresentado nesse tópico, substituir o número mágico, eu tenho um problema onde eu tenho o número, uma string, ou mesmo uma data que está solta no código, resolvo isso utilizando constantes, porém nós temos que verificar, temos que ver também se o número for óbvio como o 0 ou 1, não vamos refatorar, não vamos introduzir uma constante desnecessariamente quando tivermos um número tão óbvio quantos 0 ou 1.

Encapsulamento e Orientação a Objetos - Substituir Array Por Objeto

A próxima técnica de refatoração para organização de dados se chama Substituir Array por Objeto, a técnica 19, em qual situação vamos utilizar essa técnica?

Para isso vamos abrir o Visual Studio onde eu tenho aqui na “Aula1” a pasta “R19” e dentro eu tenho a pasta “depois” com o código de um arquivo chamado “clientes.csv”, dentro desse arquivo nós temos um texto em que cada uma das linhas desse arquivo representam um cliente diferente.

Note que, para cada cliente, eu tenho as informações quebradas por vírgula, separadas e delimitadas por vírgulas, nós precisamos abrir esse arquivo e interpretar essas informações, para isso nós temos a classe “Empresa” onde eu tenho aqui, no Construtor, o código para abrir o arquivo “clientes.csv”, como podemos ver aqui, e dentro eu tenho também o código para varrer cada uma das linhas desse arquivo, interpretar as linhas e jogar suas informações num Array de Strings, que eu chamo de “cliente”.

Em seguida eu vou consumir as informações desse arquivo acessando a partir do meu Array de string chamado “cliente”, eu vou acessar os índices para poder obter as informações do cliente, mas note que a primeira informação, que é o ID, que é uma informação numérica, está sendo acessada pelo índice “0”, em seguida eu tenho acesso do índice do 1, 2 e 3 que vão armazenar respectivamente o nome, telefone e website desse cliente.

Percebam que o ID é número, é numérico e as outras informações são strings, percebam que eu tenho dados heterogêneos, dentro de um mesmo Array, nesse caso, além disso, além de serem tipos diferentes eu também tenho cada índice representando um dado diferente. Então o nome vai cair em um índice, o telefone no outro índice, o website no outro índice, isso não é bom, isso vai contra o princípio da orientação a objetos.

Nós precisamos trazer o nosso código para “oop”, vamos implementar a orientação a objeto encapsulando essas informações do cliente numa classe, vamos criar aqui no final do nosso código uma nova classe que eu vou chamar de cliente, “class”, “Tab”, “Cliente”. Criei a classe “cliente” e agora nós vamos passar a utilizar essa classe no lugar do Array.

Antes de matar esse Array “cliente” nós vamos só modificar o nome dele, vamos chamar esse Array “cliente”, vamos chamar de campos, porque eu ainda preciso desse Array para poder quebrar essa linha a partir dos limitadores de vírgula.

Agora que eu tenho aqui os campos desse cliente eu preciso introduzir cada uma das propriedades referente a cada uma das informações desse arquivo, eu preciso do quê? Do ID, nome, telefone e Website do cliente, vamos criar aqui esses campos aqui na nossa classe cliente, o ID vai ser o número, vou colocar aqui “readonly int id”, em seguida “readonly nome”, que vai ser uma String, então “string nome”, em seguida “readonly” e uma outra string chamada de “telefone”.

Em seguida “readonly string” que eu vou chamar de “website”, agora que eu tenho esses campos eu vou criar um Construtor para essa classe, eu faço isso rapidamente e facilmente selecionando as linhas desses campos e clicando com “Ctrl + .”, “Generate constructor“ e ele vai gerar para mim automaticamente o meu Construtor.

Agora eu também preciso, eu quero utilizar a propriedades para cada um desses Campos, vamos pegar aqui e selecionar novamente esses campos e com “Ctrl + .” vamos criar, encapsular esses Campos em propriedades, vamos encapsular os campos com essa opção do “Ctrl + .” do Visual Studio, capturando os campos.

Agora ele encapsulou e jogou aqui para baixo, vamos jogar lá para cima com as teclas de “Alt + Seta para Cima”, vamos colocar aqui para cima, agora tenho um campo para cada, aliás uma propriedade para cada campo, agora que eu tenho a nossa classe criada, eu vou introduzir aqui uma nova instância da nossa classe “cliente” com “Cliente”, que eu vou chamar de “cliente” essa instância, “cliente” vai ser uma nova instância de cliente e eu vou passar lá dentro o quê?

As informações que estão no nosso Array de Campos, vamos passar aqui o “campos”, índice “0” que vai ser o ID, em seguida “campos”, índice “1”, em seguida “campos”, índice “2” e depois “campos”, índice “3”, com isso temos uma nova instância do “cliente”, mas perceba que o Visual Studio está reclamando que o primeiro parâmetro, o campo “0” precisa de um inteiro, está recebendo uma string, vamos converter esse valor para o inteiro, vamos fazer um teste para “int”, também não posso fazer isso, então o que eu tenho que fazer?

Eu tenho que fazer o “int.Parse”, vamos forçar o “int.Parse”, passando o “campos” índice “0”, agora eu consigo passar como argumento do Construtor.

Agora vamos consumir esse objeto “cliente”, vamos trocar aqui o acesso a partir do Array, a partir do índice, por um acesso através da propriedade “cliente.id”, aqui embaixo “cliente.Nome”, “cliente.Telefone” e “cliente.Website”. Vamos compilar para ver se está tudo certo, compilando, compilou sem problemas, com isso aplicamos a refatoração Substituir Array por Objeto.

Voltando na nossa apresentação, nós temos aqui a motivação, que são tipos diferentes que são armazenados no mesmo Array, isso é resolvido com a criação de uma classe para substituir esse Array, temos refatorações similares, como é o caso do Substituir o Valor por Objeto, que vamos ver mais para frente.

Agora, só para mostrar para vocês, esse tipo de classe, esse tipo de técnica vai eliminar um odor, vai eliminar um “code smell” chamado de Obsessão por Tipos Primitivos, o Array é o tipo primitivo, vamos eliminar essa obsessão por primitivos, que no caso é o Array, utilizando uma classe e trazendo o nosso código para orientação a objetos.

Sobre o curso C# Refatoração Parte 2: Refatorações baseadas em Orientação a Objetos.

O curso C# Refatoração Parte 2: Refatorações baseadas em Orientação a Objetos. possui 170 minutos de vídeos, em um total de 56 atividades. Gostou? Conheça nossos outros cursos de .NET 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 .NET acessando integralmente esse e outros cursos, comece hoje!

Plus

  • Acesso a TODOS os cursos da plataforma

    Mais de 1200 cursos completamente atualizados, com novos lançamentos todas as semanas, em Programação, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.

  • Alura Challenges

    Desafios temáticos para você turbinar seu portfólio. Você aprende na prática, com exercícios e projetos que simulam o dia a dia profissional.

  • Alura Cases

    Webséries exclusivas com discussões avançadas sobre arquitetura de sistemas com profissionais de grandes corporações e startups.

  • Certificado

    Emitimos certificados para atestar que você finalizou nossos cursos e formações.

  • Alura Língua (incluindo curso Inglês para Devs)

    Estude a língua inglesa com um curso 100% focado em tecnologia e expanda seus horizontes profissionais.

12X
R$85
à vista R$1.020
Matricule-se

Pro

  • Acesso a TODOS os cursos da plataforma

    Mais de 1200 cursos completamente atualizados, com novos lançamentos todas as semanas, em Programação, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.

  • Alura Challenges

    Desafios temáticos para você turbinar seu portfólio. Você aprende na prática, com exercícios e projetos que simulam o dia a dia profissional.

  • Alura Cases

    Webséries exclusivas com discussões avançadas sobre arquitetura de sistemas com profissionais de grandes corporações e startups.

  • Certificado

    Emitimos certificados para atestar que você finalizou nossos cursos e formações.

  • Alura Língua (incluindo curso Inglês para Devs)

    Estude a língua inglesa com um curso 100% focado em tecnologia e expanda seus horizontes profissionais.

12X
R$120
à vista R$1.440
Matricule-se
Conheça os Planos para Empresas

Acesso completo
durante 1 ano

Estude 24h/dia
onde e quando quiser

Novos cursos
todas as semanas