0%
Pular para o conteúdo principal
0%

2.1.2 Barreiras de Abstração

Antes de continuar com mais exemplos de dados compostos e abstração de dados, vamos considerar algumas das questões levantadas pelo exemplo de números racionais. Definimos as operações de números racionais em termos de um construtor make_rat e seletores numer e denom. Em geral, a ideia subjacente da abstração de dados é identificar para cada tipo de objeto de dados um conjunto básico de operações em termos das quais todas as manipulações de objetos de dados desse tipo serão expressas, e então usar apenas essas operações na manipulação dos dados.

Barreiras de abstração de dados no pacote de números racionais

Podemos visualizar a estrutura do sistema de números racionais como mostrado na figura acima. As linhas horizontais representam barreiras de abstração que isolam diferentes "níveis" do sistema. Em cada nível, a barreira separa os programas (acima) que usam a abstração de dados dos programas (abaixo) que implementam a abstração de dados. Programas que usam números racionais os manipulam exclusivamente em termos das funções fornecidas "para uso público" pelo pacote de números racionais: add_rat, sub_rat, mul_rat, div_rat e equal_rat. Estas, por sua vez, são implementadas exclusivamente em termos do construtor e seletores make_rat, numer e denom, que eles mesmos são implementados em termos de pares. Os detalhes de como os pares são implementados são irrelevantes para o resto do pacote de números racionais, desde que os pares possam ser manipulados pelo uso de pair, head e tail. Na prática, as funções em cada nível são as interfaces que definem as barreiras de abstração e conectam os diferentes níveis.

Esta ideia simples tem muitas vantagens. Uma vantagem é que torna os programas muito mais fáceis de manter e modificar. Qualquer estrutura de dados complexa pode ser representada de várias maneiras com as estruturas de dados primitivas fornecidas por uma linguagem de programação. Claro, a escolha da representação influencia os programas que operam sobre ela; assim, se a representação fosse alterada em algum momento posterior, todos esses programas poderiam ter que ser modificados de acordo. Esta tarefa poderia ser demorada e cara no caso de programas grandes, a menos que a dependência da representação fosse confinada por design a muito poucos módulos do programa.

Por exemplo, uma maneira alternativa de abordar o problema de reduzir números racionais aos menores termos é realizar a redução sempre que acessamos as partes de um número racional, em vez de quando o construímos. Isso leva a diferentes funções construtoras e seletoras:

Carregando playground de código...

A diferença entre esta implementação e a anterior reside em quando computamos o gcd. Se em nosso uso típico de números racionais acessamos os numeradores e denominadores dos mesmos números racionais muitas vezes, seria preferível computar o gcd quando os números racionais são construídos. Caso contrário, podemos ser melhor servidos esperando até o momento do acesso para computar o gcd. Em qualquer caso, quando mudamos de uma representação para a outra, as funções add_rat, sub_rat e assim por diante não precisam ser modificadas de forma alguma.

Restringir a dependência da representação a algumas poucas funções de interface nos ajuda a projetar programas, bem como modificá-los, porque nos permite manter a flexibilidade para considerar implementações alternativas. Para continuar com nosso exemplo simples, suponha que estamos projetando um pacote de números racionais e não podemos decidir inicialmente se devemos realizar o gcd no momento da construção ou no momento da seleção. A metodologia de abstração de dados nos dá uma maneira de adiar essa decisão sem perder a capacidade de progredir no resto do sistema.

Exercício 2.2

Considere o problema de representar segmentos de linha em um plano. Cada segmento é representado como um par de pontos: um ponto inicial e um ponto final. Declare um construtor make_segment e seletores start_segment e end_segment que definem a representação de segmentos em termos de pontos. Além disso, um ponto pode ser representado como um par de números: a coordenada x e a coordenada y. Consequentemente, especifique um construtor make_point e seletores x_point e y_point que definem essa representação. Finalmente, usando seus seletores e construtores, declare uma função midpoint_segment que recebe um segmento de linha como argumento e retorna seu ponto médio (o ponto cujas coordenadas são a média das coordenadas dos pontos extremos). Para testar suas funções, você precisará de uma maneira de imprimir pontos:

Carregando playground de código...

Exercício 2.3

Implemente uma representação para retângulos em um plano. (Dica: Você pode querer fazer uso do exercício 2.2.) Em termos de seus construtores e seletores, crie funções que computem o perímetro e a área de um dado retângulo. Agora implemente uma representação diferente para retângulos. Você pode projetar seu sistema com barreiras de abstração adequadas, de modo que as mesmas funções de perímetro e área funcionem usando qualquer uma das representações?

Carregando playground de código...

📝 Encontrou algo errado nesta página?

Sua ajuda é muito importante para melhorar a qualidade da tradução!

🐛 Encontrou um erro?

Se você encontrou:

  • Erro de tradução (palavra incorreta, termo técnico errado)
  • Erro de ortografia ou gramática
  • Link quebrado
  • Código de exemplo que não funciona
  • Problema de formatação

Reporte um bug →

❓ Tem uma dúvida?

Se você tem:

  • Dúvida sobre o conteúdo desta seção
  • Pergunta sobre um conceito do SICP
  • Dificuldade em entender algum exemplo
  • Questão sobre a tradução de algum termo

Inicie uma discussão →

💡 Tem uma sugestão de melhoria?

Se você quer sugerir:

  • Melhoria na explicação
  • Exemplo adicional
  • Recurso visual (diagrama, ilustração)
  • Qualquer outra ideia

Sugira uma melhoria →

🌍 Quer discutir a tradução?

Se você quer debater:

  • Escolha de tradução de algum termo
  • Consistência de terminologia
  • Nuances do português

Discussão de tradução →

Obrigado por ajudar a melhorar o SICP.js PT-BR! ✨