O terceiro nível de abstração em programação

Programar para computadores é fácil, difícil é programar para pessoas. São as pessoas que devem entender o que o seu programa faz. O computador sempre faz o que você pede sem questionar. Quem geralmente questiona porque você fez de tal forma são os outros programadores e, muitas vezes, você mesmo. Assim, programar bem é quase o mesmo que escrever bem. Não é a toa que o que usamos para programar se chama linguagem – Linguagem de Programação. Uma parte do trabalho do programador é traduzir o algoritmo que resolve o problema para uma linguagem que o computador entenda. A outra parte e, provavelmente a mais importante, é saber se expressar de forma clara a fim de lidar mais facilmente com a complexidade.

Quase todo software é um grande problema a ser resolvido. E para resolver um problema precisamos ter conhecimento do seu universo de informações. Porém, um novo problema surge por uma limitação do nosso cérebro: a quantidade de informação que somos capazes manter na memória enquanto pensamos numa solução é limitada. Por isto, geralmente decompomos o problema em partes menores. Estas partes menores, depois de resolvidas, nos permitirão ignorar grandes quantidades de informação que de outra forma manteríamos como ruído na nossa memória enquanto tentamos solucionar o problema maior. Em outras palavras, as partes menores do problema encapsulam detalhes que não são pertinentes saber enquanto pensamos no problema maior. E porque estamos livres de pensar em todos estes detalhes ao mesmo tempo o grande problema se torna mais fácil de ser resolvido. Esta é a melhor arma do programador para lidar com a complexidade e se chama Abstração.

A abstração pode existir em níveis infinitos, mas eu considero que para lidar bem com a complexidade precisamos entender três níveis de abstração:
1. Abstração de linguagem de alto nível
2. Abstração do SDK da linguagem
3. Abstração dos objetos do domínio

O primeiro e o segundo nível de abstração geralmente são fornecidos para o programador. Uma linguagem de alto nível já é uma abstração de muitos detalhes de outras linguagens de mais baixo nível. O Java, que é uma linguagem de alto nível, abstrai detalhes de mais baixo nível como o tratamento de ponteiros do C, por exemplo. Isto porque se considerou no projeto da linguagem Java que este tipo de detalhe (trabalho com ponteiros) seria um ruído desnecessário que o programador teria que manter em sua mente enquanto pensava sobre o problema a ser resolvido.

Porém, mesmo as linguagens de alto nível possuem detalhes que podem ser considerados de mais baixo nível e por isto existem os SDKs. O SDK do Java oferece mais um nível de abstração que evita que o programador tenha que saber no detalhe o que é preciso fazer até mesmo para tarefas simples como imprimir uma mensagem no console – isto está encapsulado na classe “System”. Assim, os SDKs elevam ainda mais o nível das linguagens de alto nível fornecendo determinados serviços que deixam o programador mais livre para pensar naquilo que lhe é pertinente.

Por fim, existe a abstração que é responsabilidade do programador. Esta é a abstração dos objetos do domínio; os objetos que o programador cria para o seu negócio. O problema a ser resolvido pelo programador é adicionar itens num carrinho de compras e não adicionar “floats” para preços, “strings” para nomes e “ints” para quantidades numa “Collection”. Se o programador tiver que pensar em “floats”, “ints”, “strings”, “Collections”, etc. enquanto tenta resolver o seu problema ele estará ocupando espaço em sua mente com detalhes demais ao mesmo tempo e não estará lidando bem com a complexidade. Assim, o programador pode criar um Objeto que deixa as coisas num nível ainda mais abstrato. No caso do carrinho de compras o programador poderia criar algo do tipo ShoppingCart.add(item). Desta forma é possível ler um programa quase que em linguagem natural, o que permitirá ao programador pensar sobre o seu problema nos termos do seu negócio e não nos inúmeros detalhes técnicos. Isto reduz imensamente o overhead cerebral que nós mesmos criamos ao não usar bem a abstração e é como se nós tivéssemos criado o nosso próprio SDK com os objetos do domínio do problema que queremos resolver.

Este terceiro nível de abstração também é importante porque ao ler o seu programa outro programador precisa ter inicialmente um entendimento global da solução. Neste momento é suficiente saber que ShoppingCart.add(item) faz o seu trabalho e não como isto é feito. Mais uma vez (não me canso de repetir) isto evita que o outro programador tenha que manter em sua mente o modo como o carrinho de compras funciona enquanto tenta entender o Shopping virtual como um todo. Se ele quiser saber como o carrinho de compras especificamente funciona ele desce um nível na abstração e assim sucessivamente até chegar ao nível mais baixo que desejar.

Mas pior do que não criar os seus objetos do domínio é o programador usar instruções cada vez mais baixo nível para implementar funcionalidades de negócio. Lembro que certa vez eu mostrei para uns amigos a instrução “de baixo nível” ChangeWacher.watch() do SDK do Flex e isto se espalhou por todo o software que estávamos desenvolvendo. Não estou dizendo que não devemos usar instruções de baixo nível, mas a questão é onde usá-las. Se você está implementando um Caso de Uso ou uma User Story,quando você ou outro programador for ler o programa ele tem que se deparar, inicialmente, com algo no terceiro nível de abstração. O que o programador deve ler inicialmente ao ver o seu código são chamadas aos métodos e propriedades dos objetos do domínio do seu problema. Misturar estas chamadas com instruções de baixo nível como “ChangeWatcher.watch” não é uma boa prática. Afinal de contas, para quê eu preciso saber que alguém usou um “ChangeWatcher.watch()” quando tudo que eu quero saber é como o meu Shopping virtual funciona como um todo? Sempre que vemos uma instrução de mais baixo nível enquanto tentamos entender a implementação de uma funcionalidade de negócio somos obrigados a parar e tentar adivinhar porque ela foi usada daquela forma e naquele momento.

Conclusão: se tivermos que pensar em detalhes técnicos (ints, floats, Collections, etc.) enquanto resolvermos o nosso problema não estaremos usando o terceiro nível de abstração, o único de responsabilidade do programador. Ao trabalhar com o SDK e com linguagens de alto nível o programador pode resolver facilmente os problemas menores – os detalhes técnicos de implementação. Ao trabalhar com os objetos do domínio o programador pode resolver facilmente problemas maiores – os problemas do seu negócio. Assim ele consegue o nível de abstração necessário que lhe permite lidar melhor com a complexidade. Assim ele escreve programa para pessoas, não para computadores.

3 Comentários to “O terceiro nível de abstração em programação”

  1. Anderson disse:

    Excelente post!

  2. andre disse:

    Muito bom! se artigo! muito bem escrito!

  3. Herbeson disse:

    Parabéns pelo post, excelente leitura, principalmente para mim que ainda estou iniciando minha carreira como programador, pois isso me ajudou muito a relacionar minhas idéias.

Deixe uma resposta


Thumbnails powered by Thumbshots