Prévia do material em texto
SUMÁRIO 1 INTRODUÇÃO _______________________________________________ 9 2 PREPARAÇÃO DO AMBIENTE __________________________________ 11 2.1 SISTEMA OPERACIONAL _____________________________________ Z11 2.1.1 Sistemas operacionais Desktop ____________________________ 11 2.1.2 Sistemas Operacionais Mobile ____________________________ 12 2.2 APLICAÇÕES .NET PARA SISTEMAS OPERACIONAIS _______________ 13 2.3 IDE _______________________________________________________ 13 2.4 SERVIDOR _________________________________________________ 14 2.5 BANCO DE DADOS __________________________________________ 15 2.6 EMULADOR _______________________________________________ 16 2.7 FRAMEWORKS _____________________________________________ 17 2.7.1 Frameworks Front-End ___________________________________ 17 2.7.2 Frameworks Back-End ___________________________________ 18 3 PROGRAMAÇÃO ESTRUTURADA _______________________________ 19 3.1 ESCRITA EM TELA ___________________________________________ 20 3.2 LEITURA __________________________________________________ 20 3.3 TIPOS DE DADOS ___________________________________________ 22 3.4 DECLARAÇÃO DE VARIÁVEIS __________________________________ 24 3.5 ATRIBUIÇÃO DE VALOR ______________________________________ 25 3.6 USING ____________________________________________________ 25 3.7 CONDICIONAIS_____________________________________________ 26 3.7.1 Operadores Lógicos _____________________________________ 26 3.7.2 Operadores Aritméticos __________________________________ 27 Operador __________________________________________________ 27 Descrição __________________________________________________ 27 4 PROGRAMAÇÃO ORIENTADA A OBJETOS _______________________ 47 4.1 PILARES DA ORIENTAÇÃO A OBJETOS __________________________ 48 4.1.1 Abstração _____________________________________________ 48 4.1.2 Herança ______________________________________________ 49 4.1.3 Polimorfismo __________________________________________ 51 4.1.3.1 Sobrecarga de método __________________________________ 53 4.1.4 Encapsulamento _______________________________________ 53 4.2 MÉTODOS E RETORNOS _____________________________________ 60 4.3 ESTRUTURA DE UMA CLASSE _________________________________ 64 4.4 MODIFICADORES DE ACESSO _________________________________ 70 4.5 ESCOPO E VARIÁVEL ________________________________________ 72 4.6 TRATAMENTO DE EXCEÇÕES __________________________________ 73 4.7 ELEMENTOS ESTÁTICOS ______________________________________ 74 4.7.1 Classe estática _________________________________________ 74 3.7.3 If ____________________________________________________ 28 3.7.4 Else __________________________________________________ 28 3.7.5 Else if _________________________________________________ 30 3.7.6 Switch case ____________________________________________ 31 3.8 LAÇOS DE REPETIÇÃO _______________________________________ 32 3.8.1 For ___________________________________________________ 33 3.8.2 While _________________________________________________ 35 3.8.3 Do while ______________________________________________ 36 3.9 VETORES E MATRIZES _______________________________________ 37 3.9.1 Vetor _________________________________________________ 38 3.9.2 Matrizes ______________________________________________ 40 3.10 MÉTODOS – FUNÇÕES E PROCEDIMENTOS ____________________ 41 3.10.1 Retorno ______________________________________________ 43 3.10.2 Parâmetros ___________________________________________ 45 4.7.2 Método estático ________________________________________ 74 4.7.3 Atributo estático _______________________________________ 75 4.8 CLASSE ABSTRATA __________________________________________ 75 4.9 INTERFACE ________________________________________________ 76 4.10 CONSTRUTOR _____________________________________________ 77 5 CONEXÃO COM BANCO DE DADOS ____________________________ 79 5.1 RELACIONAIS ______________________________________________ 80 5.2 NÃO-RELACIONAIS _________________________________________ 81 6 TÉCNICAS DE PROGRAMAÇÃO ________________________________ 89 6.1 FORMATAÇÃO _____________________________________________ 89 6.2 DOCUMENTAÇÃO DE CÓDIGO ________________________________ 91 6.3 REUTILIZAÇÃO DE CÓDIGO __________________________________ 92 6.4 TÉCNICAS DE OTIMIZAÇÃO DE CÓDIGO ________________________ 94 6.5 DEPURAÇÃO _______________________________________________ 96 7 RASTREABILIDADE __________________________________________ 97 7.1 SISTEMAS DE REPOSITÓRIO DE VERSIONAMENTO ________________ 97 7.2 SOFTWARE DE VERSIONAMENTO E REPOSITÓRIOS _______________ 97 7.2.1 Utilizando o git de forma local ____________________________ 100 7.2.2 Transformação de um repositório local em remoto ____________ 103 7.2.3 Clonando um repositório do GitHub _______________________ 104 7.2.4 Considerações finais sobre o tema _________________________ 104 8 TESTE UNITÁRIO _____________________________________________ 105 REFERÊNCIAS ________________________________________________ 109 9 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 1 INTRODUÇÃO Caro (a) aluno (a), Seja bem-vindo (a) à Unidade Curricular de Programação de Aplicativos no curso Técnico de Desenvolvimento de Sistemas! O objetivo nesta etapa é o de propiciar a formação técnica e científica dos conceitos de programação, a fim de desenvolver as capacidades necessárias para a atuação profissional como técnico desenvolvedor de sistemas. Este livro está dividido em sete capítulos técnicos. O capítulo Um apresentará conceitos sobre sistemas operacionais e termos introdutórios que serão utilizados ao longo desta apostila, tais como banco de dados, emulador, IDE e servidor. O capítulo Dois definirá os conceitos de programação estruturada como variáveis, laços de repetição, condicionais e tipos de dados. No capítulo Três, você aprenderá sobre programação orientada a objetos e seus pilares. Já no Quatro, você conhecerá sobre bancos de dados, seus tipos, sua importância e sua utilização. Em seguida, o capítulo Cinco apresentará técnicas de programação como formatação, documentação de código e reutilização. No capítulo Seis, será abordada a importância da rastreabilidade e sua utilização. No último capítulo, será tratado sobre os testes unitários, importantes para garantir que os códigos funcionem da maneira correta. Espera-se que, no decorrer do estudo desses capítulos, você adquira as capacidades técnicas necessárias para atuar na área de desenvolvimento de sistemas. No entanto, para que possa ter sucesso na indústria como profissional deste segmento, é imprescindível demonstrar espírito colaborativo, apresentar atitudes éticas nas ações e relações interpessoais, utilizar equipamentos de segurança, zelar pelo uso de equipamentos e instrumentos e, além disso, saber trabalhar em equipe. Convido você agora, a iniciar seu processo de aprendizagem e aproveitar todas as informações e conhecimentos do livro. Busque o máximo de proveito ao fazer o curso. Bons estudos! 11 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 2 PREPARAÇÃO DO AMBIENTE 2.1 SISTEMA OPERACIONAL Figura 1 – Sistemas Operacionais Fonte: SHUTTERSTOCK, 2019. O sistema operacional é um conjunto de softwares que operam diversos processos, inclusive o hardware, servindo de interface entre o usuário e o dispositivo, além de prover e gerenciar operações básicas de aparelhos eletrônicos como tablets, notebooks e smartphones. Os sistemas operacionais são responsáveis pelo gerenciamento de recursos e threads, graças aos sistemas operacionais é possível hoje executar diversas tarefas ao mesmo tempo. 2.1.1 Sistemas operacionais Desktop Figura 2 – Sistemas operacionais Desktop Fonte: SHUTTERSTOCK, 2019. 12 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Dentre os sistemas operacionais existentes, três são os mais utilizados: Windows Criado pela empresa Microsoft, o Windows é o sistemaoperacional desktop mais utilizado em todo o mundo, sendo muitas cópias ilegais. É o sistema mais popular entre os três, também é o mais vulnerável a vírus. Mac OS Os sistemas operacionais da Apple são focados na simplicidade e em gráficos bem trabalhados, animações suaves e minimalistas, este sistema operacional foi feito para rodar apenas em máquinas da Apple, detentora deste Sistema Operacional. Linux São várias as distribuições que são baseadas no kernel Linux. O Ubuntu é uma das distribuições mais relevantes do mercado, este possui código aberto, uma vulnerabilidade a vírus menor que os demais sistemas operacionais aqui explicados. Além do Ubuntu, existem diversos outros sistemas operacionais baseados em Linux como o Debian, CentOS, Fedora e Arch Linux. 2.1.2 Sistemas operacionais Mobile Figura 3 – Sistemas Operacionais Mobile Fonte: SHUTTERSTOCK, 2019. Os sistemas operacionais mobile são responsáveis por operações como ligações, acesso à câmera, envio de mensagens, vibrar e exibir notificações. Os aplicativos que fazem a utilização de recursos fazem requisições ao SO. A definição final da aparência do Tux (Pinguim mascote do Linux) foi solicitada por Linus Torvalds com a frase “quero um pinguim com cara de satisfeito depois de um banquete”. CURIOSIDADE 13 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT De todos os sistemas operacionais mobile disponíveis, o Android e iOS são os dois que ocupam a parcela mais considerável de utilização. Android O Android é o Sistema Operacional mais utilizado do mundo, utilizando o kernel Linux que possui seu código aberto. iOS O iOS é o sistema operacional da Apple, um sistema operacional fechado e utilizado nos aparelhos da empresa. 2.2 APLICAÇÕES .NET PARA SISTEMAS OPERACIONAIS O .NET é uma plataforma de execução de aplicações e sistemas da Microsoft, além da segurança, o .NET também oferece segurança e independência da plataforma. Com o advento do .NET Core foram abertas possibilidades de desenvolvimento para outras plataformas além do Windows, permitindo Linux e Mac também executar aplicações escritas em .NET. Para os sistemas operacionais mobile, a criação de aplicações pode ser realizada com a utilização da plataforma Xamarin, que permite exportar apps para as plataformas Windows Phone, Android e iOS. 2.3 IDE A sigla IDE vem do inglês Integrated Development Environment, ou em tradução livre Ambiente Integrado de Desenvolvimento. Trata-se de um conjunto de ferramentas para desenvolvimento de programas que trabalham de forma integrada como debugging, editor de texto e compilador, além de outras mais específicas. Auxiliando na produtividade, IDEs possuem algumas ferramentas que colaboram bastante como, por exemplo, IDEs e editores de texto que se destacam para algumas linguagens de programação, a saber: Javascript – Sublime e Atom. PHP – PHPStorm Python – PyCharm C# - Visual Studio 14 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Java – Netbeans e Eclipse Swift – Xcode Ruby – RubyMine Destaque de comandos As IDEs geralmente destacam-se por cores diferentes, comandos, variáveis, classes, etc. Isso facilita a visualização rápida quando se procura algo específico, além de mostrar muitas vezes se os comandos digitados estão corretos. Autocomplete O autocompletar é algo bem útil no desenvolvimento de softwares, eles incrementam a produtividade ao mostrar e completar comandos e variáveis ao começar a serem escritas. Geração de executáveis IDEs geralmente possuem um compilador para linguagens que necessitam, compiladores transformam o código de alto nível (simples de ser entendido) para executáveis em baixo nível. 2.4 SERVIDOR Figura 4 – Servidores Fonte: ADAPTADO DE SHUTTERSTOCK, 2019. Geralmente servidores são máquinas com grande poder de processamento e memória, capazes de realizar diversas tarefas e requisições em diversos protocolos. Operam desta forma por ter instalados softwares para esta finalidade, sendo que o tamanho e poder de processamento difere dependendo da necessidade do cliente. 15 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Os data centers costumam ficar localizados em lugares climatizados com uma boa segurança, pois costumam guardar dados importantes, estes servidores normalmente possuem cópias em diferentes lugares do mundo para caso de necessidade, como redundância e backup. A Microsoft possui data center embaixo da água, aproveitando a temperatura baixa que mantém o resfriamento. Já os recursos de energia são 100% renováveis, aproveitando a força da maré e a energia gerada pelo vento que ficam próximos ao local. CURIOSIDADE Os serviços de aplicações podem rodar em uma máquina local para testes no período de desenvolvimento, estes serviços são instalados e executados em máquinas de pequeno porte, não suportando vários acessos. O software do servidor depende da necessidade, ou seja, para rodar um site em PHP será necessária a instalação de um servidor apache; por outro lado, para executar uma página JSP será essencial um servidor Apache Tomcat e, para servidores ASPX, temos o IIS (internet Information Services). 2.5 BANCO DE DADOS Para persistir informações é utilizado serviços de bancos de dados, estes permitem que dentre várias funcionalidades se insira, altere, atualize e delete informações. Para realizar de forma mais simples o gerenciamento do banco de dados, existe uma ferramenta SGBD, sigla para Sistema de Gerenciamento de Banco de Dados, esta ferramenta permite que se utilize os serviços de armazenamento e gerenciamento dos dados. Existem diversos bancos de dados para utilização, sendo relacionais ou não relacionais. A escolha do melhor depende de estudos sobre a necessidade do projeto, podendo influenciar velocidade, desempenho e economia de recursos de memória. Atualmente, diversos softwares utilizam os bancos de dados para que se possam acessá-las em qualquer lugar e tempo, além das informações guardadas poderem ser utilizadas para análise de dados. 16 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 2.6 EMULADOR Emuladores são utilizados para a reproduzir funções em determinado ambiente e, no caso dos dispositivos móveis, os emuladores permitem que seja reproduzido diferentes aparelhos para testes, com diferentes hardwares e versões de sistemas operacionais. Quando se está desenvolvendo aplicativos móveis é importante testar em vários dispositivos e com diferentes versões do sistema operacional, tamanhos de telas e hardware. Para que não seja necessário o desenvolvedor possuir toda esta quantidade de dispositivos, pode-se utilizar os emuladores que são softwares que emulam diferentes dispositivos em um outro dispositivo, por exemplo, utilizando um notebook pode-se emular dispositivos móveis com menor poder de processamento. Figura 5 – Emulador Fonte: SENAI DR PR, 2019. 17 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 2.7 FRAMEWORKS Geralmente algumas funcionalidades são comuns entre vários sistemas como a persistência de dados, responsividade e login. A escrita destes códigos são facilitadas com o uso de frameworks. Os frameworks são conjuntos de códigos, funcionalidades e padrões que costumam se repetir em vários sistemas, estes conjuntos podem ser para back-end ou front-end, sua utilização evita com que seja escrita a mesma funcionalidade em sistemas diferentes, facilitando o desenvolvimento e incrementando velocidade e praticidade. A base do Framework é a reusabilidade, sendo o principal objetivo entregar funcionalidades genéricas e são separados em frameworks front-end e frameworks back-end. 2.7.1 Frameworks Front-End Esta categoria proporciona uma série de ferramentas para facilitar o desenvolvimento relacionado principalmente ao visual e navegação. Costuma entregarfuncionalidades como gerenciamento de rotas e criação de componentes, como também, uma estrutura para responsividade, botões e campos já estilizados. São exemplos de frameworks front-end: Angular, SASS e Bootstrap. Figura 6 – Frameworks front-end Fonte: ADAPTADO DE AALPHA, 2019. 18 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 2.7.2 Frameworks Back-End Os frameworks back-end entregam funcionalidades e padrões relacionados a regras de negócio como gerenciamento de sessão, autenticação e comunicação com a base de dados. Em geral, possuem códigos já testados para questões como segurança, tornando-se uma opção viável nestes quesitos. São exemplos de frameworks back-end: Laravel, Hibernate e Zend. Figura 7 – Frameworks back-end Fonte: ADAPTADO DE STACKOFTUTS, 2019 19 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 3 PROGRAMAÇÃO ESTRUTURADA O conceito do paradigma estrutural surgiu no fim da década de 50 juntamente com as linguagens ALGOL 58 e FORTRAN. Talvez a mais conhecida das linguagens estruturadas seja a linguagem C, criada em 1972, esta foi a escolha de Linus Torvalds ao criar o sistema operacional Linux e é famosa por sua vasta gama de aplicações, por sua portabilidade e simplicidade, além de ter influenciado várias outras linguagens de programação como JavaScript, Java, PHP, C#, Objective-C entre outras. A linguagem estruturada para iniciar o aprendizado é a escolha ideal, pois nessa etapa você precisa organizar o seu pensamento e os blocos de códigos para que funcionem da maneira desejada. Esta organização dos blocos sequenciais, condicionais e de repetição ajudam no aprendizado. Quando trabalhamos numa linha sequencial como o fluxograma ou em uma linguagem estruturada, estamos trabalhando numa forma de organizar todo conteúdo, possuindo um início, um meio e um fim. Uma das características mais significantes deste paradigma é a capacidade que a linguagem oferece de se trabalhar com subprogramação ou mais conhecida como modularização. Trata- se de uma forma de dividir blocos de códigos em subprogramas com funções mais especificas, pois blocos menores facilitam a identificação de responsabilidades, além da leitura e manutenibilidade do software. Os exemplos deste capítulo serão realizados utilizando a linguagem C# com Console Application (.NET Framework), para contextualização dos tópicos. 20 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Cada linguagem de programação possui diferentes características e particularidades, porém os conceitos aplicados neste material podem ser aplicados também a outras linguagens, com alguns ajustes de sintaxe, mas na essência os conceitos são os mesmos. 3.1 Escrita em tela Figura 8 – Console Fonte: SENAI DR PR, 2019. A prática de escrever em tela é fundamental na programação, quando se é necessário mostrar resultados, instruções, textos ou palavras. Quando estamos programando em aplicativos de console C#, temos dois comandos para isso: Console.Write e Console.WriteLine. Console.WriteLine( );”Hello World” Autoria Própria O Console.Write irá escrever no console um texto, também podendo passar variáveis. Console.Write( [Texto] ); O Console.WriteLine possui a mesma função com a diferença que irá quebrar a linha no fim da escrita. Console.WriteLine( [Texto] ); 3.2 Leitura Para realizar a leitura do teclado podemos utilizar o Console. ReadLine(), este método irá ler o que foi digitado. [VARIÁVEL] = Console.ReadLine(); 21 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT int idade; Console.WriteLine( );”Qual sua idade?” Console.Write( );”Resposta: “ idade = Parse( .ReadLine( ));int. Console Console.WriteLine( + idade);”Sua idade é “ Console.Read( ); 1 2 4 5 6 3 1. Declaração da variável idade. 2. Comando para escrever em tela a frase “Qual sua idade?” 3. Comando para escrever em tela a frase “Resposta: ” 4. O comando Int.Parse( ) é utilizado para realizar a conversão para inteiro Resultado caso o usuário digite o número 30: _ xPrompt de Comandoc:\. Qual sua idade? Resposta: 30 Sua idade é 30 Neste exemplo, o software lê o que foi digitado convertendo para um inteiro e guardando o valor na variável idade. Após guardar o valor, está exibindo em tela a mensagem “Sua idade é (valor digitado)”, o símbolo de + após as aspas indica uma concatenação. A linha Console.Read(); está sendo utilizada para aguardar uma tecla do usuário antes de finalizar o programa. string nome; Console.WriteLine( );”Qual seu nome?” Console. Write( );”Resposta: “ nome = ReadLine( );Console. Console.WriteLine( + nome);”Seu nome é “ Console.Read( ); 1 2 4 5 6 3 1. Declaração da variável nome, do tipo string. 2. Exibição da pergunta “Qual seu nome?”, em tela. 3. Exibição da palavra “Resposta” em tela, sem quebra de linha. 4. Atribuição do valor digitado pelo usuário à variável nome. 5. Exibição da frase “Seu nome é” seguida pelo valor da variável nome. 6. O comando Console.Read(), esperando uma tecla do usuário para finalizar o programa. 22 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Resultado caso o usuário digite Robson: _ xPrompt de Comandoc:\. Qual seu nome? Resposta: Robson Seu nome é Robson O exemplo acima também realiza a leitura do que foi escrito, porém, desta vez é utilizada uma variável chamada nome do tipo string. Esse tipo de dado não precisa ser convertido ao utilizar o ReadLine(). 3.3 Tipos de dados Existem diversos tipos de informações que precisamos armazenar em nossos programas como frases, textos, palavras, números inteiros, números reais e até mesmo bytes ou alguma informação booleana. Cada tipo de informação possui uma melhor forma para ser armazenada, portanto, se queremos armazenar uma palavra, não conseguimos guardar em um tipo de dado int, pois este serve para armazenar números inteiros. Por outro lado, temos o tipo de dado string, que já serve para esse caso. Se queremos armazenar um valor booleano, um ou zero, não precisamos guardá-lo em um inteiro, pois podemos guardar em um tipo bool (o tipo de dado booleano possui apenas dois valores possíveis, sendo verdadeiro ou falso, podendo ser representado por 1 ou 0). Para escolher o melhor tipo de dado ao criar uma variável, é importante conhecer os tipos possíveis e entender qual se adequa melhor à necessidade. Existem diversos tipos de tipos de dados e, para ajudá-lo, a seguir serão apresentados os principais com uma breve explicação. Vale ressaltar que cada um ocupa uma quantidade diferente de memória e permite diferentes tipos de armazenamento e, para otimizar o software, é importante conhecer os limites e o uso da memória para cada. 23 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Char Char é utilizado para representar um caractere Unicode. Ex: “a”, “b”, “c”, “1”, “@”, “#”. String A String é utilizada para armazenar um conjunto de caracteres, é o tipo de dado que se utiliza para armazenar textos, palavras e frases. Ex: “Curitiba”, “Brasil”, “Machado de Assis”, “Continue estudando diariamente para ter bons resultados”. Int O tipo de dado int é utilizado para armazenar números inteiros, não é possível guardar números reais com decimais. Ex: 1, 2, 3, 4, 100, 404, 1000, 10000, 10256. Float e Double São tipos de dados utilizados para armazenamento de valores reais, podendo conter casas decimais. O tipo double possui o dobro de precisão em relação ao float e costuma ser a escolha para quando existe uma necessidade maior de precisão. Ex: 3.14, 97.9, 212.155, 600.789. Bool O tipo de dado booleano possui dois possíveis valores, true e false. Entender esse tipo de dado é essencial para utilização de estruturas condicionais de IF e ELSE. Ex: true, false. Figura 9 – Tipos de dados Fonte: ADAPTADO DE SHUTTERSTOCK, 2019. 24 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECHIT Existem outros tipos de dados como o bigint, byte e short, cada tipo de variável pode ligar melhor com uma situação específica como um número gigante que o int não suporte. 3.4 Declaração de variáveis Para criar variáveis em C#, é necessário apenas declarar qual o tipo de dado que irá utilizar, seguido do nome que deseja. [Tipo] [NomeVariável]; Ex: int idade; string nome; float saldo; Porém, para declarar variáveis, é importante seguir algumas regras: • Não é permitido utilizar palavras reservadas. (static, void, public, private, namespace, using, new, ...); • As variáveis não podem conter espaço (nome A, valor Porcentagem, ...); • Não é permitido símbolos (Com exceção do sobrescrito (underline)). Exemplos não permitidos: nome+A, valor%imposto); • É necessário o início do nome da variável começar por uma letra ou _ (underline), números podem ser utilizados no meio e/ou fim; • As variáveis devem ser iniciadas com letras minúsculas. Neste exemplo abaixo, é demonstrada a declaração de variáveis de tipos diferentes, sua inicialização com alguns valores e, finalmente, a escrita em tela de cada um dos valores. int numeroInteiro; double casasDecimais; string frase; bool boleano; char caracter; numeroInteiro = ;2 casasDecimais = ;2.32 frase = ;”Hello World” boleano = ;true caracter = ;‘R’ Console.WriteLine(numeroInteiro); Console.WriteLine(casasDecimais); Console.WriteLine(frase); Console.WriteLine(boleano); Console.WriteLine(caracter); 1 2 3 25 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 3.5 Atribuição de valor A atribuição de valor em C# é realizada utilizando o operador = (igual), sendo relevante ressaltar que a atribuição dos valores é dada por apenas um sinal de igual, pois dois símbolos destes são utilizados quando é necessário realizar comparação de igualdade [NomeVariável] = [Valor]; Ex: idade = 30; saldo = 5000; nome = Bruna; 3.6 Using O using é utilizado para realizar a importação de uma biblioteca, essa ação agiliza e otimiza o desenvolvimento do software, pois permite a utilização de algumas funcionalidades, como as do windows. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; Utilizando a palavra reservada using importa recursos que o namespace proporciona, estes recursos variam de biblioteca para biblioteca, como por exemplo, conexão ao banco de dados, operações matemáticas complexas, como também a utilização de recursos de segurança. Algumas funções e métodos são dependentes de bibliotecas, sem a importação destas os métodos não irão funcionar. Funcionalidades como potenciação (pow) e raiz quadrada (sqrt) são funções que estão dentro do namespace System, da classe Math. Abertura e gerenciamento de arquivos ficam no namespace System. IO, este conjunto de funcionalidades também constitui algumas funções como criação, leitura, escrita e deslocamento de arquivos. 26 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 3.7 Condicionais É bem comum no desenvolvimento de software, a necessidade de executar diferentes funcionalidades dependendo do valor de variáveis. Vamos imaginar que um usuário tente realizar o login, porém errou a senha. O caminho que o software irá executar não é o mesmo se digitar corretamente suas credenciais. Vamos imaginar que está sendo desenvolvido um site para exibição de notas dos alunos do ensino primário. Um dos requisitos é a exibição de uma estrela sempre que o aluno atinge a nota máxima. Atingir a nota máxima neste cenário é a condição para exibição de uma estrela, para isso utilizamos condicionais! Figura 10 – Caminhos condicionais Fonte: ADAPTADO DE SHUTTERSTOCK, 2019. Estruturas condicionais são extremamente importantes para qualquer software, elas servem para realizar determinadas ações quando as condições forem satisfeitas. Somado a isso, permitem funcionalidades extremamente cruciais no desenvolvimento de softwares, pois são muito empregadas porque deixam sistemas mais dinâmicos, permitindo ações como redirecionamento de funcionalidades a partir de perfis. As estruturas condicionais também podem ser utilizadas para gerenciar permissões 3.7.1 OPERADORES LÓGICOS && E | | OU == IGUAL A != DIFERENTE DE ! NÃO < MENOR QUE <= MENOR OU IGUAL A > MAIOR QUE >= MAIOR OU IGUAL A 27 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 1º VALOR OPERADOR 2º VALOR RESULTADO True && (E) True True True && (E) False False False && (E) True False False && (E) False False 1º VALOR OPERADOR 2º VALOR RESULTADO True || (Ou) True True True || (Ou) False True False || (Ou) True True False || (Ou) False False VALOR OPERADOR RESULTADO False ! (Não) True True ! (Não) False 3.7.2 OPERADORES ARITMÉTICOS OPERADOR DESCRIÇÃO + Adição - Subtração * Multiplicação / Divisão % Resto/Módulo O entendimento sobre operadores lógicos é essencial para a utilização de estruturas condicionais, utilizando-os podemos escrever corretamente nossas condições. A utilização de operadores de forma incorreta pode acarretar problemas no software, como mal funcionamento ou laços de repetição infinitos. Exemplo de laço de repetição infinito: int n; for(n = 20; n >= 0; n++) { Console.WriteLine(“Executou novamente”); } 28 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Neste exemplo, a variável n é iniciada em 20, enquanto a variável for maior que 0, será incrementado em 1. Isso significa que quanto mais vezes o laço de repetição for executado, mais distante a condição está em se tornar falsa. Chamamos isto de looping infinito. 3.7.3 IF A estrutura condicional do IF é composta pelo comando IF, seguido pela condição a ser atendida entre parênteses e com a abertura das chaves, tudo que está entre as chaves do bloco será executado, caso a condição seja verdadeira. if ( [Condição] ) { //Comandos a serem executados caso a condição seja verdadeira int numero = ;20 if (numero )== 20 { Console.Write( );"O número é 20" } 1 2 4 3 1. Atribuição do número 20 a variável numero. 2. Palavra reservada if. 3. Condicional entre parênteses. 4. Bloco a ser executado, caso a condição seja verdadeira. No exemplo acima é exibido em tela a frase “O número é 20”. 3.7.4 ELSE O bloco do else será executado, caso a condição anterior não seja atendida, o comando else estará sempre após o fechamento das chaves de um IF anterior. if ( [Condição] ) { //Comandos a serem executados caso a condição seja atendida }else{ //Comandos a serem executados caso a condição não seja atendida } 29 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 1 2 4 5 6 7 3 int valor; Console.WriteLine( );”Digite um número“ valor = .Parse( Readline( ));int Console. if (valor == )% 2 0 { Console.WriteLine( + valor + );”O valor “ “ é par” } else { Console.WriteLine( + valor + );”O valor “ “ é impar” } 1. Declaração da variável valor, do tipo inteiro. 2. Exibição da mensagem: “Digite um número”. 3. Atribuição à variável valor, o valor convertido do que o usuário digitou. 4. Comando if, com a condição entre parênteses. A condição é: “Resto da divisão entre a variável valor e 2 retornar 0”. 5. Exibição da mensagem exibindo o valor e a palavra par. 6. Caso a condição do comando if não seja verdadeira, será executado o comando else. 7. Exibição da mensagem exibindo o valor e a palavra ímpar. Neste exemplo, está sendo solicitado um valor guardado na variável valor e então é executada a estrutura condicional. O IF do exemplo possui a seguinte condição “valor % 2 == 0”, isso significa que caso o resto da divisão entre a variável valor e 2 seja 0, entrará no IF, mostrando que o valor é par, caso esta condição não seja verdadeira, entrará no else. _ xPrompt de Comandoc:\. Digite um número 5 O valor 5 é impar_ xPrompt de Comandoc:\. Digite um número 8 O valor 8 é par 30 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 3.7.5 ELSE IF O comando ELSE IF é bastante útil quando se trata de desvios condicionais. O ELSE IF permite que o IF seguido do ELSE só seja verificado se o anterior for falso, isto significa que em uma estrutura com vários condicionais, onde apenas um por vez possa ser executado, existindo 2 ou mais possibilidades. if ( [Condição] ) { //Bloco a ser lido caso a condição seja atendida } else if ( [Segunda Condição] ){ //Bloco a ser lido caso a segunda condição seja atendida } else if ( [Terceira Condição] ){ //Bloco a ser lido caso a terceira condição seja atendida } [...] if (numero > )20 { Console.WriteLine( );”O número é maior que vinte” } else if (numero == )20 { Console.WriteLine( );”O número é vinte” } else if (numero > )10 { Console.WriteLine( );”O número esta entre 10 e 20” } else { Console.WriteLine( );”O número é menor ou igual a 10” } 1 2 3 4 5 6 7 8 1. Comando if, seguido pela condição. 2. Mensagem, caso o primeiro if retorne verdadeiro. 3. Caso o primeiro if retorne falso, será verificada a condição: numero == 20. 4. Exibição da mensagem, caso o segundo if seja verdadeiro. 5. Caso a segunda condicional retorne falso, será verificada a condição de numero > 10. 6. Exibição da mensagem, caso o condicional anterior seja atendido. 7. Caso o condicional não tenha sido atendido, é executado automaticamente o comando else. 31 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 3.7.6 SWITCH CASE Figura 11 – Switch case Fonte: SENAI DR PR, 2019. O Switch é o comando equivalente ao IF-ELSE-IF, com base em uma expressão é verificado qual caso corresponde ao valor. Não há limites para quantidade de cases, porém, nenhum case pode possuir o mesmo valor que outro. Permite-se a utilização do Default, que é executado quando nenhum case corresponde. switch ( [VALOR] ) { case [NÚMERO]: //comandos a serem executados. break; case [NÚMERO]: //comandos a serem executados. break; default: //comandos a serem executados. break; } int numero = ;20 switch (numero) { case 10: Console.WriteLine( );”Dez” break; case 20: Console.WriteLine( );”Vinte” break; case 30: Console.WriteLine( );”Trinta” break; default: Console.WriteLine( );”Nenhum destes corresponde” break; } 1 2 3 6 9 4 7 10 5 8 11 32 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 1. Atribuição do valor 20 à variável numero. 2. Comando switch, colocando em foco a variável numero, sendo este o foco para os casos. 3. Primeiro case, o valor em foco é comparado com o valor 10, caso a comparação entre os dois valores retorne verdadeiro, será executado os comandos até encontrar o comando break. 4. Exibição da palavra “Dez” na tela. 5. O comando break para a execução do switch. 6. Segundo case, o valor em foco é comparado com o valor 20, caso a comparação entre os dois valores retorne verdadeiro, será executado os comandos até encontrar o comando break. 7. Exibição da palavra “Vinte” na tela. 8. O comando break para a execução do switch. 9. O caso default é executado quando nenhum dos casos anteriores corresponde ao valor em foco. 10. Exibição da mensagem “Nenhum destes valores corresponde”. 11. Parada da execução do switch. No exemplo acima, a palavra exibida na tela seria “Vinte”. O break é um comando muito importante, pois sem ele seriam executados os sucessores também, neste caso seria a palavra “Trinta” e frase “Nenhum destes corresponde”. 3.8 Laços De Repetição Figura 12 – Looping Fonte: SENAI DR PR, 2019. Em alguns momentos, será necessário realizar a mesma tarefa n vezes, para que não exista códigos redundantes, utilizando várias linhas e pensando na manutenção dos códigos. Imagine que seja necessário escrever os números de 1 a 1000 e, até o momento, só teríamos a possibilidade de utilizar o Console.Write e Console.WriteLine. Agora, imagine que tenha sido alterado o pedido 33 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT para apenas os números pares. Quanto tempo esta pequena alteração iria impactar no desenvolvimento? Para tarefas repetidas, podemos utilizar os laços de repetição. Os laços de repetição ou looping realizam atividades repetidas várias vezes. São muitos os exemplos como percorrer um vetor (não se preocupe com esta palavra agora, será explicado adiante) ou executar a mesma tarefa repetidas vezes. É comum que as linguagens de programação possuam pelo menos os três principais laços de repetição: FOR, WHILE e DO WHILE. Existem algumas pequenas diferenças entre eles, isso faz com que um laço seja mais recomendado que outro para determinadas ações. 3.8.1 FOR O laço FOR é utilizado quando já sabemos a quantidade de vezes que será percorrido. Um exemplo clássico da utilização deste laço é quando precisamos percorrer um array. O FOR é constituído por 3 parâmetros, sendo eles: inicialização, condição e incremento. for( [Inicialização]; [Condição]; [Incremento ou decremento]){ //Bloco a ser executado enquanto a condição for atendida. } Exemplo de código: int i; for (i = ; i ; i ) {0 <= 10 ++ Console.WriteLine(i); } 1 2 4 5 3 1. Declaração da variável i, do tipo inteiro. 2. Atribuindo o valor 0 a variável i. 3. Condição do laço for, (Enquanto i for menor ou igual a 10). 4. Incremento de 1, para cada vez que o laço for tenha sido executado. 5. Comandos a serem executados em cada passagem do for. Neste exemplo, temos a inicialização com a variável i recebendo 0, a condição é a variável i menor ou igual a 10, e o incremento é de i + 1. 34 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Retorno: _ xPrompt de Comandoc:\. 0 1 2 3 4 5 6 7 8 9 10 Exemplo 2: int i; for (i = ; i ; i ) {10 >= 0 -- Console.WriteLine(i); } 1 2 4 5 3 1. Declaração da variável i, do tipo inteiro. 2. Atribuindo o valor 10 a variável i. 3. Condição do laço for, (Enquanto i for maior ou igual a 0). 4. Decremento de 1, para cada vez que o laço for tenha sido executado. 5. Comandos a serem executados em cada passagem do for. Neste exemplo, temos a inicialização com a variável i recebendo 10, a condição é a variável i maior ou igual a 0, e o incremento é de i - 1. Retorno: _ xPrompt de Comandoc:\. 10 9 8 7 6 5 4 3 2 1 0 35 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Exemplo: static void Main( [ ] )string args { 5 6 7 8 9 10 11int [ ] vetor = { , , , , , , }; int i; for (i = ; i < vetor.Length; i++)0 { Console.WriteLine( + i + +vetor[ i ]);”O valor do vetor na posição [“ “] é “ } Console.Read( ); } 1 2 4 5 6 7 8 3 1. Declaração de um vetor do tipo inteiro. 2. Nome do vetor. 3. Símbolo de atribuição. 4. Valores que estão sendo atribuídos ao vetor. 5. Declaração de uma variável do tipo inteiro. 6. Laço de repetição for. 7. Mensagem que será exibida: “O valor do vetor na posição vetor[”, seguido pelo valor atual da variável i, seguido pela mensagem: “é ”, seguido pelo valor do vetor na posição i. 8. Comando para espera de uma tecla, evitando o fechamento automático do programa. Neste exemplo, temos um vetor do tipo inteiro com os valores 5, 6, 7, 8, 9, 10, 11, uma variável e um for. Neste caso, o for está iniciando a variável i para 0, enquanto esta variável for menor que o tamanho do vetor, será incrementado 1. Quando executamos este código, temos o seguinte retorno em tela. O valor do vetor na posição [0] é 5 O valor do vetor na posição [1] é 6 O valor do vetor na posição [2] é 7 O valor do vetor na posição [3] é 8 O valor do vetor na posição [4] é 9 O valor do vetor na posição [5] é 10 O valor do vetor na posição [6] é 11 _ xPrompt de Comandoc:\. 3.8.2 WHILE while ( [Condição] ){ //Bloco a ser executado enquanto a condição for atendida.} 36 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT O laço de repetição WHILE é utilizado quando não sabemos a quantidade de execuções necessárias, o laço será executado até a condição se tornar falsa. É importante frisar que este laço pode não executar nenhuma vez, pois é realizada a verificação antes de executar. Exemplo de código. int x = ;1 while (x )! = 0 { x = .Parse( .ReadLine( ));int Console } Console.WriteLine( );”Fim“ Console.Read( ); 1 2 4 5 6 7 8 3 1. Atribuição do valor 1 à variável x. 2. Comando While. 3. Condição do laço de repetição While, neste caso é: enquanto x for diferente de zero. 4. Variável x, seguida pelo símbolo de atribuição. 5. Conversão do valor que está entre parênteses para inteiro. 6. Leitura do valor digitado pelo usuário. 7. Escrita da palavra Fim em tela 8. Comando de leitura de teclado, evitando o fechamento automático do programa. Neste exemplo, o laço de repetição será executado enquanto o usuário não digitar o valor 0. Ainda no mesmo caso acima, o looping é ativado pelo menos uma vez pelo fato do x iniciar com o valor 1, caso se inicie com o valor 0, o laço de repetição não será lido. 3.8.3 DO WHILE do { //Bloco a ser executado enquanto a condição for atendida. } while ( [Condição] ); O laço de repetição DO WHILE é utilizado quando não sabemos a quantidade de execução necessárias como o WHILE, porém a diferença principal entre os dois é que o DO WHILE verifica após a execução, então este laço de repetição irá executar o bloco pelo menos uma vez. 37 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Exemplo de código: int x = ;0 do{ x = .Parse( .ReadLine( ));int Console } (x );while ! = 0 Console.WriteLine( );”Fim“ Console.Read( ); 1 2 4 5 6 3 1. Atribuição do valor 0 à variável x. 2. Comando do, iniciando o comando do while, seguido pela abertura do bloco de comando. 3. Conversão e atribuição do valor digitado pelo usuário a variável x. 4. Fechamento do bloco do while, utilizando o comando while, seguido pela condição entre parênteses. 5. Escrita da palavra “Fim” na tela do console. 6. Comando Console.Read() aguardar uma tecla do usuário antes de fechar o programa. Neste exemplo, o laço de repetição será executado enquanto o usuário não digitar o valor 0. O looping é ativado pelo menos uma vez, mas desta vez sem a necessidade de x iniciar com o valor diferente da condição. Todo looping DO WHILE terá sua execução pelo menos uma vez quando lido. 3.9 Vetores e Matrizes Ao pensar em guardar 4 notas bimestrais de 50 alunos de um colégio, podemos imaginar quantas variáveis não precisam ser instanciadas? Quantas linhas de código não precisam ser escritas para ler os valores, calcular e mostrar os resultados? Porém, para guardar valores que fazem parte de um mesmo conjunto, podemos utilizar vetores e matrizes. Vetores e matrizes representam conjuntos de dados que por sua vez facilitam o armazenamento de informações, ao invés de criar 20 variáveis do mesmo tipo para armazenar dados sobre o mesmo foco e conteúdo, pode-se simplesmente criar um vetor com 20 posições, permitindo percorrer o mesmo com laços de repetição. 38 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 3.9.1 VETOR Figura 13 – Vetor Fonte: SENAI DR PR, 2019. Vetores armazenam mais de um valor do mesmo tipo de dado, cada valor armazenado é guardado em uma posição. Armazenando os valores de forma unidimensional, a sua declaração baseia-se no tipo de dado escolhido e, para realizar a declaração de um vetor do tipo inteiro com 5 posições, pode ser utilizado o seguinte código: int [ ] valores = [ ];new int 5 1 2 4 53 Para realizar a declaração de um vetor, deve-se seguir os seguintes passos: 1. Tipo de dado seguido da abertura e fechamento dos colchetes. 2. Nome do vetor. 3. Sinal de atribuição (sinal de igual). 4. Palavra reservada new. 5. Novamente o tipo de dado com a quantidade de valores entre colchetes. A atribuição dos valores à matriz segue a mesma ideia da variável, com a alteração que se deve colocar a posição que o valor será atribuído. valores[ ] = ;0 2 valores[ ] = ;1 4 valores[ ] = ;2 8 valores[ ] = ;3 16 valores[ ] = ;4 32 39 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT A primeira posição é a posição 0, muita atenção nesta parte, pois um vetor com 5 posições chega até a posição número 4. FIQUE ATENTO! A melhor forma de se percorrer um vetor é com o uso de laços de repetição: for (contador = ; contador <= ; contador )0 4 ++ { Console.WriteLine(valores[contador]); } 1 2 5 4 7 3 6 1. Comando for. 2. Atribuição do valor 0 à variável contador. 3. Condição para execução do laço for. “Enquanto contador for menor ou igual a 4”. 4. Incremento do contador em 1, para cada execução do contador. 5. Comando para exibição em tela. 6. Nome do vetor. 7. Posição do vetor. O valor da variável contador é alterado a cada passagem do for, fazendo com que a posição do vetor valores também seja alterado em cada passagem. Resultado: 2 4 8 16 32 _ xPrompt de Comandoc:\. Porém, pode-se também mostrar apenas a posição que deseja. Console.WriteLine(valores[2]); 1 2 3 1. Comando para exibição em tela. 2. Nome do vetor. 3. Posição do vetor. 40 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Neste exemplo, é exibida a terceira posição, no caso a posição número 2, levando em consideração que a primeira posição é a 0. Resultado: 8 _ _ xPrompt de Comandoc:\. 3.9.2 MATRIZES Figura 14 – Matriz Fonte: SENAI DR PR, 2019. Matrizes armazenam valores do mesmo tipo de dado, o armazenamento é realizado de forma bidimensional, sendo necessário passar a linha e coluna em que o valor se encontra. A declaração de matrizes é muito parecida com a de vetores, alterando alguns pontos na declaração e uso. Declaração de matriz bidimensional: [Tipo][,] [nomeVetor] = new [Tipo][[quantidadeLinhas], [QuantidadeColunas]]; string new string[ , ] paises = [ , ];2 2 Atribuição de valores: [nomeVetor][[posiçãoLinha], [posiçãoColuna]] = [valor]; paises[ , ] = ;0 0 ”Portugal” paises[ , ] = ;0 0 ”Brasil” paises[ , ] = ;0 0 ”Espanha” paises[ , ] = ;0 0 ”México” Percorrer a matriz utilizando laços de repetição. 41 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT for (linha = ; linha <= ; linha )0 1 ++ { for (coluna = ; coluna <= ; coluna )0 1 ++ { Console.WriteLine(valores[contador]); } } 1 2 3 1. Laço de repetição para percorrer linhas. 2. Laços de repetição para percorrer as colunas. 3. Comando de exibição para mostrar o valor da posição linha e coluna da matriz países. Resultado: Portugal Brasil Espanha México _ xPrompt de Comandoc:\. Desta vez são necessários dois laços de repetição, um para percorrer as linhas, e então é utilizado um laço de repetição para percorrer todas as colunas de cada linha. Para se exibir um valor específico dentro de uma matriz é simples: Console.WriteLine([nomeVetor][[posiçãoLinha], [posiçãoColuna]]); Console.WriteLine(paises[ , ]);0 1 Ao executar esta linha será exibido o valor armazenado na primeira linha, segunda coluna. Resultado: Brasil _ _ xPrompt de Comandoc:\. 3.10 Métodos – Funções e Procedimentos Métodos são sub-rotinas de código, podendo ou não retornar algo, como também podem ou não solicitar algum dado como parâmetro. Funções e procedimentos permitem a execução da mesma sub- rotina em diversas partes do software, isso evita a reescrita de código. 42 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Os subprogramas ou métodos possuem funcionalidades específicas, pois além de agilizar a codificação deixa o código mais limpo melhorando a compreensão do código para outros programadores, podendo assim, facilitar também na manutenção do código. Uma das partes mais interessantes dos métodos é que independentementeda quantidade de chamadas, caso seja alterado o método principal, todas estas chamadas terão a mesma alteração, isto reflete em um tópico muito importante do desenvolvimento, a facilidade de manutenção do código. A diferença entre função e procedimento é o fato de que as funções possuem retorno, enquanto os procedimentos não possuem. A declaração dos métodos é bem parecida com a das variáveis, com as mesmas regras. A nomeação dos métodos por convenção é escrita com a primeira letra de cada palavra em maiúsculo, inclusive a primeira letra. Sempre utilizando um verbo no infinitivo que representa sua função. Ex: CalcularSoma() CalcularDivisao() TestarLeds() ImprimirReceita() Exemplo de Função [Visibilidade] [retorno] [NomeFunção] ( [Parâmetros] ){ //Bloco de comandos } static void Main( [ ] args)string { int n1, n2, resultado; Console.WriteLine( );”Digite um número” n1 = .Parse( .ReadLine( ));int Console Console.WriteLine( );”Digite um segundo número” n2 = .Parse( .ReadLine( ));int Console resultado = Somar(n1, n2); Console.WriteLine(resultado); Console.Read( ); } static public int int intSomar( n1, n2) { return n1 + n2; } 1 2 3 4 5 6 7 8 9 10 11 12 43 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 1. Declaração das variáveis n1, n2 e resultado. 2. Exibição da mensagem “Digite um número”. 3. Conversão do valor digitado pelo usuário para inteiro, atribuindo-a para variável n1. 4. Exibição da mensagem “Digite um segundo número”. 5. Conversão do valor digitado pelo usuário para inteiro, atribuindo-a para variável n2. 6. Atribuindo o valor retornado da função Somar à variável resultado. 7. Exibição em tela do valor da variável resultado. 8. Comando de leitura de tecla utilizado para não permitir o fechamento do programa automaticamente. 9. Tipo do retorno da função. 10. Nome da função. 11. Parâmetros. 12. Retorno da soma dos parâmetros. 3.10.1 RETORNO Retornos são utilizados quando se deseja retornar alguma informação a quem chamou o módulo, para isso é utilizado o comando return. Essa ação pode ser o resultado de um cálculo ou uma busca, podendo trazer uma ou mais informações. O retorno é uma resposta de uma função, essa resposta pode vir em diferentes tipos de dados, como int, float, double, string etc. O valor retornado, pode também ser um conjunto, como uma matriz ou um vetor. Para utilizá-lo é necessário definir qual é o tipo de dado que o método irá retornar logo após sua visibilidade. Por padrão o retorno é void, esta palavra reservada significa que o método não retorna nenhum dado. 44 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT static void Main( [ ] args)string { Console.WriteLine( );”Digite um número” int numero = int.Parse( .ReadLine( ));Console string resposta = V carParImpar(numero); Console.WriteLine(resposta); Console.Read( ); } static public string intVe carParImpar( n) { if (n % == )2 0 { return ”Par”; } else { return ”Impar”; } } 1 2 3 4 5 6 7 8 9 10 11 12 1. Exibição da mensagem “Digite um número” em tela. 2. Conversão do valor digitado pelo usuário para inteiro, atribuindo à variável número. 3. Declaração da variável resposta, do tipo string, atribuindo o valor retornado pela função VerificarParImpar, enviando como parâmetro a variável número. 4. Exibição da variável resultado. 5. Comando para aguardar uma tecla antes de finalizar o programa. 6. Tipo de retorno. 7. Nome da função. 8. Parâmetros 9. Condicional para verificação do resto da divisão entre n e 2. 10. Retorno da palavra “Par”. 11. Comando else, sendo executado caso o if retorne um valor falso. 12. Retorno da palavra “Impar”. Todas as saídas possíveis do método devem retornar algo, para isso se utiliza a palavra reservada return seguido da informação que irá ser retornada. O método será substituído pela informação de retorno, podendo ser utilizada de diversas maneiras, como por exemplo, dentro de uma estrutura condicional de repetição, atribuindo-a à uma variável ou até mesmo passando como parâmetro para outro método. A utilização da informação retornada pelo método irá depender da necessidade e das regras de negócio do software. 45 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Exemplo de Procedimentos [Visibilidade] void [nomeProcedimento]( [Parâmetros] ){ //Bloco de comandos } static void Main( [ ] args)string { int n1, n2; Console.WriteLine( );”Digite um número” n1 = .Parse( .ReadLine( ));int Console Console.WriteLine( );”Digite um segundo número” n2 = .Parse( .ReadLine( ));int Console Somar(n1, n2); Console.Read( ); } static public void int intSomar( n1, n2) { Console.WriteLine(n1 + n2); } 1 2 3 4 5 6 7 8 9 10 11 1. Declaração das variáveis inteiras n1 e n2. 2. Exibição em tela a mensagem “Digite um número”. 3. Conversão do valor digitado pelo usuário para int, atribuindo-a na variável n1. 4. Exibição da mensagem “Digite um segundo número”. 5. Conversão do valor digitado pelo usuário para int, atribuindo-a na variável n2. 6. Chamada do procedimento Somar, enviando como parâmetro as variáveis n1 e n2. 7. Aguardando tecla do usuário para finalização do programa. 8. O procedimento não irá possuir retorno, sinalizado pela palavra reservada void. 9. Nome do procedimento. 10. Parâmetros. 11. Exibição da soma dos parâmetros. 3.10.2 PARÂMETROS Os parâmetros são dados enviados para o método, para que funcionem de maneira correta, estas informações são necessárias para que sejam utilizados nos métodos, os parâmetros podem ser de diversos tipos. Para criar um método que some dois números, é necessário realizar o envio de dois inteiros para que o método consiga executar de forma correta. 46 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Exemplo de Função com parâmetros [Visibilidade] [Retorno] [NomeFunção] ( [Parâmetros] ) { //Comandos return [Retorno]; } public int Soma( a, b)int int { return a + b; } 1 2 3 4 5 1. Visibilidade. 2. Retorno. 3. Nome do procedimento. 4. Parâmetros. 5. Retorno do resultado da soma dos dois parâmetros. Exemplo de Procedimento com parâmetro [Visibilidade] void [NomeFunção] ( [Parâmetros] ) { //Comandos } public void Soma( a, b)int int { Console.WriteLine(a + b); } 1 2 3 4 5 1. Visibilidade. 2. Retorno vazio. 3. Nome do procedimento. 4. Parâmetros. 5. Exibição do resultado da soma dos dois parâmetros. 47 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 4 PROGRAMAÇÃO ORIENTADA A OBJETOS Neste capítulo, iremos entender termos e aplicações da orientação a objetos, sendo abordados conceitos como classes, objetos, atributos, métodos, além dos pilares que cercam o paradigma orientado a objetos. Para compreender o tema deste capítulo, é preciso compreender a base, que se fundamenta em classes, objetos, atributos e métodos, além dos pilares que estão divididos em: Abstração, Herança, Polimorfismo e Encapsulamento. Iremos nos familiarizar e entender o que são termos como escopo e variável, modificadores estáticos e cláusulas de visibilidade. Este material foi desenvolvido para apresentar e exemplificar os conceitos utilizando a linguagem C#. Porém esses conceitos podem ser aplicados a outras linguagens orientadas a objetos, podendo haver diferenças de sintaxe, forma de instanciação e de importações de bibliotecas. Entendendo bem os conceitos aqui apresentados, pode-se implementá-los em outra linguagem, sendo necessário estudar as suas caraterísticas. A primeira linguagem a implementar conceitos de orientação a objetos foi a SIMULA 67 na década de 60. CURIOSIDADE 48 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 4.1 PILARES DA ORIENTAÇÃO A OBJETOS A programação orientada a objetos possui 4 grandes pilares que não podem ser aplicados na programação estruturada. Vale ressaltar que cada pilar possui sua importância.Os 4 pilares são polimorfismo, herança, abstração e encapsulamento. Cada um apresenta uma função específica, entretanto eles trabalham juntos para atribuir a característica de linguagem orientada a objeto. Configura a representação dessa estrutura na figura abaixo. Figura 15 - Pilares da Orientação a Objetos Fonte: SENAI DR PR, 2019. 4.1.1 ABSTRAÇÃO Abstração consiste em trazermos algo do mundo real ao mundo virtual, conseguirmos modelar qualquer coisa do mundo que conhecemos para o mundo que a máquina conhece. Este é o pilar mais importante, pois sem ele não teríamos nenhum outro. O processo de identificação dos relacionamentos e classes que o sistema irá contemplar está ligado ao pilar da abstração, nele é tratado o processo de transformar partes do mundo real para classes do mundo virtual como a criação de classes, contemplando atributos genéricos dos objetos 49 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT do mundo real. É importante entender que quando se fala em objetos em POO vindos do mundo real podem ser: pessoa; carro; banco; conta; usuário; calculadora; animal ou qualquer coisa que se pode representar com atributos e métodos. “O processo de abstração compõe-se de um conjunto de operações realizadas com a finalidade de representar objetos do mundo real como classes, de modo que eles possam interagir em um programa para realizar determinadas tarefas. Um primeiro esforço deve ser empreendido no sentido de identificar os atributos e métodos relevantes de cada classe e para eliminar atributos e métodos desnecessários.” (SANTOS, 2014, p 332) As operações citadas pelo autor, referem-se à identificação das necessidades que serão utilizadas no desenvolvimento do software, alguns atributos e métodos podem ser descartados neste processo por não ser necessário ou não fazer sentido à existência do mesmo para o programa. 4.1.2 HERANÇA A definição de herança é muito parecida com a que já conhecemos de DNA, herdar característica de nossos pais. No caso da orientação a objetos, iremos herdar atributos e métodos que possuem na classe mãe (apenas métodos e atributos públicos ou protegidos). A herança permite o reaproveitamento de código, essencialmente classificação, evitando a reescrita. Além de deixar claro a hierarquia entre classes, permite que sejam escritos objetos mais especializados herdando de classes mais generalistas. Santos (2014), apresenta uma definição de herança que corrobora com as informações citadas até agora. “Herança é o mecanismo que possibilita a criação de novas classes a partir de uma já existente como forma de reutilizar seus membros. Isto é possível mesmo quando não se tem acesso ao código-fonte da superclasse. É o mecanismo de herança que permite realizar as operações de especialização e generalização. Trata-se de um mecanismo fundamental para quaisquer linguagens que suportem o paradigma orientado a objetos A aplicação do mecanismo da herança sempre envolve dois papéis: uma superclasse e uma subclasse. A superclasse, também conhecida como classe ancestral, é aquela que representa as características genéricas de um conjunto de objetos. A subclasse, também conhecida como classe descendente, é aquela que estende a superclasse para incluir a representação de características especificas de um subconjunto desses objetos.” (SANTOS, 2014, p 488). Um objeto criado de uma classe filha, também pertence à classe mãe. Na figura abaixo, podemos entender que a classe bicicleta também pertence à classe veículo. 50 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Figura 16 - Herança Fonte: SENAI DR PR, 2019. class Veiculo { public string marca; private string chassi; protected string placa; } class Carro Veiculo: { } Neste caso acima, a classe Carro está herdando da classe Veículo, os atributos herdados são os que foram definidos como public e protected. A sintaxe para herança pode variar entre as linguagens, em alguns casos será utilizada a palavra-chave extends, ou utilizado o símbolo de dois pontos “ : ”, podendo até ser diferente destas formas, porém o conceito é o mesmo nas linguagens de programação orientadas a objetos. { ( ) public void Ve car { this. } } } 0 references Equals GetHashCode GetType marca MemberwiseClone placa ToString Verificar > Ao acessar os atributos e métodos de possível utilização na classe carro, podemos encontrar placa e marca, pois são do tipo Protected e Public, porém, não temos acesso à chassi que é private. 51 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Vamos imaginar que temos as seguintes classes: Animal; Gato; Mamífero. A classe Gato herda de Mamífero, que por sua vez herda de Animal; portanto, pode-se dizer que Animal é a classe mais genérica e Gato é a classe mais específica. 4.1.2.1 SOBRESCRITA DE MÉTODO A sobrescrita de método se dá quando uma classe filha reescreve um método que veio de uma classe mãe, fazendo com que caso um objeto chame este método seja executado o método da classe filha. Os fins de se sobrescrever métodos é torná-los mais específicos. Esta prática está ligada diretamente à herança. Para realizar a sobrescrita de método, é importante saber que o método que está sendo criado deve possuir o mesmo nome, a mesma quantidade e tipo de parâmetros utilizados no que está sendo sobrescrito. 4.1.3 POLIMORFISMO O polimorfismo diz respeito aos métodos dos objetos, permitindo que um método de classe abstrata tome diferentes comportamentos pelas classes filhas, fazendo que a mesma assinatura de método em duas classes diferentes tome comportamentos diferentes, isso permite uma série de possibilidades na programação. O termo Polimorfismo originou-se do grego “Poli morphos”, que significa “muitas formas”. CURIOSIDADE Figura 17 - Polimorfismo Fonte: SENAI DR PR, 2019. Para exemplificar o Polimorfismo, iremos realizar algumas modificações em nossas classes. 52 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Classe Veículo: class Veiculo { public virtual void Locomover( ) { } } 4 references A cláusula virtual é utilizada para indicar que o método pode ser sobrescrito pelas classes filhas. Classe Carro: class Carro Veiculo: { public override void Locomover( ) { Console. ( );WriteLine ”Correr” } } 4 references 1 2 3 4 1. Subclasse Carro. 2. Símbolo para herança. 3. Super Classe Veículo. 4. Cláusula override, para indicar a sobrescrita do método. Classe Aviao: class Aviao Veiculo: { public override void Locomover( ) { Console. ( );WriteLine ”Voar” } } 4 references Classe Program: class Program { static void stringMain( [ ] )args { newVeiculo Carroa = ( ); newVeiculo Aviaob = ( ); a.Locomover( ); .b Locomover( ); Console.Read( ); } } 0 references 53 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Resultado final: _ xPrompt de Comandoc:\. Correr Voar O método Locomover(), embora tenha o mesmo nome, é executado de forma diferente dependendo da classe à qual está inserido. 4.1.3.1 SOBRECARGA DE MÉTODO: A sobrecarga de método é uma parte do polimorfismo que por definição é a criação do método com o mesmo nome, porém com diferentes parâmetros. Com a utilização de sobrecarga, é possível executar diferentes funcionalidades dependendo dos tipos e quantidades de parâmetros enviados. public int int intCalcular( a, b) { return a + b; } public int int int intCalcular( a, b, c) { return a + b + c; } public int int int int intCalcular( a, b, c, d) { return a + b + c + d; } public float float intCalcular( a, b) { return a + b; } 4.1.4 ENCAPSULAMENTO É o que permite a ocultação de detalhes internos do funcionamento de métodos para outros objetos. O encapsulamento também diz respeito à divisão dos métodos, mantendo o código coeso. Quando se está codificandoem equipes, é importante garantir que todos respeitem as regras de negócio para alterações dos atributos, lembrando que em alguns casos é necessário realizar algumas 54 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT verificações antes de que qualquer atributo seja alterado. Para isso, podemos utilizar o encapsulamento o qual permite que se crie algumas verificações para garantir que os atributos sejam alterados, caso passem por algum tipo de validação. Um bom exemplo é o de saldo do banco, a alteração só deve ser feita caso seja comprovada a veracidade. Figura 18 - Encapsulamento Fonte: ADAPTADO DE SHUTTERSTOCK, 2019. Imaginando o cenário de um banco digital, com o saldo sem estar encapsulado, qualquer outro programador pode acessar a classe e realizar as alterações que desejar, desrespeitando qualquer regra de negócio. Para que nenhuma outra classe tenha acesso ao atributo diretamente, é importante que esteja com o modificador de privado. Caso seja realizado o encapsulamento de forma correta, as alterações dos atributos são realizadas apenas por métodos da classe atual. Isso faz com que caso seja necessário realizar uma alteração, adicionando ou retirando regras de negócio, não seja necessário realizá- la em diversas partes do código. Figura 19 - Proteção por encapsulamento Fonte: ADAPTADO DE SHUTTERSTOCK, 2019. class Conta { public double saldo; } 55 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Quando se deixa o atributo público, toda classe pode acessar e modificar o valor do objeto. class Conta { private double saldo; } Ao deixar o atributo privado, o acesso pode ser realizado apenas na mesma classe. class Conta { private double saldo; private double getSaldo( ) { this.return saldo; } private void setSaldo(double novoSaldo) { this.saldo = novoSaldo; } } 0 referências 0 referências Ao inserir os métodos get e set, é possível acessar o atributo, porém os métodos permitem que se façam algumas validações. Tais validações irão variar conforme a regra de negócio, pode-se por exemplo, verificar se o novo saldo é negativo, ou ainda, solicitar o novo saldo juntamente com um código de segurança ou número da transação. Os métodos get e set são métodos assessores, e servem para realizar uma intermediação ao atributo. É recomendado a utilização destes métodos para inserção das regras de negócio. “Esconder características de um objeto as quais só interessam ao próprio objeto visa garantir sua integridade, isto é, assegurar que o usuário do objeto não o danifique. Assim, ao projetarmos uma classe, só devem ser disponibilizados os métodos necessários à utilização do objeto. O projetista de uma classe precisa considerar que o usuário do objeto deve visualizá- lo como uma entidade completa e com o qual se comunica através dos serviços que o objeto pode executar, sem a necessidade do conhecimento de sua estrutura e do funcionamento interno.” (BORATTI, 2007, p 142). Nomear atributos e métodos é uma forma de manter autoexplicativa a utilização de cada parte da classe, o retorno colabora indicando o que o utilizador do método irá receber como resposta, fazendo com que não seja necessário conhecer como o método funciona internamente. 56 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Ao escrever atributos e métodos de uma classe, devemos analisar a necessidade de exibi-los aos usuário. Em alguns momentos é necessário dividir o mesmo método em vários menores, neste caso, talvez seja interessante encapsular porque não existe a necessidade de mostrá-los fora da classe. “O encapsulamento é um princípio importante durante a definição de classes. A ideia é que um programa que utiliza uma classe não precisa se preocupar com o modo como essa classe realmente funciona internamen- te; o programa simplesmente cria uma instância de uma classe e chama os métodos dessa classe. Desde que esses métodos façam o que se propõe a fazer, o programa não se preocupa com a maneira como eles são im- plementados. Por exemplo, ao chamar o método Console.WriteLine, você não quer se incomodar com todos os detalhes complicados de como a classe Console organiza fisicamente os dados a serem escritos em tela. Uma classe talvez precise manter todos os tipos de informações internas para executar seus vários métodos. Essas ativi- dades e informações de estado adicionais são ocultas do programa que está utilizando a classe. Portanto, o encapsulamento é às vezes chamado de ocultamento de informação.” (SHARP, 2014, p 162). Como o autor explica, não é necessário entender o processo de execução interna de um método, apenas o que este método pede como parâmetro, o que irá retornar como resposta e o que o método irá realizar, mas não como realizar.Figura 20 - Separação por pequenas partes Fonte: SENAI DR PR, 2019. 57 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT O autor ainda cita dois objetivos, sendo eles: • Combinar os métodos e dados dentro de uma classe, ou seja, dar suporte à classificação. • Controlar a acessibilidade de métodos e dados, ou seja, controlar o uso da classe. public string nome; public int codigo; private Double saldo; public void saldosetSaldo( )Double { if( > )saldo 0 { this saldo.saldo = ; } } 0 references No código acima, a única forma de outras classes modificarem o saldo é por meio do setSaldo(), a validação interna pode ser melhorada. A validação interna do encapsulamento garante que outros desenvolvedores que irão utilizar a classe não se preocupem tanto com algumas regras internas, além de garantir uma proteção mais adequada. A ideia é que nenhuma classe acesse os atributos de outra classe diretamente, ou seja, o acesso deve ser realizado por meio de métodos. Além da proteção que o encapsulamento nos oferece, também temos a vantagem de criar um padrão, facilitar a reutilização de código, além de reduzir os efeitos colaterais na alteração de código. Este pilar permite que esconda todos os detalhes internos dos funcionamentos do método. O encapsulamento de forma bem-feita colabora de forma efetiva na manutenibilidade de código, pois minimiza o impacto de mudança. Atributos: referem-se às características de uma classe, são exemplos de atributos para uma suposta classe Veículo: cor; marca; ano; modelo; combustível; dentre outros. Os atributos devem fazer sentido à classe em que está inserida. 58 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT “Pode haver dois ou mais objetos que possuam alguns atributos com os mesmos valores. Entretanto, em função de sua própria natureza, o valor de alguns atributos é único e não se repete entre os diversos objetos semelhantes. Existe uma infinidade de carros cuja cor é vermelha, mas não pode haver dois carros com a mesma placa ou chassi etc.”. (SANTOS, 2014, p 329). Entende-se que embora possa haver atributos iguais, deve-se existir algum atributo que o diferencie de todos os outros, como a placa e o chassi para um carro ou o CPF e RG para uma pessoa. Cada atributo irá possuir uma visibilidade e também um tipo de dado. Figura 21 - Atributos Fonte: ADAPTADO DE SHUTTERSTOCK, 2019. Métodos: referem-se aos comportamentos que o objeto pode tomar, são exemplos para uma possível classe carro: ligar, desligar, frenar, acelerar, buzinar. “Além de possuir atributos, os objetos também manifestam um comportamento. O comportamento dos objetos diz respeito às ações que eles podem realizar ou serviços que eles podem prestar. O cachorro pode correr, pular, latir e até buscar o jornal para seu dono. O computador pode ligar-se, desligar-se, processar dados, exibir informações no vídeo, imprimir textos na impressora e emitir sons”. (SANTOS, 2014, p 329). As ações dos objetos denominam-se métodos, estes são abstraídos da realidade e realizam algumcomportamento. Devem fazer sentido à classe em que estão inseridos e podem ou não possuir algum tipo de retorno, como podem ou não possuir parâmetros. Por definição, o método é um conjunto de instruções agrupadas em um bloco de código, um elemento indispensável em programação. O nome do método é sempre escrito com um verbo no infinitivo. Quando bem escritos colaboram para a manutenção de código, além de simplificar, aumentar a velocidade, dinamismo e integração no desenvolvimento em equipes. 59 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Após o nome do método sempre irá existir a abertura e fechamento de parênteses, podendo possuir algum valor entre os mesmos e este valor é chamado de parâmetro. A assinatura deste método é definida pelo nome juntamente com seus parâmetros. Pode-se possuir mais de um método com o mesmo nome, porém os parâmetros da assinatura devem ser diferentes. Figura 22 - Métodos Fonte: ADAPTADO DE SHUTTERSTOCK, 2019. É possível e bastante comum a interação entre objetos de classes diferentes por meio de métodos. class Carro { public string marca; public string modelo; public string combustivel; public int qtdPortas; public int ano; public void Acelerar( ) { } public void Desacelerar( ) { } public void Ligar( ) { } public void Desligar( ) { } } 2 references 0 referências 0 referências 1 2 3 4 5 1. Visibilidade do atributo. 2. Retorno do método. 3. Nome do Método. 4. Parâmetros. 5. Bloco a ser executado quando o método for chamado. 60 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 4.2 Métodos e retornos O retorno é muito utilizado na criação de softwares, pois permitem que os métodos retornem alguma informação após a finalização. Retornando alguma informação a quem chamou o módulo, podendo ser de diferentes tipos de dados como int, float, double, para este retorno é necessário a utilização da clausula return. Para utilizá-lo é necessário definir qual é o tipo de dado que o método irá retornar logo após sua chamada. Pode-se utilizar o tipo void, esta palavra reservada indica que o método não retorna nenhum dado. class Calculadora { public double double doubleDividir ( a, b) { if (a == 0 | | b == 0) { ;return 0 } else { return a / b; } } } 0 referências 0 referências Todas as saídas possíveis do método devem retornar algo, para isso se utiliza a palavra reservada return seguido da informação que irá ser retornada. Após a execução do método, é devolvida um ou mais dados como retorno, podendo ser utilizados de diversas maneiras, como por exemplo, dentro de uma estrutura condicional de repetição, atribuindo-a à uma variável ou até mesmo passando como parâmetro para outro método. class Program { static void stringMain ( [ ] args) { double a = 3,14, b = 5; double resultado; Calculadora Calculadoracalc = ( );new resultado = calc. (a, b);Dividir Console. (resultado);Write Console. ( );Read } } A utilização da informação retornada pelo método irá depender da necessidade e das regras de negócio do software. 61 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Resultado esperado ao executar: _ xPrompt de Comandoc:\. 0,628 Classe: Refere-se a um conjunto de atributos e métodos abstraídos do mundo real, alguns exemplos de classes são: Carro; Cachorro; e Pessoa. Segundo SANTOS, 2014, p 331: “Quando um conjunto de objetos possui atributos comuns, significa que eles pertencem a uma mesma categoria. Se João e Maria são dois clientes de uma empresa, pode-se dizer que, apesar de eles serem pessoas distintas, eles pertencem a uma mesma categoria: a dos clientes. O termo classe é utilizado para significar o mesmo que categoria. Ao invés de dizer que João e Maria pertencem a uma categoria dos clientes, pode-se dizer que eles pertencem a uma classe dos clientes. Eles são dois objetos que possuem características comuns e, portanto, serão representados no sistema como uma classe.” O autor ainda complementa em sequência: “Uma classe representa um grupo de objetos com características comuns e compõe-se, basicamente, de atributos e de métodos. Os atributos representam as características dos objetos e os métodos representam as ações que eles podem realizar ou serviços que eles podem prestar.” (SANTOS, 2014, p 332). Classes são conjuntos de objetos com atributos comuns entre eles, como por exemplo, a classe carro que possui ano, marca e modelo. Embora os objetos (carros) possuam as mesmas características gerais, elas podem ser diferentes ao detalha-las como a cor vermelha para um carro e a prata para outro. Podemos comparar a classe com uma forma de bolo, todos os bolos criados por meio desta forma terão o mesmo formato, porém cada um pode ter sabores diferentes, o bolo neste caso é o objeto criado por meio da classe (forma). Retornemos ao exemplo da classe Carro, sabemos que todo carro proveniente de nossa classe terá uma marca, modelo, um tipo de combustível, além do ano e quantidade de portas. 62 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT class Carro { public string marca; public string modelo; public string combustivel; public int qtdPortas; public int ano; public void Acelerar( ) { } public void Desacelerar( ) { } public void Ligar( ) { } public void Desligar( ) { } } 0 referências 0 referências 0 referências 0 referências } } 1 2 3 1. Classe Carro. 2. Atributos marca, modelo, combustível, qtdPortas, ano. 3. Métodos Acelerar, Desacelerar, Ligar e Desligar. Objetos: São instâncias de classes, possuindo os valores atribuídos aos seus devidos atributos. Em uma classe podemos possuir um atributo chamado cor: no nosso primeiro objeto instanciado podemos definir inicialmente o valor azul; no segundo objeto podemos definir a cor verde; e no terceiro, podemos inserir verde novamente. “Em termos de programação, podemos definir um objeto como sendo a abstração de uma entidade do mundo real, que representa sua própria existência, identificação, características de composição e que tem alguma entidade, isto é, pode executar determinados serviços quando solicitado.” (BORATTI, 2007, p 30). Como o autor cita, podemos definir o objeto como a abstração de uma entidade do mundo real, pois nesta etapa são definidos os valores para os atributos do objeto. Um exemplo é quando se cria um objeto abstraindo as características reais. Está sendo definido a placa do carro, o chassi, a cor, o modelo e o ano, todas estas características sendo trazidas de um carro real. 63 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT A instanciação de uma classe ou criação de objeto se dá com a utilização da palavra reservada new. Ex.: [nomeClasse] [nomeObjeto] = new [nomeClasse](); Dois objetos não podem possuir o mesmo nome da instância, mas podem possuir nomes parecidos, como por exemplo: carro1 e carro2. Por regra, espaço, acentuação e símbolos não são usados na nomeação de objetos (com exceção do underline). Da mesma forma que na declaração das variáveis e constantes, números podem ser utilizados, porém não como primeiro caractere do nome da variável. Caso os atributos e métodos sejam escritos sem concordância com estas regras, a IDE irá mostrar como erros de sintaxe e não permitirá a compilação do programa. Temos algumas boas práticas que facilitam o entendimento e oferecem uma padronização de nomeação, sendo os atributos escritos com a primeira inicial em minúsculo e as demais iniciais escritas em maiúsculo, sem utilizar o underline como separador. Enquanto o método possui todas as iniciais em maiúscula, caso não seja escrita desta forma, não será exibido um erro, nem irá impedir a compilação do programa. A classe Carro com seus atributos ficaria da seguinte forma: using System.Collectons.Generic using System.Text; namespace Carro {class Carro { public string marca; public string modelo; public string combustivel; public int qtdPortas; public int ano; } } 2 referências 64 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Após criar uma classe carro e adicionar seus respectivos atributos, poderemos chamá-los na classe Program. static void stringMain( [ ] args) { newCarro CarromyCar = ( ); myCar.marca = ;“Ferrari” myCar.modelo = ;“Portofino” myCar.combustivel = ;“Gasolina” myCar.ano = ;2019 myCar.qtdPortas = ;2 } 1 2 3 4 5 6 1. Inicialização do objeto myCar da classe Carro. 2. Atribuição do valor “Ferrari” ao atributo marca do objeto myCar. 3. Atribuição do valor “Portofino” ao atributo modelo do objeto myCar. 4. Atribuição do valor “Gasolina” ao atributo combustivel do objeto myCar. 5. Atribuição do valor “2019” ao atributo ano do objeto myCar. 6. Atribuição do valor “2” ao atributo qtdPortas do objeto myCar. Figura 23 - Classes e objetos Fonte: SENAI DR PR, 2019. 4.3 Estrutura de uma classe Para exemplificar, iremos exibir em um novo projeto, adicionando a classe SuperHeroi. class SuperHeroi { public string nomeHeroi; public string nomeReal; public void falaHeroi ( ) { Console.WriteLine( + .nomeHeroi);“Eu sou o ” this } } 1 referência 65 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT O retângulo em azul indica o nome da classe, neste caso a classe chama-se SuperHeroi. O retângulo vermelho na imagem indica os atributos da classe SuperHeroi, são estas: nomeHeroi, nomeReal. A marcação em verde indica um método da nossa classe, chamado falaHeroi(), este método irá retornar a frase: “Eu sou o” seguido do valor do atributo nomeHeroi. A utilização da palavra-chave this, indica uma referência da instância atual da classe em que se encontra, neste caso está referenciando o atributo nomeHeroi, fora do método. Voltando para a classe principal, adicionaremos o seguinte código: class Program { static void stringMain( [ ] args) { SuperHeroi SuperHeroiironMan = ( );new ironMan.nomeHeroi = ;”Homem de Ferro“ ironMan.nomeReal = ;”Tony Stark“ ironMan. ( );falaHeroi } } 0 referência 1 2 3 4 1. É realizado a instanciação de um objeto SuperHeroi, este objeto se chama ironMan. 2. Atribuição do valor “Homem de Ferro” ao nosso atributo nomeHeroi do objeto ironMan. 3. Atribuição do valor “Tony Stark” ao nosso atributo nomeReal do objeto ironMan. 4. Execução do método falaHeroi pelo objeto ironMan. _ xPrompt de Comandoc:\. Eu sou o Homem de Ferro _ Iremos utilizar novamente o exemplo de carros para exemplificar este tópico: 66 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT class Carro { public string marca; public string modelo; public bool falseligado = ; public int velocidade = ;0 public void LigarVeiculo( ) { } public void DesligarVeiculo( ) { } public void Ve carVelocidade( ) { } public void Ve carStatus( ) { } public void int aceleracaoAcelerar( ) { } public void int frenagemFrenar( ) { } } 1 referência 1 referência 3 referências 2 referências 2 referências 2 referências 1 2 3 4 5 6 7 8 1. Classe Carro. 2. Atributos da classe Carro, sendo estes: marca, modelo, ligado e velocidade. 3. Método LigarVeículo(), sem retorno e sem parâmetros. 4. Método DesligarVeículo(), sem retorno e sem parâmetros. 5. Método VerificarVelocidade(), sem retorno e sem parâmetros. 6. Método VerificarStatus(), sem retorno e sem parâmetros. 7. Método Acelerar(), sem retorno e com um parâmetro do tipo inteiro chamado aceleracao. 8. Método Frenar(), sem retorno e com um parâmetro do tipo inteiro chamado frenagem. O método LigarVeiculo() foi escrito da seguinte forma: public void LigarVeiculo( ) { if(ligado == )true { thisConsole. ( + .modelo + );WriteLine ”O veículo “ ” já encontra-se ligado” } else { ligado = ;true Console. ( + .modelo + );WriteLine ”O veículo “ “ foi ligado”this } } 67 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT É verificado se o veículo já está ligado, caso não esteja, o atributo ligado receberá o valor true. Caso o veículo já esteja ligado, é exibida uma mensagem que já se encontra ligado. O método DesligarVeículo() é bem parecido com o método LigarVeículo(). public void DesligarVeiculo( ) { falseif(ligado == ) { . thisConsole WriteLine( + .modelo + );”O veículo “ ” já encontra-se ligado” } else { ligado = ;false .Console WriteLine( + .modelo + );”O veículo “ “ foi desligado”this } } Porém, ao invés de verificar se o veículo se encontra ligado, irá verificar se o veículo se encontra desligado. VerificarVelocidade() possui a responsabilidade de exibir ao usuário a velocidade atual do objeto carro. public void Ve carVelocidade( ) { this thisConsole. ( + .modelo + + .velocidade. ( ) + );WriteLine ToString”O veículo ” “ está em uma velocidade de “ “ km/h” } O método VerificarStatus() irá exibir na tela se o carro está ligado ou desligado. public void Veri�carStatus( ) { trueif(ligado == ) { thisConsole. ( + .modelo + );WriteLine ”O veículo “ ” está ligado” } else { .Console WriteLine( + .modelo + );”O veículo “ “ está desligado”this } } Os métodos Acelerar() e Frenar() foram implementados de formas bem semelhantes, ambos necessitam do envio de um valor inteiro como parâmetro. public void int aceleracaoAcelerar ( ) { this aceleracaoConsole. ( + .marca + + . ( ) + );WriteLine ToString”O veículo “ ” acelerou” ” km/h“ velociade = velocidade + aceleracao; } } public void int frenagemFrenar ( ) { this frenagemConsole. ( + .marca + + . ( ) + );WriteLine ToString”O veículo “ ” frenou” ” km/h“ velociade = velocidade - ;frenagem } 2 referências É verificado se o veículo se encontra ligado para executar a ação de aceleração. 68 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT A segunda linha do método Acelerar poderia ser substituída por velocidade += aceleracao; é uma forma de simplificar a operação, enquanto a segunda linha do método frenar poderia ser simplificada por velocidade -= frenagem; Na classe principal do programa, foi inserido o seguinte código: static void string argsMain( [ ] ) { ferrari newCarro Carro= ( ); ford newCarro Carro= ( ); ferrari.marca = ;“Ferrari” ferrari.modelo = ;“F430” ford.marca = ;“Ford” ford.modelo = ;“Mustang GT” 1 2 3 4 5 6 1. Instanciação do primeiro objeto da classe Carro, chamado ferrari. 2. Instanciação do segundo objeto da classe Carro, chamado ford. 3. Atribuição do valor “Ferrari” ao atributo marca do objeto ferrari. 4. Atribuição do valor “f430” ao atributo modelo do objeto ferrari. 5. Atribuição do valor “Ford” ao atributo marca do objeto ford. 6. Atribuição do valor “Mustang GT” ao atributo modelo do objeto ford. Carro Carroferrari new= ( ); Carro Carroford new= ( ); ferrari.marca = ;“Ferrari” ferrari.modelo = ;“F430” ford.marca = ;“Ford” ford.modelo = ;“Mustang GT” ferrari. ( );LigarVeiculo ford. ( );Ve carStatus ferrari. ( );Ve carStatus ferrari. (60);Acelerar ferrari. ( );Ve carVelocidade ferrari. (20);Frenar ferrari. ( );Ve carVelocidade Console. ( );Read 1 2 3 4 5 6 7 1. Chamada do método LigarVeiculo pelo objeto ferrari. 2. Chamada do método VerificarStatus pelo objeto ford. 3. Chamada do método VerificarStatus pelo objeto ferrari. 4. Chamada do método Acelerar pelo objeto ferrari, enviando como parâmetro o valor 60. 69 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 5. Chamada do método VerificarVelocidade pelo objeto ferrari. 6. Chamada do método Frenar pelo objeto ferrari, enviando como parâmetro o valor 20. 7. Chamada do método VerificarVelocidade pelo objeto ferrari. Nas primeiras linhas foram realizadas duas instâncias, ferrari e ford. Figura 24 - Objetos sem atributos Fonte: SENAI DR PR, 2019. Em seguida, foram definidos os atributos marca e modelo dos objetos ferrari e ford. Vale lembrar que cada objeto possui seus atributos e seusvalores. Figura 25 - Objetos com atributos definidos Fonte: ADAPTADO DE SHUTTERSTOCK, 2019. Após a definição dos atributos, está sendo executado o método LigarVeículo() para o objeto ferrari e na linha seguinte, chamando o método VerificarStatus do objeto ford. Durante a execução, poderemos perceber que o ford encontra-se desligado. Após isso, o mesmo método é chamado, porém pelo objeto ferrari. Então é realizada algumas chamadas de aceleração, verificação de velocidade e frenagem. A execução do programa no estado em que foi codificado até aqui apresenta os seguintes resultados: 70 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT _ xPrompt de Comandoc:\. O veículo F430 foi ligado O veículo Mustang GT está desligado O veículo F430 está ligado O veículo Ferrari acelerou 60 km/h O veículo F430 está em velocidade de 60 km/h O veículo Ferrari frenou 20 km/h O veículo F430 está em velocidade de 40 km/h Inserindo alguns métodos em nosso código. ferrari. ( );LigarVeiculo ford. ( );Ve carStatus ferrari. ( );Ve carStatus ferrari. (60);Acelerar ferrari. ( ); Ve carVelocidade ferrari. (20);Frenar ferrari. ( );Ve carVelocidade ford. (80);Acelerar ford. ( );Ve carVelocidade ferrari. (40);Frenar ferrari. ( );DesligarVeiculo Console. ( );Read Teremos os seguintes resultados: _ xPrompt de Comandoc:\. O veículo F430 foi ligado O veículo Mustang GT está desligado O veículo F430 está ligado O veículo Ferrari acelerou 60 km/h O veículo F430 está em velocidade de 60 km/h O veículo Ferrari frenou 20 km/h O veículo F430 está em velocidade de 40 km/h O veículo Ford acelerou 80 km/h O veículo Mustang GT está em velocidade de 80 km/h O veículo Ferrari frenou 40 km/h O veículo F430 foi desligado Nos exemplos citados, podemos observar que a execução irá variar conforme valores dos atributos dos objetos chamados, pois cada objeto possui seus próprios valores. 4.4 Modificadores de acesso Os modificadores de acesso são responsáveis por definir as permissões de acesso de métodos e atributos. Os 3 principais tipos de modificadores de acesso são: Public: Permite que os membros da classe (métodos e atributos) possam ser acessados e modificados por qualquer entidade que faça uso desta classe. 71 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Private: Não permite que nenhuma outra classe acesse, nem mesmo as classes que herdam desta. Faz com que o atributo/método só seja acessado pela classe em que se encontra, isso torna o acesso reservado a parte interna da classe. Protected: Torna acessível às classes que herdam e na classe em que se encontra. TROELSEN, 2009, p 147. “Ao trabalhar com encapsulamento, sempre deve levar em conta quais aspectos de um tipo são visíveis para diversas partes de sua aplicação. Especificamente, tipos (classes, interfaces, estruturas, enumerações, delegates) e seus membros (propriedades, métodos, construtores, campos e assim por diante) são sempre definidos através de uma palavra- chave específica para controlar quão “visível” o item será para outras partes da aplicação [...]”. SANTOS, 2014, p 396: “O encapsulamento é uma das características mais importantes da Programação Orientada a Objetos. É ele quem possibilita a aplicação de diferentes níveis de visibilidade para os membros de uma classe. Esta visibilidade determina se é permitido o acesso a um membro de uma classe a partir de outra classe ou se o acesso a ele é restrito à própria classe onde se encontra.”. Para demonstrar o funcionamento dos modificadores de acesso, foi criada três classes: a ClasseMae, onde ficará os atributos que serão herdados; a ClasseFilha que herdará da ClasseMae; e por último a ClasseExterna, que irá instanciar um objeto da ClasseMae. class ClasseMae { public int valorPublico; private int valorPrivado; protected int valorProtegido; } 1 2 3 1. Atributo público. 2. Atributo privado. 3. Atributo protegido. A utilização dos atributos de uma hierarquia maior. class ClasseFilha ClasseMae: { ( ) {public void ve carHeranca this. } } valorProtegido * valorPublico > 0 references 0 references 1 2 72 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 1. Subclasse. 2. Superclasse. Os únicos atributos que a ClasseFilha herdará são os públicos e protegidos. Para utilizar os atributos de uma classe sem herdar a mesma, devemos instanciá-la, ou seja, criar um objeto do tipo da classe. class ClasseExterna { ( )public void ve cadores { newClasseMae ClasseMaemae = ( ); mae. } } valorPublico > 0 references Ao utilizar a instância da classe, podemos verificar que os únicos valores que são possíveis de serem recuperados são os que possuem modificadores públicos. É muito importante na hora da criação dos atributos, saber qual modificador utilizar. Deve-se levar em consideração quais classes deverão e poderão utilizar e esconder o restante, pois infere-se não ser necessário para outras classes. 4.5 Escopo e variável O termo escopo se dá pela definição de existência de uma variável e podemos possuir variáveis com o escopo global e com escopo local. Chamamos as variáveis de escopo global dentro de uma classe quando todas os métodos podem acessá-la. Geralmente, estas variáveis se encontram no cabeçalho da classe. As variáveis de escopo local não podem ser acessadas fora do método ou bloco que se encontra, são declaradas nestes blocos e não podem ser acessados fora dali. São chamadas de variáveis auxiliares e existem apenas durante a execução do método ou bloco em que foi definida. Escopo global: class Carro { public string valor; public void Escopo( ) { //// variável valor pode ser acessada aqui. } public void Ve carEscopo( ) { // variável valor pode ser acessada aqui. } } 0 references 0 references 73 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Escopo local: class Carro { public void Escopo( ) { string valor; // variável valor só existe aqui. } public void Ve carEscopo( ) { // variável valor não pode ser acessada aqui. } } 0 references 0 references 4.6 Tratamento de exceções Tratar exceções é fundamental para que não tenha uma parada na execução do software, podendo executar comandos que tentem contornar o problema enfrentado. O tratamento de exceções é extremamente recomendado, além de ser uma boa prática. Exceções podem ser geradas durante a execução de um software por diversos motivos, seja por manipulação incorreta de variáveis, erros de hardware ou por uma simples divisão por zero. As exceções geradas durante a execução podem parar o software. Com o bloco Try-Catch, o software pode tentar se recuperar ou mostrar a exceção gerada, não parando a execução. try { // ... } ( e )catch Exception { Console.WriteLine( + e);“ ‘Exceção:“ } A execução é realizada no bloco Try. Caso seja gerado alguma exceção, o bloco Catch é executado, não interrompendo o funcionamento do software. int numero = .ToInt32( );Convert 0 int resultado = / numero;100 O código acima gera uma exceção, parando a execução. Colocando o código que iria gerar um erro em um bloco Try, temos um software que não iria ter a parada de execução. 74 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT try { // ... Convertint numero = .ToInt32( );0 int resultado = / numero;100 } catch( e )Exception { Console.WriteLine( + e);“ ‘Exceção:“ } Console.Read( ); Assim que o código acima executa o comando de divisão por zero, o software gera a exceção executando o bloco catch, exibindo a exceção gerada. Porém, não finaliza o processo. 4.7 Elementos estáticos Em alguns momentos, não faz sentido exigir a instância de uma classe para utilizar algumas funcionalidades simples que não necessitam de um objeto. Para isso, existe o modificador static. Com ele não é necessário instanciar um objeto para utilizar os métodos ou atributos. 4.7.1 CLASSE ESTÁTICA A classe estática em si é idênticaa uma classe não estática, a única diferença entre as duas é que a classe com o atributo STATIC não pode ser instanciada. Caso tente realizar a criação de um objeto de uma classe estática, a IDE irá retornar uma mensagem: “Não é possível criar a instância da classe estática” static class Estoque { } Classes estáticas possuem apenas membros estáticos, podendo ser utilizadas quando não existe a dependência de uma identidade do objeto. Este tipo de classe não pode herdar de outra classe, pois são consideradas seladas, isto indica que restringe características de herança. 4.7.2 MÉTODO ESTÁTICO O método estático ou método utilitário não necessita de um objeto instanciado para ser utilizado. 75 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT static class Estoque { public static void AdicionarProduto( produto)String { //... } } Para utilizar algum método estático é necessário apenas usar o nome da classe, seguido por um ponto e o nome do atributo/método. class Program { static void stringMain( [ ] args) { Estoque.AdicionarProduto( );“Papel A4" } } 4.7.3 ATRIBUTO ESTÁTICO O valor do atributo static é compartilhado entre todos os objetos da classe, caso seja alterado em qualquer objeto, todos os outros sofrerão a mesma mudança. Também não é necessária a instância de um objeto para utilização de atributos estáticos. Métodos e atributos estáticos podem ser encontrados em classes não estáticas, então não é necessário criar uma classe estática para utilizar métodos e atributos com este modificador. class Estoque { public static void AdicionarProduto( produto)String { //... } } 0 references 4.8 Classe abstrata Classes abstratas são utilizadas como modelos para classes concretas e a sua utilização se dá por herança, servindo de classe mãe. Não pode existir instâncias de classes abstratas, já que as mesmas só podem ser utilizadas como superclasses. Essa classe, ainda permite a criação de métodos com corpo, devendo possuir pelo menos um método abstrato (não possuir implementação, apenas a assinatura do método). 76 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT abstract class Moto { public abstract void DesligarMotor( ); public void LigarMotor( ) { } } Não é possível instanciar um objeto de uma classe abstrata. Caso tente criar um objeto a partir deste tipo de classe, teremos a seguinte mensagem: Moto Motomoto = ( );new class ConsoleApp7.Moto Não é possível criar uma instância da classe abstract ou interface “Moto” 4.9 Interface Interfaces auxiliam na construção de classes. Os métodos abstratos de uma interface não possuem corpo, apenas a declaração do mesmo com o retorno, nome e parâmetros. A definição das funcionalidades de cada método é de responsabilidade das classes que implementam as interfaces. Interface é uma entidade, uma forma de contrato com as classes que irão implementar, pois garante que os métodos sejam criados nessas classes. Existe uma obrigatoriedade que todos os novos automóveis devem possuir como o airbag e freio ABS. Este contrato com as montadoras faz com que só possa vender novos veículos, caso eles sigam o contrato. Assim também são as interfaces, pois permitem que as classes que irão implementar, sigam o contrato. A utilização das interfaces se dá por implementação e não por herança, como vimos nas classes abstratas. Algumas linguagens permitem a herança múltipla, já outras linguagens não. Para estas linguagens, a implementação de várias interfaces pode auxiliar neste quesito. Todos os métodos de uma interface são abstratos e quando uma classe implementa a interface, é necessário que sobrescreva todos estes métodos. interface ICarro { void Ligar( ); bool Ve carStatusMotor( );{ string Placa( ); } 77 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Geralmente, interfaces possuem o prefixo I antes do nome, para indicar que se trata de uma interface. Não é possível instanciar um objeto de uma interface, caso tente realizar a criação de um objeto a partir de uma interface, receberá uma mensagem da seguinte forma: ICarro moto = ( );new ICarro interface ConsoleApp7.ICarro Não é possível criar uma instância da classe abstract ou interface “ICarro” 4.10 Construtor O Construtor é executado na criação do objeto com o uso da palavra- chave new. Geralmente é utilizado para definir os valores padrões dos atributos de um objeto e para verificações. O método construtor não possui nenhum retorno. Escrever os métodos construtores permitem a execução de alguns comandos assim que o objeto é criado, podendo ser utilizado para definir valores iniciais e chamar outros métodos. Os métodos construtores são ótimos quando existe a necessidade de solicitar valores ao criar um objeto, fazendo com que o mesmo só realmente seja criado, caso as informações sejam enviadas como parâmetros. “Os construtores são métodos especiais que são invocados para reservar espaço na memória do computador a ser ocupado por um novo objeto. Além de exercerem um papel essencial no processo de instanciação de classes, os construtores também podem ser utilizados para inicializar os atributos com valores predefinidos ou com valores informados.” (SANTOS, 2014, p 356) Métodos construtores são métodos com o mesmo nome da classe, permitindo que seja especificado os parâmetros necessários para criação de objetos da classe. public Calculadora( ) { } public int int stringCalculadora ( a, b, tipo) { } 79 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 5 CONEXÃO COM BANCO DE DADOS A internet está presente em nosso cotidiano, em nosso mundo. O tempo todo fotos estão sendo postadas em redes sociais, aplicativos de conversas registram uma grande quantidade de textos. Os sites e blogs geram notícias, tutoriais, entre outros. Todas estas informações ficam guardadas e qualquer pessoa que tenha permissão pode visualizá-las. Quando colocamos algo na internet, isto fica guardado em um lugar que é chamado de banco de dados, imprescindível para nosso mundo atualmente e é o responsável por armazenar e organizar todo tipo de informação. São muitos os softwares que necessitam guardar dados ou se conectar em uma base para obtê-los. A persistência de dados de forma organizada é o foco de todos os bancos de dados. Em outras palavras, significa que as informações guardadas não serão perdidas, de modo que podem ser recuperadas posteriormente. Os bancos de dados são muito utilizados para persistir os dados, ou seja, quando estamos acessando um site e temos um login e senha, estes estão guardados em um banco de dados. Quando estamos subindo fotos e vídeos na nuvem, estes também são armazenados em um banco de dados. O saldo do banco que podemos visualizar no computador ou smartphone, também é registrado nesse local. Caso esteja em um servidor remoto, podemos acessar esses diversos tipos de informação em qualquer lugar, por qualquer dispositivo, sempre que estiver disponível. 80 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Figura 26 - CRUD Fonte: SENAI DR PR, 2019. A persistência de dados se baseia na palavra CRUD, correspondente às palavras: Create (Criar): Momento em que são cadastradas novas tuplas no banco de dados. Read (Ler): São realizadas as consultas das informações existentes em um banco de dados. Update (Atualizar): Este termo se refere à atualização de informações das tuplas cadastradas no banco de dados. Delete (Deletar): Uma ou mais tuplas são deletadas das tabelas. Estas 4 principais operações norteiam a persistência de dados, mantendo os dados em conformidade com a regra de negócio do utilizador. Existem duas grandes categorias para bancos de dados, as relacionais e as não-relacionais. Essas, veremos nos subcapítulos seguintes. 5.1 Relacionais Os relacionais possuem estruturas definidas para os conjuntosde dados, formado por tabelas e que por sua vez contém colunas e armazenam dados em formato de registros (linhas). Um dos pontos fortes dos bancos relacionais é a padronização dos dados. Alguns exemplos de relacionais são: Oracle, PostgreSQL, SQLite e MySql. 81 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Figura 27 - Banco de dados relacionais Fonte: DATA SCIENCE ACADEMY, 2019 5.2 Não-relacionais Os não-relacionais se baseiam em documentos, não sendo necessário definir a estrutura de tabelas, cada arquivo pode possuir diferentes tipos de dados, o NOSQL (banco de dados não relacional) permite uma grande escalabilidade. Alguns exemplos de não relacionais são: MongoDB, CouchDB, Cassandra e Riak. Figura 28 - Banco de dados não relacionais Fonte: ADAPATADO DE DATAWIX, 2019. ADO.NET O ADO.NET é uma tecnologia exclusiva para .NET utilizada para acesso e manipulação de dados que suporta provedores de dados para comunicação com um gerenciador de banco de dados, como por exemplo, SQL Server, Oracle, MySQL. O ADO permite a realização completa da conexão e nos entrega as ferramentas para a sua utilização, como por exemplo, as inserções, deleções, seleções e atualizações de dados. Destaca-se por sua simples utilização. 82 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Figura 29 - ADO.NET Fonte: SENAI DR PR, 2019. Os provedores ADO.NET possuem alguns principais objetos, sendo eles: Connection: O objeto connection é responsável por realizar a conexão e desconexão de um repositório de dados, usando informações como provedor da database, caminho, usuário e em alguns casos senha. Todas estas informações são guardadas em uma string de conexão. Cada provedor de banco de dados possui um objeto connection específico, como o SQLConnection que é utilizado para se conectar com o SQL Server. Para utilizar a conexão com o banco de dados SQL Server é necessário utilizar um namespace chamado System.Data.SqlClient, utilizando-o no cabeçalho. using System.Data.SqlClient; Criar um método para abrir a conexão. public void Conectar( ) { } 83 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT public void Conectar( ) { var newsqlconnectstring = ( );SqlConnectionStringBuilder sqlconnectstring.IntegratedSecuritu = ;true sqlconnectstring.InitialCatalog = ;”bank“ sqlconnectstring.DataSource = ;”localhost“ sqlconnectstring.UserID = ;”sa“ sqlconnectstring.Password = ;”123" Após a criação da classe, o objeto SqlConnectionStringBuilder é criado e permitirá que adicione vários parâmetros como o nome da base de dados, onde se encontra o servidor, o id do usuário do banco de dados e a senha de acesso. Com estas informações o objeto irá retornar a string de conexão. string connectionString = sqlconnectstring. ( );ToString Após a criação da string de conexão, temos a criação do objeto SqlConnection e a utilização do método Open, que se encontra na classe. SqlConnection SqlConnectionnewcnn = (connectionString); try { cnn. ( );Open Console.WriteLine( );“Conexão Aberta! ” } catch (Exception )ex { Console.WriteLine( );“Não foi possível conectar! ” } Para fechar a conexão, é necessário utilizar o método Close, que também se encontra disponível para os objetos do tipo SqlConnection. Command: O comando command é responsável por executar comandos no banco de dados como SELECT, INSERT, UPDATE e DELETE. É necessário utilizar o SqlDataReader, caso precise como retorno um conjunto de dados. Para um insert, pode-se utilizar o ExecuteNonQuery que não terá retorno. public void Deletar( ) { SqlCommand SqlCommandsqlComm = ( , cnn);new “DELETE FROM Categorias WHERE id = 1" sqlComm. ( );ExecuteNonQuery } 41 2 3 5 1. Nome do Método. 2. Criação do objeto do tipo SqlCommand. 3. Query para deleção de um registro do banco de dados. 4. Objeto de conexão. 5. Execução da query, podendo variar também para Execute Reader caso esteja realizando um select e ExecuteScalar para caso queira retornar apenas um único valor de consulta. 84 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT DataTable: DataTable é um conjunto de linhas e colunas que por sua vez armazenam informações de qualquer tipo de fonte de dados. DataTable DataTabletable1 = ( );new “professores“ table1.Columns. ( );Add “nome“ table1.Columns. ( );Add “id“ table1.Rows. ( , 1);Add “Claudio“ table1.Rows. ( , 2);Add “Cesar“ DataSet: O DataSet trabalha na parte desconectada, tendo suas características como um cache com cópia dos dados, ela guarda as informações para manipulação, seja inserção, deleção ou atualização dos dados. O DataSet não é conectado com o banco de dados, os dados são mantidos por meio de XML. DataTable DataTabletable1 = ( );new “professores“ table1.Columns. ( );Add “nome“ table1.Columns. ( );Add “id“ table1.Rows. ( , 1);Add “Claudio“ table1.Rows. ( , 2);Add “Cesar“ DataTable DataTabletable2 = ( );new “disciplinas“ table2.Columns. ( );Add “id“ table2.Columns. ( );Add “nome_disciplina“ table2.Rows. (1, );Add “Sistemas Operacionais“ table2.Rows. (2, );Add “Back-End“ DataSet DataSetset = ( );new “Escola“ set.Tables. (table1);Add set.Tables. (table2);Add DataAdapter: DataAdapter faz a equivalência de dados entre a linguagem e o repositório de dados, apoiando as operações de inserção, atualização, deleção e seleção dos dados no banco. 85 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT string queryString = “SELECT id, nome FROM dbo.professores!“ SqlDataAdapter SqlDataAdapteradapter = (queryString, cnn);new DataSet DataSetprofessores = ( );new adapter. (professores, );Fill ”Professores“ DataReader: Funcionando como um ponteiro de forma eficiente, o DataReader retorna um fluxo de dados somente-para-frente e somente-leitura do lado do servidor. SqlCommand SqlCommandcommand = ( , cnn);new “SELECT * from professores;“ SqlDataReader reader = command.ExecuteReader( ); if ( .HasRows)reader { while ( . ( ))reader Read { //... para cada registro } } DataSource: Representa a localização da base de dados do objeto de conexão. comboVeiculos.DataSource = table; comboVeiculos.Databind(); BIBLIOTECAS O namespace System.Data possui diversas classes para conexão e manipulação dos dados ADO, dentre elas podemos ressaltar a System.Data.SqlClient, utilizada para métodos como SqlConnection, SqlCommand e SqlDataReader. Além da System.Data.SqlClient também temos System.Data.OleDb, System.Data.Odbc e System.Data.Commom. Para realizar a conexão com alguns outros bancos de dados, como por exemplo o MySql, é necessário a instalação de uma dll que permite a integração. Figura 30 - Namespace System.Data Fonte: SENAI DR PR, 2019. 86 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT ORM ORM significa OBJECT RELATIONAL MAPPING ou Objeto de Mapeamento Relacional, tem por objetivo facilitar o acesso ao banco e a sua manipulação, simplificando operações básicas e repetitivas. Figura 31 - ORM Fonte: SENAI DR PR, 2019. Code first VS DB First Dentre as formas de se iniciar um projeto utilizando os ORMs, podemos destacas 3: code first; database first; e model first. A escolha do modo irá depender do contexto aplicado no projeto. • O Code First é uma técnica que permite que seja realizada a codificação das classes por primeiro e o banco de dados será gerado a partir delas. • O Database First é a técnica que foca na criação das tabelas do banco de dados em primeiro lugar, as entidades de modelo de dados são criadas usando a database como base. • O Model First se baseia em uma modelagem visual através do arquivo .EDMX, não sendo necessário entender conceitos específicos da estrutura de banco de dados nem mesmo os conceitos específicos do framework. O mapeamento que o ORM cria entre o banco de dados relacional e as classes do código facilita a interação. A “ponte” que é criada reduz a necessidadede escrever queries para o banco de dados. O mapeamento criado pelo framework facilita a criação do CRUD (Create, Read, Update e Delete) e as operações básicas são simplificadas, visando o ganho de tempo e produtividade. Dentre as vantagens, podem ser citadas: • Incremento de produtividade e facilidade; • Isolamento do banco de dados; • Interface única entre os bancos de dados; • Ferramenta versátil; 87 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT • Modelagem antes do banco de dados. A facilidade que o ORM apresenta em questão de produtividade é visível pelo tempo e facilidade, além de isolar a natureza real dos relacionamentos de banco de dados, também cria uma interface única para os diferentes tipos de bancos de dados. Como nenhuma ferramenta possui apenas vantagens, os ORMS também possuem algumas desvantagens: • Funcionalidades genéricas; • Performance menor; • Dificuldade de escrita de queries complexas. A realização de consultas complexas para os ORMs é tarefa difícil, além da performance ser menor e possuir apenas funcionalidades genéricas. Como os ORMs trabalham com diferentes tipos de bancos, são focados nas operações mais comuns e genéricas. 89 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 6 TÉCNICAS DE PROGRAMAÇÃO 6.1 FORMATAÇÃO A formatação da disposição do código é muito importante para que se consiga visualizar facilmente toda a hierarquia de comandos. Também conhecido como identação, consiste em um processo para organizar o código de forma posicionada, fazendo com que tudo que está dentro de um método, ou função de bloco, tenha um espaçamento a mais. Isso faz com que de forma simples e fácil, consigamos saber o que faz parte do quê. private int int intSomar( , ) {a b if( > && > )a b0 0 { return a b+ ; } else { return 0; } } Acima, encontra-se um exemplo de um código sem identação. É complicado de se identificar e saber qual bloco está terminando ou começando. Em poucas linhas, pode não ser tão complicado, porém, arquivos de códigos podem passar de mil linhas facilmente. private int int intSomar( , ) {a b if( > && > )a b0 0 { return a b+ ; } else { return 0; } } 90 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT O mesmo código do exemplo passado, porém desta vez encontra- se identado. Outra boa prática de programação é agrupar códigos que façam sentido estar juntos e separar com um ou dois espaços códigos que não fazem parte do mesmo processo. Sendo assim, mais simples e rápido para identificar até onde vai cada função ou método, o ideal é que pratique este e outros bons hábitos. Código sem espaçamento namespace ConsoleApp12 { class Program { static void stringMain( [ ] args) { } public void int intSomar( a, b) { Console. (a + b);WriteLine } public void int intDividir( a, b) { if(a !=0 && b !=0) { Console. (a / b);WriteLine } else { Console. ( );WriteLine “Não é possível“ } } } } Código com espaçamento namespace ConsoleApp12 { class Program { static void stringMain( [ ] args) { } public void int intSomar( a, b) { Console. (a + b);WriteLine } public void int intDividir( a, b) { if(a !=0 && b !=0) { Console. (a / b);WriteLine } else { Console. ( );WriteLine “Não é possível“ } } } } 91 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 6.2 DOCUMENTAÇÃO DE CÓDIGO A documentação de código é constituída de várias partes e uma delas é o comentário de código. Essa é uma prática bem conhecida, comum e muito valiosa, pois é necessário que todo bom programador comente códigos e estes comentários devem ser explicativos e responder todas as possíveis perguntas que a pessoa que irá dar manutenção ao código possa ter. Nesse sentido, deve-se evitar comentários óbvios pelo programador, como por exemplo: “Esta linha está realizando uma quebra de linha”. Os comentários precisam conter explicações importantes como “Está requisitando o valor do salário e impostos, e retornando o valor liquido em dólar”. Os comentários podem ser até um pouco mais simples, mas devem auxiliar os desenvolvedores como “Aqui está finalizando o FOR para listagem de usuários”. Estes apontamentos, embora sejam simples, possuem uma capacidade de auxílio eficiente quando combinado à identação. //Isto é um comentário de uma linha /* Isto é um comentário de bloco Abrange mais de uma linha ao mesmo tempo */ Podemos utilizar em alguns softwares como o chamado Summary. Este componente gera o esqueleto do XML da documentação para o elemento que queremos documentar. Este sumário é importante para que possamos identificar o que aquela classe faz. A diferença desse para o simples comentário é que no Visual Studio 2017, por exemplo, ele pode mostrar o que você digitou quando for utilizar em outra classe. Ele mostra em um pequeno bloco abaixo, sendo bem útil para desenvolvimento de código em equipes. Na ferramenta Visual Studio 2019, ao pressionarmos três vezes o símbolo de barra “///” acima de um método, automaticamente aparece o summary: 92 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT ///<summary> /// ///</summary> /// <param = ></param>name ” ”x /// <param = ></param>name ” ”y public void int x int yCalcular( , ) { } } 0 references Então podemos preencher com informações que iremos utilizar como base depois. ///<summary> ///Iremos calcular X e Y ///</summary> /// <param = >Primeiro valor</param>name ” ”x /// <param = >Segundo valor</param>name ” ”y public void int x int yCalcular( , ) { } 0 references O summary permite que façamos a leitura quando vamos utilizar o método: Calc| Calcular void int intProgram.Calcular( , )x y Iremos calcular X e Y Perceba que a frase que aparece ao passar o mouse no método é a mesma que escrevemos entre as tags summary. É interessante utilizar o summary, principalmente quando existem várias funções que outras pessoas na sua equipe irão utilizar. 6.3 Reutilização de código A reutilização de código é uma prática bem comum no mundo do desenvolvimento de software, já que tem por motivação o aproveitamento de soluções, módulos e ferramentas já criadas. Isso aumenta a produtividade e a qualidade do código com as partes já desenvolvidas anteriormente. 93 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Um dos pontos positivos na prática de reutilização de código é que já foi escrito, testado e utilizado em outro sistema, então isso garante uma utilização de tempo muito boa já que não será necessário escrever a mesma solução do zero novamente. Entretanto, faz-se necessário fazer testes destes códigos, arquitetura ou módulos que estão sendo utilizados novamente. Deve- se verificar se o código se encaixa com o novo software e se adapta-se à situação e as regras de negócio. Caso a resposta seja não, é importante a verificar e alterar, caso necessário. Figura 32 - Looping de reaproveitamento Fonte: SENAI DR PR, 2019. A principal razão de reutilizar códigos está relacionada ao nível de qualidade e produtividade. Para reutilizar um componente é importante seguir alguns passos que serão descritos a seguir. Primeiramente, é necessário realizar a pesquisa dos artefatos que satisfaçam o problema em questão. Por isso, é importante fazer um refinamento dos mais aceitáveis e, em seguida, verificar a importância da realização de alterações para que seja possível adaptar para o problema a ser resolvido, pois nem sempre o componente que está sendo reutilizado irá satisfazer totalmente o novo problema. Algumas alterações podem ser necessárias para que funcione de acordo. Quando se trata de reuso de software, em alguns casos, passa do código e pode também reusar ideias e especificações. Os frameworks hoje são ótimos exemplos de reuso, pois alguns permitem que você crie pequenos módulos e os reutilize de vários formas. Com isso, você pode criarum mais genérico e alterar conforme sua necessidade. Isso também permite que migre de forma mais simples para outros sistemas, dentre frameworks e bibliotecas, hoje se destacam o React, React Native, Angular, Laravel, dentre outros. 94 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Além da reutilização de componentes realizados por frameworks e bibliotecas, também existe a reutilização de classes, estas podem ser escritas de uma forma mais genérica a primeiro momento, não colocando tantas regras de negócio específico para o projeto. Embora isso gaste um pouco mais tempo a primeiro instante e nos primeiros projetos, o tempo é recompensado para todos os outros que forem utilizar estas classes. O reuso de código pode ser por meio do mesmo domínio e também de domínios diferentes. Para facilitar a reutilização de componentes, é importante documentar e, por vezes, ter um investimento e comprometimento um pouco mais alto na parte da gestão, já pensando em reutilizar os componentes criados. Esses componentes devem ser pensados um pouco mais na hora da criação, sendo assim, demanda um pouco mais de tempo na criação, porém facilita muito na hora de reutilizar estes códigos. 6.4 Técnicas de otimização de código A otimização de código está relacionada a como é codificado o software. Em alguns casos, podem existir algumas limitações de memória ou de processamento, como por exemplo, os embarcados. Utilizar métodos estáticos quando ele é totalmente independente da classe em que se encontra é uma boa forma de se otimizar o código, pois ele mostra ao compilador que só irá ficar em memória quando estiver sendo executado e não quando a classe está sendo instanciada, como acontece de costume. Além disso, não é necessário instanciar a classe, isso significa que não será necessário alocar memória de atributos que não serão utilizados, poupando recursos do sistema. É importante saber quando o método pode ser trocado para estático, pois nem sempre é o correto. Evitar declarar variáveis dentro de laços de repetição é extremamente importante. Isso pode ser facilmente contornado criando a variável fora declarando como null e a utilizando dentro do laço, pois caso declare-a dentro, fará com que cada laço declare uma nova (pode depender da linguagem). Então, a otimização pode ser realizada de forma bem simples. 95 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Criar Variáveis dentro de laços de repetição Manter os códigos identados Nomear as variáveis e funções de acordo com seu papel Entender as funções possíveis e suas utilizações Declarar variáveis dentro de laços de repetição cientes Uma ótima forma de otimizar códigos é utilizar os já testados e otimizados que façam o que você precisa. Isso porque recriar todo o código, provavelmente, tornará a ação a ser executada mais lenta ou mais pesada para o interpretador/compilador. Para ajudar, existem diversos códigos com operações simples testadas na linguagem. Entender como a linguagem funciona e o que é melhor para cada situação também irá colaborar muito no desempenho do sistema, visto que cada linguagem possui suas peculiaridades. É importante entender quais são elas e os métodos disponíveis para cada situação, pois isso faz com que o máximo da linguagem seja aproveitado. Em alguns momentos, alguns métodos passam a ser obsoletos por aparecer outras formas melhores e mais eficazes de realizar o mesmo problema. Um ótimo exemplo são os laços de repetição que podem possuir diferentes desempenhos em mesmos contextos. Vale lembrar que começar o desenvolvimento do programa já pensando nas boas práticas e otimização é melhor que pensar em como corrigir a lentidão. Refazer um trabalho é sempre pior que fazê-lo correto da primeira vez. Diversas linguagens permitem a importação de bibliotecas, que por sua vez são conjuntos de códigos que complementam as ferramentas e métodos que a linguagem possui. Por vezes, estas bibliotecas são extremamente úteis, porém é importante saber como importá-las, e não importá-las sem ter a certeza de que vai utilizá-las. Inclusão de bibliotecas na linguagem C: #include<stdlib.h> #include<stdio.h> #include<math.h> No cenário da WEB é comum se preocupar com o espaço em que os arquivos ocupam, pois o tamanho destes arquivos irão influenciar diretamente na velocidade do carregamento e tráfego de internet do usuário. Algumas linguagens permitem que o código seja reduzido para o carregamento nos dispositivos, estes arquivos minimizados costumam não conter nenhum ENTER. Vale ressaltar que os arquivos desta forma 96 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT são apenas utilizados no ambiente de produção e não no ambiente de desenvolvimento. Para esta técnica de otimização de código, é importante possuir a cópia identada. Figura 33 - Velocidade de carregamento Fonte: SENAI DR PR, 2019. 6.5 Depuração O termo depuração de código é também muito conhecido como debugging. Ocorre quando o desenvolvedor executa o software passo a passo, a procura de erros ou bugs, para corrigi-los. Quando se está executando a depuração de código é possível acompanhar os valores das variáveis, além de permitir que as altere em tempo de execução, além de acompanhar todos os comandos executados. A tarefa de depuração normalmente é acompanhada de um depurador, que é a ferramenta que permite isso. Ela possui diversas funcionalidades especificas para encontrar bugs. static void stringMain( [ ] )args { Console.WriteLine(”Os pontos vermelhos são os pontos de parada”); Console.WriteLine(”O sistema executa de breakpoint para breakpoint ao pressionar F10"); Console.WriteLine(”Assim podemos analisar os eventos, valores e métodos executados”); Console.WriteLine(”Encontrar bugs, para que possamos corrigir”); 11 12 13 14 15 16 17 18 19 0 references Cada círculo à esquerda é um breakpoint, ou ponto de parada, e faz com que o depurador execute o código até encontrar um destes. Quando o depurador faz a parada, é possível continuar a execução. Essas paradas são importantes para verificar os valores atuais e os comportamentos até o momento. Em IDEs, costuma ser simples adicionar breakpoints, normalmente baseia-se em um simples clique com o botão na linha vertical ao lado esquerdo da numeração. Em alguns casos, será necessário clicar com o botão direito para que apareça a opção. 97 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 7 RASTREABILIDADE 7.1 SISTEMAS DE REPOSITÓRIO DE VERSIONAMENTO. Dentre os repositórios conhecidos, destacam-se dois: • Git Hub: O Github é um repositório de versionamento que chegou a marca de 36 milhões de usuários, colaborando em 100 milhões de repositórios em abril de 2019. Com uma interface bem trabalhada, é o mais famoso dos repositórios. • BitBucket: Bitbucket também é um repositório git para times. Mantido atualmente pela Atlassian, possui um conjunto de ferramentas fantásticas para se trabalhar, não ficando para trás do GitHub. O BitBucket, além do git, também possui suporte para Mercurial. 7.2 SOFTWARE DE VERSIONAMENTO E REPOSITÓRIOS É comum, no desenvolvimento de software em equipe, problemas como alguém sobrescrever uma parte do seu código e não encontrar o responsável. Ao sobrescrever alguma variável e a funcionalidade parar de funcionar, sem saber o motivo, começa-se uma jornada em busca da linha de código que está em conflito, gerando retrabalho, dor de cabeça e tempo perdido. As várias versões de um sistema sem um controle por software versionador pode gerar outros problemas, como por exemplo, encontrar a versão exata em que foi implementado ou alterado uma nova funcionalidade. 98 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Existem 3 grandes conhecidos para solucionar os problemas descritos acima,são eles: Subversion, Git e Mercurial. Dentre as 3 ferramentas de controle de versão vamos trabalhar aqui o Git, pois é o mais popular graças ao GitHub. O GitHub é uma plataforma de hospedagem de código para controle de versão com um visual atrativo, simples e fácil de se utilizar. O versionamento de software se faz essencial para qualquer programador hoje em dia. Somado a isso, é importante que o profissional busque se aprimorar conhecendo o funcionamento desta ferramenta. Também vale apresentar alguns detalhes importantes sobre o fluxo de trabalho. Nel,e temos o Working Directory, Index e HEAD. Abaixo segue uma breve definição de cada um: • O chamado Working Directory é o que contém os arquivos vigentes, podendo realizar uma tradução livre para Diretório de Trabalho. Aqui os arquivos alterados não estão em seu repositório. • O Index aqui é uma área temporária. • O HEAD é o que aponta para seu último commit que você fez. • Commit é uma confirmação, cada commit possui algumas informações, como você verá adiante. Figura 34 - Estágios do versionador Fonte: SENAI DR PR, 2019. O git add adiciona os arquivos no fluxo de trabalho Index. Uma vez adicionados estes arquivos, podem ser novos ou não no repositório, o comando add indica quais deles estão sendo preparados para entrar na próxima revisão do repositório. git commit -m "[inserir um comentário]” O git commit é um comando que verá bastante em questão de versionamento de software, o ato de “commitar” é a transferência do seu Index para o seu HEAD. 99 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Este comando cria uma revisão com o comentário que foi inserido no comando, guardando também seu nome, e-mail, data e hora que foi realizado. O git push é utilizado quando queremos empurrar os nossos commits para um repositório como o GitHub. Neste momento é solicitada sua senha. git push -u origin master Para iniciar um repositório local, é necessário utilizar o comando git init, caso não coloque o nome do projeto irá ser criado na raiz, sem criação da pasta, tornando-se opcional o nome. git init [nome do projeto] Conseguimos visualizar um histórico de commits realizados com data, hora, nome e e-mail do usuário que realizou o commit, id único e o comentário dos commits realizados no repositório. Para conseguir estas informações, será utilizado o comando git log. [ ] – [ ]user@parrot ~/ProjetoTechIt $git log commit 43aa97489fc353d7fa8b397fdc5a81623ac6a71f ( )HEAD -> master Author: Robson Barbosa <exemplogithub@gmail.com> Date: Thu Jun 6 13:50:25 2019 -0400 Mudança da porta 8080 para 8081 commit 95ef2cbaa852853d74e16f302c1677ed983c7e6e Author: Robson Barbosa <exemplogithub@gmail.com> Date: Thu Jun 6 13:33:24 2019 -0400 Parrot Terminal File ViewEdit Search Terminal Help Para comparar duas versões diferentes, existe o comando: git diff. git diff [id de um commit]..[id de outro commit] Em alguns momentos pode ser necessário guardar algumas versões dos códigos para que, se em algum momento pare de funcionar ou funcione de forma inesperada, você consiga voltar na versão que ainda estava funcionando ou para que consiga comparar os arquivos. O git vem solucionar este problema de uma forma fácil, sempre que queremos guardar uma versão de algum arquivo, fazemos o que chamamos de commit. Estes commits ficam guardados com as versões, sendo realizados com o comando: git commit. O versionamento também ajuda em questão de comparação de códigos, possuindo comandos específicos para comparar duas versões do mesmo arquivo, mostrando de uma forma visual o que foi retirado, alterado e o que foi adicionado. 100 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Figura 35 - Branchs Fonte: ADAPTADO DE SHUTTERSTOCK, 2019. 7.2.1 UTILIZANDO O GIT DE FORMA LOCAL. É necessário fornecer o nome e e-mail para a configuração do git, os comandos iniciais são: git config --global user.name "[Seu nome]" git config --global user.email "[Seu endereço de e-mail]" [ ] – [ ]user@parrot ~ $git log config - -global user.name ”Robson Barbosa“ [ ] – [ ]user@parrot ~ $git log config - -global user.email ”exemplogithub@gmail.com“ [ ] – [ ]user@parrot ~ $ Parrot Terminal File ViewEdit Search Terminal Help Ps: O símbolo $ é exibido porque neste exemplo o git foi executado por um terminal do Linux. Após configurado isto, podemos criar nosso repositório local utilizando o comando git init, porém precisamos estar na pasta do nosso projeto. 101 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT $git log config - -global user.email ”exemplogithub@gmail.com“ [ ] – [ ]user@parrot ~ $mkdir ProjetoTechIt [ ] – [ ]user@parrot ~ $cd ProjetoTechIt/ [ ] – [ ]user@parrot ~/ProjetoTechIt $git init Initialized empy Git repository in /home/user/ProjetoTechIt/.git/ [ ] – [ ]user@parrot ~/ProjetoTechIt $ [ ] – [ ]user@parrot ~/ProjetoTechIt $git status On branch master No commits yet nothing to commit (create/copy files and use ”git add“ to track) Parrot Terminal File ViewEdit Search Terminal Help Na imagem acima, pode-se identificar mais um comando além do git init, o comando git status, nos indicando que ainda não existe nenhum commit em nosso repositório. Alguns arquivos foram anexados no repositório. Depois disso, foi utilizado o comando git add *, para sinalizar que todos os arquivos serão adicionados. [ ] – [ ]user@parrot ~/ProjetoTechIt $ git add * [ ] – [ ]user@parrot ~/ProjetoTechIt $ git commit -m ”Nosso primeiro commit! ” [master (root-commit) 95ef2cb] Nosso primeiro commit! 539 files changed, 119090 insertions(+) create mode 100644 node_modules/.bin/mime create mode 100644 node_modules/.bin/mime.cmd create mode 100644 node_modules/.bin/semver create mode 100644 node_modules/.bin/semver.cmd create mode 100644 node_modules/accepts/HISTORY.md [ ] – [ ]user@parrot ~/ProjetoTechIt $git status On branch master No commits yet nothing to commit (create/copy files and use ”git add“ to track) Parrot Terminal File ViewEdit Search Terminal Help Após alterar o arquivo server.js, foram utilizados os comandos git add server.js e git commit. 102 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT create mode 100644 node_modules/utils-merge/package.json create mode 100644 node_modules/vary/HISTORY.md create mode 100644 node_modules/vary/LICENSE create mode 100644 node_modules/vary/README.md create mode 100644 node_modules/vary/index.js create mode 100644 node_modules/vary/package.json create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 server.js [ ] – [ ]user@parrot ~/ProjetoTechIt $ git add server.js [ ] – [ ]user@parrot ~/ProjetoTechIt $ [ ] – [ ]user@parrot ~/ProjetoTechIt $ git commit -m ”Mudança da porta 8080 para 8081" [master 43aa974] Mudança da porta 8080 para 8081 1 file changed, 1 insertion(+), 1 deletion(-) Parrot Terminal File ViewEdit Search Terminal Help O comando git log nos devolve a lista de commits do nosso repositório. Do mais atual até o mais antigo, é importante reparar no código identificador composto por letras e números. Ele será utilizado para outros comandos. [ ] – [ ]user@parrot ~/ProjetoTechIt $git log commit 43aa97489fc353d7fa8b397fdc5a81623ac6a71f ( )HEAD -> master Author: Robson Barbosa <exemplogithub@gmail.com> Date: Thu Jun 6 13:50:25 2019 -0400 Mudança da porta 8080 para 8081 commit 95ef2cbaa852853d74e16f302c1677ed983c7e6e Author: Robson Barbosa <exemplogithub@gmail.com> Date: Thu Jun 6 13:33:24 2019 -0400 Parrot Terminal File ViewEdit Search Terminal Help O git diff solicita dois commits separados por “ .. “. [ ] – [ ]user@parrot ~/ProjetoTechIt $git diff 95ef2cbaa852853d74e16f302c1677ed983c7e6e..43aa97489fc353d7fa8b397fdc5a81623ac6a71f diff - - git a/server.js b/server.js index ac7c676..e02c840 100644 - - - a/server.js +++ b/server.js app.use(function(req,res, next){@@ -22,7 + 22,7 @@ next( ); }); -var por = 8080; +var port = 8081 Parrot Terminal File ViewEdit Search Terminal Help Analisando a imagem acima, pode-se identificar que o único arquivo alterado foi o server.js. 103 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT E a linha de código alterada foi: var port = 8080; para var port = 8081 7.2.2 TRANSFORMAÇÃO DE UM REPOSITÓRIO LOCAL EM REMOTO. Para transformar um repositório local em remoto é necessário a utilização do comando: git remote add origin [endereco_do_repositorio.git] $git remote add origin https://github.com/TechItRobson/Exemplo-inicial.git Para subir os arquivos para o repositório remoto pode-se utilizar o comando: git push -u origin master --force $git push -u origin master - - force Username for ‘https://github.com’ : TechItRobson Password for ‘https://TechItRobson@github.com' : Enumerating objects: 647, done. Counting objects: 100% (647/647), done. Delta compression using up to 3 threads Compressing objects: 100% (617/617), done. Writing objects: 100% (647/647), 998.27 KiB | 2.42 MiB/s, done. Total 647 (delta 105), reused 0 (delta 0) remote: Resolving deltas: 100% (105/105), done. To https://github.com/TechItRobson/Exemplo-inicial.git + fe9603f ...43aa974 master -> master (forced update) Branch ‘master’ set up to track remote branch ‘master’ from ‘origin’. Ao utilizar o comando push, será solicitado o nome de usuário e senha, a senha será totalmente ocultada, nem mesmo mostrando os tão conhecidos asteriscos. Pode parecer um pouco estranho no início, mas não se preocupe. 104 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 7.2.3 CLONANDO UM REPOSITÓRIO DO GITHUB Para clonar um repositório remoto, é utilizado o comando: git clone [URL_REPOSITÓRIO] _ xPrompt de Comandoc:\. Microsoft Windows [versão 10.0.17763.503] (c) 2018 Microsoft Corporation. Todos os direitos reservados. C:\Users\Robson>git clone https://github.com/chrislgarry/Apollo-11.git Cloning into ‘Apollo-11' ... remote: Enumerating objects: 1584, done. remote: Total 1584 (delta 0), reused 0 (delta 0), pack-reused 1584 Receiving objects: 100% (1584/1584), 2,11 MiB | 173.00 KiB/s, done. Resolving deltas: 100% (942/942), done. C:\Users\Robson> Apollo-11 06/06/2019 15:56 Pasta de arquivos Quando realizamos o git clone, podemos utilizar o git pull e trazer os arquivos mais atualizados. Também podemos realizar pull requests, que são solicitações para que suas alterações sejam aceitas em repositórios de terceiros. Basicamente é uma forma de perguntar se o dono do projeto quer aceitar as alterações que você fez, seja inserções, deleções ou alterações. 7.2.4 CONSIDERAÇÕES FINAIS SOBRE O TEMA. Lembramos que todas as ferramentas aqui descritas podem sofrem alterações, como mudança de funções, instalação, layout, ou até mesmo na política de cobrança. É importante que identifique na documentação como se utiliza cada função da ferramenta que está utilizando, o uso para o Subversion, Mercurial e o Git podem possuir algumas diferenças, irá ser necessário uma breve pesquisa para a sintaxe. 105 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 8 TESTE UNITÁRIO O princípio deste tipo de teste é validar e invalidar dados, conforme entrada e saída testando a menor parte possível. Em programação orientada a objetos, o foco destes testes seriam os métodos. Para realizar os testes, são criadas classes de testes sendo que a separação da classe de testes do código principal garante que não interfiram no funcionamento do código principal de alguma forma. Figura 36 - Processo de testes unitários Fonte: ADAPTADO DE SHUTTERSTOCK, 2019. 106 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Os testes unitários visam garantir que caso seja passado parâmetros corretos, o método irá funcionar de maneira adequada e esperada. Enquanto que, caso seja passado valores incorretos, o método irá tratar e devolver o valor de maneira com que o sistema não pare. Figura 37 - Validação dos testes unitários Fonte: ADAPTADO DE SHUTTERSTOCK, 2019. É importante ter o hábito de aplicar os testes de unidade para que cada pequeno método funcione e que a junção de todos eles também funcione de forma esperada. Os testes unitários são aplicados durante o desenvolvimento dos métodos. Os testes unitários se baseiam, além de verificar se determinado método está funcionando, em verificar se os métodos continuam funcionando mesmo depois de receber alterações em sua base de código. Dentre vários motivos para se utilizar, está o fato de que auxiliam a identificação de possíveis paradas do funcionamento em alguma parte. Então, caso esteja realizando alguma alteração em alguma parte do sistema, e isso venha a acarretar erros, seria notificado imediatamente exibindo o local que não está funcionando de forma esperada. 107 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT Figura 38 - Validação dos testes Fonte: SENAI DR PR, 2019. Existem diversas ferramentas de testes para cada linguagem de programação, mesmo havendo diferença na escrita dos testes, o funcionamento tende a ser igual, havendo poucas funcionalidades que as diferem. É importante escolher uma e aprendê-la, usar os recursos de forma correta e tirar o melhor proveito das ferramentas que são oferecidas. Destacam-se algumas ferramentas de testes unitários por linguagem, como o NUnit para C#, PHPUnit para PHP, Jest e Mocha para JavaScript, RSpec para Ruby, Pytest para Python e XCTest para Swift. using BankAccountNS; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace BankTests2 { [ ]TestClass public class UnitTest1 { [ ]TestClass public void DebitoComValorReal_Test( ) { // Arrange double saldo = 11.99; double valorDebitado = 4.55; double esperado = 7.44; ContaBanco ContaBancoconta = ( , saldo);new “John Doe“ // Act conta. (valorDebitado);Debitar // Assert double valorAtual = conta.saldo; Assert. (esperado, valorAtual, 0,001, );AreEqual ”Valor não foi debitado corretamente“ } } } A primeira linha indica qual será a classe testada. A linha 2 importa o namespace necessário para realizar os testes. A linha 7 indica que abaixo terá o nome da classe de testes, no caso é UnitTest1, encontrando-o na linha 8. A linha 10 indica que na linha seguinte terá o nome do método, sendo este um método de teste, no caso é DebitoComValorReal_Test. 108 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT A linha 17 está criando um objeto. Linha 20 executando o método Debitar. A linha 24 está conferindo o resultado recebido com o resultado esperado. O método debitar escrito de forma incorreta: public void doubleDebitar( valor) { balanco += valor; } Está realizando o inverso proposto, no caso está somando ao invés de subtrair. Isso gera o seguinte erro, sinalizando que o valor recebido não confere com o valor esperado, causando a reprovação do teste. Resumo dos Detalhes do Teste DebitoComValorReal_Test Fonte: UnitTest1.cs linha: 11 Duração: 190 ms Mensagem: Assert.AreEqual failed. Expected a difference no greater than <0,001> between expected value <7,44> Rastreamento de Pilha: em UnitTest1.DebitoComValorReal_Test( ) em UnitTest1.cs linha: 21 Alterando o método Debitar, para subtração, do modo que realmente deveria agir: public void doubleDebitar( valor) { balanco -= valor; } Gera um resultado positivo do teste, sinalizando que o resultado esperado foi o mesmo recebido. Resumo dos Detalhes do Teste DebitoComValorReal_Test Fonte: UnitTest1.cs linha: 11 Duração: 125 ms Pode-se criar várias classes de testes ao mesmo tempo e, dentro de cada classe, pode existir vários métodos de testes. Estes métodos, quando executados, irão informar quais pequenos módulos estão corretos e quais os que tiveram um resultado diferente do esperado,poupando tempo, porém não deixando desnecessário os outros tipos de testes. 109 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT 9 REFERÊNCIAS BORATTI, I. C. Programação Orientada a Objetos em Java. 1. ed. São Paulo. Visual Books. 2007. CANALTECH. C: a linguagem de programação que está em tudo o que você usa. Disponível em: <https://canaltech.com.br/software/ c-a-linguagem-de-programacao-que-esta-em-tudo-o-que-voce- usa-19512/> Acesso em: 11 nov 2019. CCM. POO - O polimorfismo. Disponível em <https://br.ccm.net/ contents/416-poo-o-polimorfismo> Acesso em: 05 jun 2019. DEVMEDIA. Conceitos – Encapsulamento: Programação Orientada a Objetos. Disponível em <https://www.devmedia.com.br/conceitos- encapsulamento-programacao-orientada-a-objetos/18702> Acesso em: 08 ago 2019. DEVMEDIA. Introdução à Programação Estruturada. Disponível em <https://www.devmedia.com.br/introducao-a-programacao- estruturada/24951> Acesso em: 06 set 2019. MICROSOFT. Requisitos de sistema da família de produtos do Visual Studio 2017. Disponível em <https://docs.microsoft.com/pt-br/ visualstudio/productinfo/vs2017-system-requirements-vs> Acesso em: 13 ago 2019. SANTOS, R. R. dos. Programação de computadores em JAVA. 2. ed. Rio de Janeiro. Novaterra. 2014 SHARP, J. Visual C# 2010 Passo a Passo. 1. ed. Bookman. Rio Grande do Sul. 2014. TABLELESS. Tudo que você queria saber sobre Git e GitHub, mas tinha vergonha de perguntar. Disponível em <https://tableless.com.br/tudo- que-voce-queria-saber-sobre-git-e-github-mas-tinha-vergonha-de- perguntar/> Acesso em: 13 ago 2019. TROELSEN, A. Profissional C# e a Plataforma .NET 3.5 Curso Completo. 1. ed. AltaBooks. Rio de Janeiro 2009. 110 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT MINICURRÍCULO DO AUTOR Robson Inocêncio Barbosa Robson Inocêncio Barbosa é Técnico em Informática pelo SENAI/PR desde 2014, Tecnólogo em Análise e Desenvolvimento de Sistemas desde 2019 pela Unicesumar. Tem experiência como Analista e Desenvolvedor de Aplicativos web e mobile, docente nos cursos de aprendizagem, qualificação e técnico, presencial e semipresencial na área de Tecnologia da Informação na Unidade Campus da Indústria do SENAI/ PR. Desenvolvedor de aplicações de Realidade Aumentada, treinador medalhista na etapa estadual da Seletiva World Skills 2019. Atualmente atuando como conteudista, professor e com desenvolvimento de sistemas front e back-end. 111 SENAI – SERVIÇO NACIONAL DE APRENDIZAGEM INDUSTRIAL DO PARANÁTECH IT CRÉDITOS SENAI – DEPARTAMENTO REGIONAL DO PARANÁ Alexandre Luis Kloch Revisão e Coordenação Técnica Erica Luz de Souza Orientação Pedagógica Karem Morigi Revisão Ortográfica e Gramatical Daniel Gustavo Hella Estela Pereira Raphael Hardy Fioravanti Coordenação de Projeto Willian Bill Ilustrações e Tratamento de Imagens Anderson Calixto de Carvalho Diagramação, Revisão de Arte e Fechamento de Arquivo Ricardo Luiz Freire de Menezes Projeto Gráfico José Antônio Fares Diretor Regional Giovana Chimentao Punhagui Gerente Executiva de Educação Vanessa Sorda Frason Gerente de Educação Profissional Jacielle Feltrin Vila Verde Ribeiro Sandra Cristina Brasil Toloto Coordenação Pedagógica Robson Inocêncio Barbosa Elaboração