Tipo abstrato de dados: o que é?

Tipo abstrato de dados: o que é?

Se você está em algum curso de ciência da computação e está cursando a disciplina de estrutura de dados você vai se deparar bastante com o termo “tipo abstrato de dados”. Essa é uma das primeiras barreiras que você enfrenta nessa disciplina, a terminologia. Apesar de parecer algo complexo, um tipo abstrato de dados é uma forma de pensar em estruturas do mundo real e abstrair em código.

Mas antes de qualquer coisa vamos entender um pouco melhor sobre alguns termos muito usados e que as vezes ficam perdidos no nosso vocabulário:

  • Algoritmo – um algoritmo deve ser visto como uma sequência de passos ou ações expressas em termos de uma linguagem de programação, constituindo parte da solução de um tipo determinado de problema. Sendo assim, um algoritmo pode ser visto também como uma descrição do padrão de comportamento. Ou seja, essas ações descritas são expressas por meio de um conjunto finito de ações especificadas usando uma linguagem de programação.  
  • Estrutura de dados – uma estruturas de dados é uma coleção tanto de valores (e seus relacionamentos) quanto de operações (sobre os valores e estruturas decorrentes). As estruturas de dados não são apenas algoritmos, os algoritmos são apenas uma parte da solução do problema. Ou seja, uma estrutura de dados é composta por valores e algoritmos, sendo que ambos compõem um programa a ser executado pelo computador.
  • Programa – nesse contexto, quando falamos em programa, estamos nos referindo a uma formulação concreta, em termos de uma linguagem de programação, de um procedimento abstrato que atua sobre um modelo de dados também abstrato.
  • Tipos de dados  – em uma linguagem de programação é importante classificar constantes, variáveis e valores gerados por expressões/funções de acordo com o seu tipo de dados. Um tipo de dado deve caracterizar o conjunto de valores a que uma constante pertence ou o conjunto de valores que pode ser assumido por uma variável ou gerado por uma expressão/função. Nesse contexto temos os tipos de dados simples que tem a característica de ser um conjunto de valores de valores indivisíveis, como por exemplo os tipos numeral, texto (não tem como você dividir os números inteiros em duas partes – inteiro é inteiro e ponto final).   

Esses conceitos foram adaptados do material do professor Bruno Maffeo.

Agora que já conhecemos o que são tipos de dados e vários termos relacionados a esse contexto, podemos começar a entender melhor o tipo abstrato de dados.    

O que é um tipo abstrato de dados?

Podemos dizer que um tipo abstrato de dados (TAD) é um modelo matemático que esconde (encapsula) um modelo de dados também um conjunto de procedimentos que atuam diretamente e com exclusividade sobre os dados encapsulados.

Ficou difícil? Vamos simplificar um pouco.

Um tipo de dados abstrato de dados possui duas partes: 1) dados armazenados 2) funções que manipulam os dados. Os dados podem ser armazenados em variáveis, vetores, ponteiros etc. Já as funções implementam procedimentos por meio de subprogramas denominados operações, métodos ou serviços.  É importante dizer que qualquer processamento realizado só deve atuar sobre os dados encapsulados em um TAD, além disso, os processamentos só poderão acontecer intermédio dos procedimentos definidos no modelo do TAD.

Ao ler todas essas restrições pode parecer que tudo isso não faz sentido algum, mas acredite em mim, tudo isso é muito útil quando vamos programar. Quando implementamos uma TAD podemos garantir que o programa será mais “resistente” a erros ao manipular os dados, além disso, podemos abstrair o conceito encapsulado na TAD e implementá-lo usando qualquer linguagem de programação

Vamos pegar por exemplo as Strings em Java, Python, C++ etc. Esses objetos complexos são bem definidos e podem ser instanciados e manipulados por meio dos métodos associados. Por exemplo, em Java:

String nome = "vinicius";

Para manipular essa string podemos invocar alguns métodos, por exemplo para tornar tudo maiúsculo:

nome = nome.toUpperCase();

Perceba que estamos realizando uma ação que não teve nenhuma influência externa. Não acessamos em nenhum momento o código da classe String. Essa é uma característica importante dos tipos de dados abstratos, eles são tão coesos que você pode manipulá-los simplesmente usando os métodos disponíveis.

É muito comum que encontremos nas TADs uma coleção de atividades, tais como inserir, remover e consultar, tudo isso encapsulado junto com uma estrutura passiva, como um dicionário ou arrays (conjunto de dados), que pode ser considerada um tipo abstrato de dados (TAD). 

Por que usamos TADs

A principal característica que nos faz assumir que uma TAD é melhor do que outros códigos é o encapsulamento. Isso significa que os dados só são acessíveis por meio dos métodos, ou seja, elementos da estrutura passiva do TAD são acessíveis somente através dos elementos da estrutura ativa (métodos). Essa mudança insere uma restrição rígida e uma forma mais eficiente de programação defensiva (protegendo os dados que foram encapsulados pelo programador no TAD). Essa prática pode reduzir consideravelmente o risco de outros algoritmos afetarem os dados que estão protegidos na TAD.   

As TADs permitem que você altere como os métodos são implementados internamente sem a preocupação de causar problemas no restante do código, visto que as TADs são extremamente altamente genéricas e não dependem do contexto onde foram usadas. Por exemplo, imagine que você implementou um tipo de dados abstrato que cuida do saldo dos seus clientes no banco. Nessa TAD você especifica toda e qualquer operação que é permitida e tudo que não pode ser feito. Quando você constrói um software baseado nessa TAD você tem a certeza que todas aquelas regras são seguidas à risca. No entanto, essa TAD é editável, sendo assim, se você resolver otimizar um processo dentro dessa TAD, as alterações não afetarão o programa original.

Essa implementação altamente genérica só é possível quando a TAD possui uma única conexão com o restante do programa (uma chamada única apenas), ou seja, uma interface que não muda. As TADs quando são bem construídas podem tornar-se uma porção de código confiável, genérica e reutilizável em outros programas. Assim, você pode aumentar a produtividade na construção de programas e aumentar a qualidade dos produtos finais.

Alguns exemplos de TADs

Veja abaixo alguns dos tipos mais comuns de TADs implementadas na computação:

  • Pilhas – estrutura onde empilhamos dados como se fossem caixas. Colocamos um dado sobre o outro e quando queremos retirar um dado é preciso desempilhá-los.
  • Filas – as filas podem armazenar dados, porém a forma de inserir ou remover dados podem ser feitas em qualquer uma das pontas.
  • Árvores – estruturas que armazenam os dados e relacionam cada dado com dois ou mais dados.
  • Listas – muito semelhante as filas porém com alterações também na forma de entrada, saída e alteração dos dados.
  • Mapas/dicionários – essas estruturas são muito comuns e relacionam chave com um valor, por exemplo: {Idade: 10, profissão: estudante}.

Por que aprendemos TADs em computação?

Esse conceito é tão genérico que ele é capaz de ser implementado em qualquer linguagem de programação (mesmo que algumas delas apresentem algumas restrições). Geralmente os modelos mais comuns como pilhas, filas, listas são pré-implementados no pacote básico da linguagem e você não precisa se preocupar com eles. No entanto, você precisa entender o que são as TADs, visto que elas são a base do encapsulamento. Assim, planejando bem sua implementação e criando tipos de dados abstratos e confiáveis, você poderá reutilizá-los em vários projetos.

Vinicius dos Santos

Apenas um apaixonado por Ciência da Computação e a forma com que ela pode transformar vidas!

Deixe um comentário

cinco × dois =